Exemplo n.º 1
0
int msHatchPolygon(imageObj *img, shapeObj *poly, double spacing, double width, double *pattern, int patternlength, double angle, colorObj *color)
{
  assert(MS_RENDERER_PLUGIN(img->format));
  msComputeBounds(poly);

  /* amount we should expand the bounding box by */
  double exp = width * 0.7072;

  /* width and height of the bounding box we will be creating the hatch in */
  int pw=(int)(poly->bounds.maxx-poly->bounds.minx+exp*2)+1;
  int ph=(int)(poly->bounds.maxy-poly->bounds.miny+exp*2)+1;

  /* position of the top-left corner of the bounding box */
  double ox = poly->bounds.minx - exp;
  double oy = poly->bounds.miny - exp;

  //create a rectangular hatch of size pw,ph starting at 0,0
  //the created hatch is of the size of the shape's bounding box
  mapserver::path_storage hatch = createHatch(ox,oy,
                                  img->refpt.x,img->refpt.y,pw,ph,angle,spacing);
  if(hatch.total_vertices()<=0) return MS_SUCCESS;

  //translate the hatch so it overlaps the current shape
  hatch.transform(mapserver::trans_affine_translation(ox,oy));

  polygon_adaptor polygons(poly);



  if(patternlength>1) {
    //dash the hatch and render it clipped by the shape
    mapserver::conv_dash<mapserver::path_storage > dash(hatch);
    mapserver::conv_stroke<mapserver::conv_dash<mapserver::path_storage> > stroke(dash);
    for (int i=0; i<patternlength; i+=2) {
      if (i < patternlength-1) {
        dash.add_dash(pattern[i], pattern[i+1]);
      }
    }
    stroke.width(width);
    stroke.line_cap(mapserver::butt_cap);
    mapserver::conv_clipper<polygon_adaptor,mapserver::conv_stroke<mapserver::conv_dash<mapserver::path_storage> > > clipper(polygons,stroke, mapserver::clipper_and);
    renderPolygonHatches(img,clipper,color);
  } else {
    //render the hatch clipped by the shape
    mapserver::conv_stroke <mapserver::path_storage > stroke(hatch);
    stroke.width(width);
    stroke.line_cap(mapserver::butt_cap);
    mapserver::conv_clipper<polygon_adaptor,mapserver::conv_stroke<mapserver::path_storage> > clipper(polygons,stroke, mapserver::clipper_and);
    renderPolygonHatches(img,clipper,color);
  }


  //assert(prevCmd == mapserver::path_cmd_line_to);
  //delete lines;
  return MS_SUCCESS;
}
Exemplo n.º 2
0
void msFreeOutputFormat( outputFormatObj *format )

{
    if( format == NULL )
        return;
    if(MS_RENDERER_PLUGIN(format) && format->vtable) {
       format->vtable->cleanup(MS_RENDERER_CACHE(format->vtable));
       free( format->vtable );
    }
    msFree( format->name );
    msFree( format->mimetype );
    msFree( format->driver );
    msFree( format->extension );
    msFreeCharArray( format->formatoptions, format->numformatoptions );
    msFree( format );
}
Exemplo n.º 3
0
void msApplyOutputFormat( outputFormatObj **target,
                          outputFormatObj *format,
                          int transparent,
                          int interlaced,
                          int imagequality )

{
  int       change_needed = MS_FALSE;
  int       old_imagequality, old_interlaced;
  outputFormatObj *formatToFree = NULL;

  assert( target != NULL );

  if( *target != NULL && MS_REFCNT_DECR_IS_ZERO( (*target) ) ) {
    formatToFree = *target;
    *target = NULL;
  }

  if( format == NULL ) {
    if( formatToFree )
      msFreeOutputFormat( formatToFree );
    *target = NULL;
    return;
  }

  msOutputFormatValidate( format, MS_FALSE );

  /* -------------------------------------------------------------------- */
  /*      Do we need to change any values?  If not, then just apply       */
  /*      and return.                                                     */
  /* -------------------------------------------------------------------- */
  if( transparent != MS_NOOVERRIDE && !format->transparent != !transparent )
    change_needed = MS_TRUE;

  old_imagequality = atoi(msGetOutputFormatOption( format, "QUALITY", "75"));
  if( imagequality != MS_NOOVERRIDE && old_imagequality != imagequality )
    change_needed = MS_TRUE;

  old_interlaced =
    strcasecmp(msGetOutputFormatOption( format, "INTERLACE", "ON"),
               "OFF") != 0;
  if( interlaced != MS_NOOVERRIDE && !interlaced != !old_interlaced )
    change_needed = MS_TRUE;

  if( change_needed ) {
    char new_value[128];

    if( format->refcount > 0 )
      format = msCloneOutputFormat( format );

    if( transparent != MS_NOOVERRIDE ) {
      format->transparent = transparent;
      if( format->imagemode == MS_IMAGEMODE_RGB )
        format->imagemode = MS_IMAGEMODE_RGBA;
    }

    if( imagequality != MS_NOOVERRIDE && imagequality != old_imagequality ) {
      snprintf( new_value, sizeof(new_value), "%d", imagequality );
      msSetOutputFormatOption( format, "QUALITY", new_value );
    }

    if( interlaced != MS_NOOVERRIDE && !interlaced != !old_interlaced ) {
      if( interlaced )
        msSetOutputFormatOption( format, "INTERLACE", "ON" );
      else
        msSetOutputFormatOption( format, "INTERLACE", "OFF" );
    }
  }

  *target = format;
  format->refcount++;
  if( MS_RENDERER_PLUGIN(format) ) {
    msInitializeRendererVTable(format);
  }


  if( formatToFree )
    msFreeOutputFormat( formatToFree );
}
Exemplo n.º 4
0
/*
 * generic function for drawing a legend icon. (added for bug #2348)
 * renderer specific drawing functions shouldn't be called directly, but through
 * this function
 */
int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass,
                     int width, int height, imageObj *image, int dstX, int dstY)
{
  int i, type, hasmarkersymbol;
  double offset;
  shapeObj box, zigzag;
  pointObj marker;
  char szPath[MS_MAXPATHLEN];
  styleObj outline_style;
  imageObj *image_draw = image;
  int originalopacity = lp->opacity;
  rendererVTableObj *renderer;
  outputFormatObj *transFormat = NULL, *altFormat=NULL;
  const char *alternativeFormatString = NULL;

  if(!MS_RENDERER_PLUGIN(image->format)) {
    msSetError(MS_MISCERR,"unsupported image format","msDrawLegendIcon()");
    return MS_FAILURE;
  }

  alternativeFormatString = msLayerGetProcessingKey(lp, "RENDERER");
  if (MS_RENDERER_PLUGIN(image_draw->format) && alternativeFormatString!=NULL &&
      (altFormat=  msSelectOutputFormat(map, alternativeFormatString))) {
    msInitializeRendererVTable(altFormat);

    image_draw = msImageCreate(image->width, image->height,
                               altFormat, image->imagepath, image->imageurl, map->resolution, map->defresolution, &map->imagecolor);
    renderer = MS_IMAGE_RENDERER(image_draw);
  } else {
    renderer = MS_IMAGE_RENDERER(image_draw);
    if (lp->opacity > 0 && lp->opacity < 100) {
      if (!renderer->supports_transparent_layers) {
        image_draw = msImageCreate(image->width, image->height,
                                   image->format, image->imagepath, image->imageurl, map->resolution, map->defresolution, NULL);
        if (!image_draw) {
          msSetError(MS_MISCERR, "Unable to initialize temporary transparent image.",
                     "msDrawLegendIcon()");
          return (MS_FAILURE);
        }
        /* set opacity to full, as the renderer should be rendering a fully opaque image */
        lp->opacity=100;
      }
    }
  }


  if(renderer->supports_clipping && MS_VALID_COLOR(map->legend.outlinecolor)) {
    /* keep GD specific code here for now as it supports clipping */
    rectObj clip;
    clip.maxx = dstX + width - 1;
    clip.maxy = dstY + height -1;
    clip.minx = dstX;
    clip.miny = dstY;
    renderer->setClip(image_draw,clip);
  }

  /* initialize the box used for polygons and for outlines */
  box.line = (lineObj *)msSmallMalloc(sizeof(lineObj));
  box.numlines = 1;
  box.line[0].point = (pointObj *)msSmallMalloc(sizeof(pointObj)*5);
  box.line[0].numpoints = 5;

  box.line[0].point[0].x = dstX + 0.5;
  box.line[0].point[0].y = dstY + 0.5;
  box.line[0].point[1].x = dstX + width - 0.5;
  box.line[0].point[1].y = dstY + 0.5;
  box.line[0].point[2].x = dstX + width - 0.5;
  box.line[0].point[2].y = dstY + height - 0.5;
  box.line[0].point[3].x = dstX + 0.5;
  box.line[0].point[3].y = dstY + height - 0.5;
  box.line[0].point[4].x = box.line[0].point[0].x;
  box.line[0].point[4].y = box.line[0].point[0].y;
  box.line[0].numpoints = 5;

  /* if the class has a keyimage, treat it as a point layer
   * (the keyimage will be treated there) */
  if(theclass->keyimage != NULL) {
    type = MS_LAYER_POINT;
  } else {
    /* some polygon layers may be better drawn using zigzag if there is no fill */
    type = lp->type;
    if(type == MS_LAYER_POLYGON) {
      type = MS_LAYER_LINE;
      for(i=0; i<theclass->numstyles; i++) {
        if(MS_VALID_COLOR(theclass->styles[i]->color)) { /* there is a fill */
          type = MS_LAYER_POLYGON;
          break;
        }
      }
    }
  }

  /*
  ** now draw the appropriate color/symbol/size combination
  */
  switch(type) {
    case MS_LAYER_ANNOTATION:
      marker.x = dstX + MS_NINT(width / 2.0);
      marker.y = dstY + MS_NINT(height / 2.0);
      hasmarkersymbol = 0;
      for(i=0; i<theclass->numstyles; i++) {
          if (theclass->styles[i]->symbol < map->symbolset.numsymbols && theclass->styles[i]->symbol > 0) {
             hasmarkersymbol = 1;
             break;
          }
      }
      if (hasmarkersymbol) {
        for(i=0; i<theclass->numstyles; i++)
          msDrawMarkerSymbol(&map->symbolset, image_draw, &marker, theclass->styles[i], lp->scalefactor);
      } else if (theclass->labels && theclass->numlabels > 0) {
        labelObj *label = theclass->labels[0]; /* use the first label definition */
        double lsize = label->size;
        double langle = label->angle;
        int lpos = label->position;
        int loffsetx = label->offsetx;
        int loffsety = label->offsety;

        label->offsetx = 0;
        label->offsety = 0;
        label->angle = 0;
        label->position = MS_CC;
        if (label->type == MS_TRUETYPE) label->size = height;
        msDrawLabel(map, image_draw, marker, (char*)"Az", label,1.0);

        label->size = lsize;
        label->position = lpos;
        label->angle = langle;
        label->offsetx = loffsetx;
        label->offsety = loffsety;
      }
      break;
    case MS_LAYER_POINT:
      marker.x = dstX + MS_NINT(width / 2.0);
      marker.y = dstY + MS_NINT(height / 2.0);
      if(theclass->keyimage != NULL) {
        int symbolNum;
        styleObj imgStyle;
        symbolObj *symbol=NULL;
        symbolNum = msAddImageSymbol(&(map->symbolset), msBuildPath(szPath, map->mappath, theclass->keyimage));
        if(symbolNum == -1) {
          msSetError(MS_GDERR, "Failed to open legend key image", "msCreateLegendIcon()");
          return(MS_FAILURE);
        }

        symbol = map->symbolset.symbol[symbolNum];

        initStyle(&imgStyle);
        /*set size so that symbol will be scaled properly #3296*/
        if (width/symbol->sizex < height/symbol->sizey)
          imgStyle.size = symbol->sizey*(width/symbol->sizex);
        else
          imgStyle.size = symbol->sizey*(height/symbol->sizey);

        if (imgStyle.size > imgStyle.maxsize)
          imgStyle.maxsize = imgStyle.size;

        imgStyle.symbol = symbolNum;
        msDrawMarkerSymbol(&map->symbolset,image_draw,&marker,&imgStyle,lp->scalefactor);
        /* TO DO: we may want to handle this differently depending on the relative size of the keyimage */
      } else {
        for(i=0; i<theclass->numstyles; i++)
          msDrawMarkerSymbol(&map->symbolset, image_draw, &marker, theclass->styles[i], lp->scalefactor);
      }
      break;
    case MS_LAYER_LINE:
      offset = 1;
      /* To set the offset, we only check the size/width parameter of the first style */
      if (theclass->numstyles > 0) {
        if (theclass->styles[0]->symbol > 0 && theclass->styles[0]->symbol < map->symbolset.numsymbols && 
              map->symbolset.symbol[theclass->styles[0]->symbol]->type != MS_SYMBOL_SIMPLE)
            offset = theclass->styles[0]->size/2;
        else
            offset = theclass->styles[0]->width/2;
      }
      zigzag.line = (lineObj *)msSmallMalloc(sizeof(lineObj));
      zigzag.numlines = 1;
      zigzag.line[0].point = (pointObj *)msSmallMalloc(sizeof(pointObj)*4);
      zigzag.line[0].numpoints = 4;

      zigzag.line[0].point[0].x = dstX + offset;
      zigzag.line[0].point[0].y = dstY + height - offset;
      zigzag.line[0].point[1].x = dstX + MS_NINT(width / 3.0) - 1;
      zigzag.line[0].point[1].y = dstY + offset;
      zigzag.line[0].point[2].x = dstX + MS_NINT(2.0 * width / 3.0) - 1;
      zigzag.line[0].point[2].y = dstY + height - offset;
      zigzag.line[0].point[3].x = dstX + width - offset;
      zigzag.line[0].point[3].y = dstY + offset;

      for(i=0; i<theclass->numstyles; i++)
        msDrawLineSymbol(&map->symbolset, image_draw, &zigzag, theclass->styles[i], lp->scalefactor);

      free(zigzag.line[0].point);
      free(zigzag.line);
      break;
    case MS_LAYER_CIRCLE:
    case MS_LAYER_RASTER:
    case MS_LAYER_CHART:
    case MS_LAYER_POLYGON:
      for(i=0; i<theclass->numstyles; i++)
        msDrawShadeSymbol(&map->symbolset, image_draw, &box, theclass->styles[i], lp->scalefactor);
      break;
    default:
      return MS_FAILURE;
      break;
  } /* end symbol drawing */

  /* handle an outline if necessary */
  if(MS_VALID_COLOR(map->legend.outlinecolor)) {
    initStyle(&outline_style);
    outline_style.color = map->legend.outlinecolor;
    msDrawLineSymbol(&map->symbolset, image_draw, &box, &outline_style, 1.0);
    /* reset clipping rectangle */
    if(renderer->supports_clipping)
      renderer->resetClip(image_draw);
  }

  if (altFormat) {
    rendererVTableObj *renderer = MS_IMAGE_RENDERER(image);
    rendererVTableObj *altrenderer = MS_IMAGE_RENDERER(image_draw);
    rasterBufferObj rb;
    memset(&rb,0,sizeof(rasterBufferObj));

    altrenderer->getRasterBufferHandle(image_draw,&rb);
    renderer->mergeRasterBuffer(image,&rb,lp->opacity*0.01,0,0,0,0,rb.width,rb.height);
    /*
     * hack to work around bug #3834: if we have use an alternate renderer, the symbolset may contain
     * symbols that reference it. We want to remove those references before the altFormat is destroyed
     * to avoid a segfault and/or a leak, and so the the main renderer doesn't pick the cache up thinking
     * it's for him.
     */
    for(i=0; i<map->symbolset.numsymbols; i++) {
      if (map->symbolset.symbol[i]!=NULL) {
        symbolObj *s = map->symbolset.symbol[i];
        if(s->renderer == altrenderer) {
          altrenderer->freeSymbol(s);
          s->renderer = NULL;
        }
      }
    }
    msFreeImage(image_draw);

  } else if(image != image_draw) {
    rendererVTableObj *renderer = MS_IMAGE_RENDERER(image_draw);
    rasterBufferObj rb;
    memset(&rb,0,sizeof(rasterBufferObj));

    lp->opacity = originalopacity;

    renderer->getRasterBufferHandle(image_draw,&rb);
    renderer->mergeRasterBuffer(image,&rb,lp->opacity*0.01,0,0,0,0,rb.width,rb.height);
    msFreeImage(image_draw);

    /* deref and possibly free temporary transparent output format.  */
    msApplyOutputFormat( &transFormat, NULL, MS_NOOVERRIDE, MS_NOOVERRIDE, MS_NOOVERRIDE );

  }

  free(box.line[0].point);
  free(box.line);

  return MS_SUCCESS;
}
Exemplo n.º 5
0
/*
 * generic function for drawing a legend icon. (added for bug #2348)
 * renderer specific drawing functions shouldn't be called directly, but through
 * this function
 */
int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass,
                     int width, int height, imageObj *image, int dstX, int dstY,
                     int scale_independant, class_hittest *hittest)
{
  int i, type, hasmarkersymbol, ret=MS_SUCCESS;
  double offset;
  double polygon_contraction = 0.5; /* used to account for the width of a polygon's outline */
  shapeObj box, zigzag;
  lineObj box_line,zigzag_line;
  pointObj box_point[5], zigzag_point[4];
  pointObj marker;
  char szPath[MS_MAXPATHLEN];
  styleObj outline_style;
  imageObj *image_draw = image;
  int originalopacity = lp->opacity;
  rendererVTableObj *renderer;
  outputFormatObj *transFormat = NULL, *altFormat=NULL;
  const char *alternativeFormatString = NULL;

  if(!MS_RENDERER_PLUGIN(image->format)) {
    msSetError(MS_MISCERR,"unsupported image format","msDrawLegendIcon()");
    return MS_FAILURE;
  }

  alternativeFormatString = msLayerGetProcessingKey(lp, "RENDERER");
  if (MS_RENDERER_PLUGIN(image_draw->format) && alternativeFormatString!=NULL &&
      (altFormat=  msSelectOutputFormat(map, alternativeFormatString))) {
    msInitializeRendererVTable(altFormat);

    image_draw = msImageCreate(image->width, image->height,
                               altFormat, image->imagepath, image->imageurl, map->resolution, map->defresolution, &map->imagecolor);
    renderer = MS_IMAGE_RENDERER(image_draw);
  } else {
    renderer = MS_IMAGE_RENDERER(image_draw);
    if (lp->opacity > 0 && lp->opacity < 100) {
      if (!renderer->supports_transparent_layers) {
        image_draw = msImageCreate(image->width, image->height,
                                   image->format, image->imagepath, image->imageurl, map->resolution, map->defresolution, NULL);
        if (!image_draw) {
          msSetError(MS_MISCERR, "Unable to initialize temporary transparent image.",
                     "msDrawLegendIcon()");
          return (MS_FAILURE);
        }
        /* set opacity to full, as the renderer should be rendering a fully opaque image */
        lp->opacity=100;
      }
    }
  }


  if(renderer->supports_clipping && MS_VALID_COLOR(map->legend.outlinecolor)) {
    /* keep GD specific code here for now as it supports clipping */
    rectObj clip;
    clip.maxx = dstX + width - 1;
    clip.maxy = dstY + height -1;
    clip.minx = dstX;
    clip.miny = dstY;
    renderer->setClip(image_draw,clip);
  }
  
  /* if the class has a keyimage, treat it as a point layer
   * (the keyimage will be treated there) */
  if(theclass->keyimage != NULL) {
    type = MS_LAYER_POINT;
  } else {
    /* some polygon layers may be better drawn using zigzag if there is no fill */
    type = lp->type;
    if(type == MS_LAYER_POLYGON) {
      type = MS_LAYER_LINE;
      for(i=0; i<theclass->numstyles; i++) {
        if(MS_VALID_COLOR(theclass->styles[i]->color)) { /* there is a fill */
          type = MS_LAYER_POLYGON;
        }
        if(MS_VALID_COLOR(theclass->styles[i]->outlinecolor)) { /* there is an outline */
          polygon_contraction = MS_MAX(polygon_contraction, theclass->styles[i]->width / 2.0);
        }
      }
    }
  }

  /* initialize the box used for polygons and for outlines */
  box.line = &box_line;
  box.numlines = 1;
  box.line[0].point = box_point;
  box.line[0].numpoints = 5;

  box.line[0].point[0].x = dstX + polygon_contraction;
  box.line[0].point[0].y = dstY + polygon_contraction;
  box.line[0].point[1].x = dstX + width - polygon_contraction;
  box.line[0].point[1].y = dstY + polygon_contraction;
  box.line[0].point[2].x = dstX + width - polygon_contraction;
  box.line[0].point[2].y = dstY + height - polygon_contraction;
  box.line[0].point[3].x = dstX + polygon_contraction;
  box.line[0].point[3].y = dstY + height - polygon_contraction;
  box.line[0].point[4].x = box.line[0].point[0].x;
  box.line[0].point[4].y = box.line[0].point[0].y;



  /*
  ** now draw the appropriate color/symbol/size combination
  */
  switch(type) {
    case MS_LAYER_POINT:
      marker.x = dstX + MS_NINT(width / 2.0);
      marker.y = dstY + MS_NINT(height / 2.0);
      if(theclass->keyimage != NULL) {
        int symbolNum;
        styleObj imgStyle;
        symbolObj *symbol=NULL;
        for(symbolNum=0; symbolNum<theclass->numstyles; symbolNum++)
        symbolNum = msAddImageSymbol(&(map->symbolset), msBuildPath(szPath, map->mappath, theclass->keyimage));
        if(symbolNum == -1) {
          msSetError(MS_IMGERR, "Failed to open legend key image", "msCreateLegendIcon()");
          return(MS_FAILURE);
        }

        symbol = map->symbolset.symbol[symbolNum];

        initStyle(&imgStyle);
        /*set size so that symbol will be scaled properly #3296*/
        if (width/symbol->sizex < height/symbol->sizey)
          imgStyle.size = symbol->sizey*(width/symbol->sizex);
        else
          imgStyle.size = symbol->sizey*(height/symbol->sizey);

        if (imgStyle.size > imgStyle.maxsize)
          imgStyle.maxsize = imgStyle.size;

        imgStyle.symbol = symbolNum;
        ret = msDrawMarkerSymbol(map ,image_draw,&marker,&imgStyle,lp->scalefactor * image_draw->resolutionfactor);
        if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
        /* TO DO: we may want to handle this differently depending on the relative size of the keyimage */
      } else {
        for(i=0; i<theclass->numstyles; i++) {
          if(!scale_independant && map->scaledenom > 0) {
            styleObj *lp = theclass->styles[i];
            if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue;
            if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue;
          }
          if(hittest && hittest->stylehits[i].status == 0) continue;
          ret = msDrawMarkerSymbol(map, image_draw, &marker, theclass->styles[i], lp->scalefactor * image->resolutionfactor);
          if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
        }
      }
      break;
    case MS_LAYER_LINE:
      offset = 1;
      /* To set the offset, we only check the size/width parameter of the first style */
      if (theclass->numstyles > 0) {
        if (theclass->styles[0]->symbol > 0 && theclass->styles[0]->symbol < map->symbolset.numsymbols && 
              map->symbolset.symbol[theclass->styles[0]->symbol]->type != MS_SYMBOL_SIMPLE)
            offset = theclass->styles[0]->size/2;
        else
            offset = theclass->styles[0]->width/2;
      }
      zigzag.line = &zigzag_line;
      zigzag.numlines = 1;
      zigzag.line[0].point = zigzag_point;
      zigzag.line[0].numpoints = 4;

      zigzag.line[0].point[0].x = dstX + offset;
      zigzag.line[0].point[0].y = dstY + height - offset;
      zigzag.line[0].point[1].x = dstX + MS_NINT(width / 3.0) - 1;
      zigzag.line[0].point[1].y = dstY + offset;
      zigzag.line[0].point[2].x = dstX + MS_NINT(2.0 * width / 3.0) - 1;
      zigzag.line[0].point[2].y = dstY + height - offset;
      zigzag.line[0].point[3].x = dstX + width - offset;
      zigzag.line[0].point[3].y = dstY + offset;

      for(i=0; i<theclass->numstyles; i++) {
        if(!scale_independant && map->scaledenom > 0) {
          styleObj *lp = theclass->styles[i];
          if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue;
          if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue;
        }
        if(hittest && hittest->stylehits[i].status == 0) continue;
        if (theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE ||
            theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT ||
            theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) {
          ret = msDrawLineSymbol(map, image_draw, &zigzag, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor);
          if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
        }
        else {
          ret = msDrawTransformedShape(map, image_draw, &zigzag, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor);
          if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
        }
      }

      break;
    case MS_LAYER_CIRCLE:
    case MS_LAYER_RASTER:
    case MS_LAYER_CHART:
    case MS_LAYER_POLYGON:
      for(i=0; i<theclass->numstyles; i++) {
        if(!scale_independant && map->scaledenom > 0) {
          styleObj *lp = theclass->styles[i];
          if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue;
          if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue;
        }
        if(hittest && hittest->stylehits[i].status == 0) continue;
        if (theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE ||
            theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT ||
            theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) {
          ret = msDrawShadeSymbol(map, image_draw, &box, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor);
          if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
        }
        else {
          ret = msDrawTransformedShape(map, image_draw, &box,
                                 theclass->styles[i], lp->scalefactor);
          if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
        }
      }
      break;
    default:
      return MS_FAILURE;
      break;
  } /* end symbol drawing */

  /* handle label styles */
  for(i=0; i<theclass->numlabels; i++) {
    labelObj *l = theclass->labels[i];
    if(!scale_independant && map->scaledenom > 0) {
      if(msScaleInBounds(map->scaledenom, l->minscaledenom, l->maxscaledenom)) {
        int j;
        for(j=0; j<l->numstyles; j++) {
          styleObj *s = l->styles[j];
          marker.x = dstX + MS_NINT(width / 2.0);
          marker.y = dstY + MS_NINT(height / 2.0);
          if(s->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) {
            ret = msDrawMarkerSymbol(map, image_draw, &marker, s, lp->scalefactor);
            if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
          }
        }
      }
    }
  }

  /* handle "pure" text layers, i.e. layers with no symbology */
  hasmarkersymbol = 0;
  if(theclass->numstyles == 0) {
    for(i=0; i<theclass->numlabels; i++) {
      labelObj *l = theclass->labels[i];
      if(!scale_independant && map->scaledenom > 0) {
        if(msScaleInBounds(map->scaledenom, l->minscaledenom, l->maxscaledenom)) {
          int j;
          for(j=0; j<l->numstyles; j++) {
            styleObj *s = l->styles[j];
            if(s->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) {
              hasmarkersymbol = 1;
            }
          }
        }
      }
    }
  } else {
    hasmarkersymbol = 1;
  }

  if(!hasmarkersymbol && theclass->numlabels>0) {
    textSymbolObj ts;
    pointObj textstartpt;
    marker.x = dstX + MS_NINT(width / 2.0);
    marker.y = dstY + MS_NINT(height / 2.0);
    initTextSymbol(&ts);
    msPopulateTextSymbolForLabelAndString(&ts,theclass->labels[0],msStrdup("Az"),lp->scalefactor*image_draw->resolutionfactor,image_draw->resolutionfactor, duplicate_always);
    ts.label->size = height - 1;
    ret = msComputeTextPath(map,&ts);
    if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
    textstartpt = get_metrics(&marker,MS_CC,ts.textpath,0,0,0,0,NULL);
    ret = msDrawTextSymbol(map,image_draw, textstartpt, &ts);
    freeTextSymbol(&ts);
    if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;

  }


  /* handle an outline if necessary */
  if(MS_VALID_COLOR(map->legend.outlinecolor)) {
    initStyle(&outline_style);
    outline_style.color = map->legend.outlinecolor;
    ret = msDrawLineSymbol(map, image_draw, &box, &outline_style, image_draw->resolutionfactor);
    if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
    /* reset clipping rectangle */
    if(renderer->supports_clipping)
      renderer->resetClip(image_draw);
  }

  if (altFormat) {
    rendererVTableObj *renderer = MS_IMAGE_RENDERER(image);
    rendererVTableObj *altrenderer = MS_IMAGE_RENDERER(image_draw);
    rasterBufferObj rb;
    memset(&rb,0,sizeof(rasterBufferObj));

    ret = altrenderer->getRasterBufferHandle(image_draw,&rb);
    if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
    ret = renderer->mergeRasterBuffer(image,&rb,lp->opacity*0.01,0,0,0,0,rb.width,rb.height);
    if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
    /*
     * hack to work around bug #3834: if we have use an alternate renderer, the symbolset may contain
     * symbols that reference it. We want to remove those references before the altFormat is destroyed
     * to avoid a segfault and/or a leak, and so the the main renderer doesn't pick the cache up thinking
     * it's for him.
     */
    for(i=0; i<map->symbolset.numsymbols; i++) {
      if (map->symbolset.symbol[i]!=NULL) {
        symbolObj *s = map->symbolset.symbol[i];
        if(s->renderer == altrenderer) {
          altrenderer->freeSymbol(s);
          s->renderer = NULL;
        }
      }
    }

  } else if(image != image_draw) {
    rendererVTableObj *renderer = MS_IMAGE_RENDERER(image_draw);
    rasterBufferObj rb;
    memset(&rb,0,sizeof(rasterBufferObj));

    lp->opacity = originalopacity;

    ret = renderer->getRasterBufferHandle(image_draw,&rb);
    if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
    ret = renderer->mergeRasterBuffer(image,&rb,lp->opacity*0.01,0,0,0,0,rb.width,rb.height);
    if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;

    /* deref and possibly free temporary transparent output format.  */
    msApplyOutputFormat( &transFormat, NULL, MS_NOOVERRIDE, MS_NOOVERRIDE, MS_NOOVERRIDE );

  }

legend_icon_cleanup:
  if(image != image_draw) {
    msFreeImage(image_draw);
  }
  return ret;
}
Exemplo n.º 6
0
void msWriteErrorImage(mapObj *map, char *filename, int blank) {
    imageObj *img;
    rendererVTableObj *renderer;
    int font_index = 0;
    int width=400, height=300;
    int nMargin =5;
    int nTextLength = 0;
    int nUsableWidth = 0;
    int nMaxCharsPerLine = 0;
    int nLines = 0;
    int i = 0;
    int nStart = 0;
    int nEnd = 0;
    int nLength = 0;
    char **papszLines = NULL;
    int nXPos = 0;
    int nYPos = 0;
    int nWidthTxt = 0;
    outputFormatObj *format = NULL;
    char *errormsg = msGetErrorString("; ");
    fontMetrics *font = NULL;
    char *imagepath = NULL, *imageurl = NULL;
    labelStyleObj ls;
    colorObj labelcolor, labeloutlinecolor, imagecolor, *imagecolorptr=NULL;
    ls.color = &labelcolor;
    ls.outlinecolor = &labeloutlinecolor;

    if (map) {
        if( map->width > 0 && map->height > 0 )
        {
            width = map->width;
            height = map->height;
        }
        format = map->outputformat;
        imagepath = map->web.imagepath;
        imageurl = map->web.imageurl;
    }

    /* Default to GIF if no suitable GD output format set */
    if (format == NULL || !MS_RENDERER_PLUGIN(format) || !format->vtable->supports_bitmap_fonts)
        format = msCreateDefaultOutputFormat( NULL, "GD/PC256", "gif" );

    if(!format->transparent) {
        if(map && MS_VALID_COLOR(map->imagecolor)) {
            imagecolorptr = &map->imagecolor;
        } else {
            MS_INIT_COLOR(imagecolor,255,255,255,255);
            imagecolorptr = &imagecolor;
        }
    }

    img = msImageCreate(width,height,format,imagepath,imageurl,MS_DEFAULT_RESOLUTION,MS_DEFAULT_RESOLUTION,imagecolorptr);
    renderer = MS_IMAGE_RENDERER(img);

    for(i=0; i<5; i++) {
        /* use the first font we find */
        if((font = renderer->bitmapFontMetrics[font_index]) != NULL) {
            ls.size = i;
            MS_INIT_COLOR(*ls.color,0,0,0,255);
            MS_INIT_COLOR(*ls.outlinecolor,255,255,255,255);
            break;
        }
    }
    /* if no font found we can't do much. this shouldn't happen */
    if(font) {

        nTextLength = strlen(errormsg);
        nWidthTxt  =  nTextLength * font->charWidth;
        nUsableWidth = width - (nMargin*2);

        /* Check to see if it all fits on one line. If not, split the text on several lines. */
        if(!blank) {
            if (nWidthTxt > nUsableWidth) {
                nMaxCharsPerLine =  nUsableWidth/font->charWidth;
                nLines = (int) ceil ((double)nTextLength / (double)nMaxCharsPerLine);
                if (nLines > 0) {
                    papszLines = (char **)malloc(nLines*sizeof(char *));
                    for (i=0; i<nLines; i++) {
                        papszLines[i] = (char *)malloc((nMaxCharsPerLine+1)*sizeof(char));
                        papszLines[i][0] = '\0';
                    }
                }
                for (i=0; i<nLines; i++) {
                    nStart = i*nMaxCharsPerLine;
                    nEnd = nStart + nMaxCharsPerLine;
                    if (nStart < nTextLength) {
                        if (nEnd > nTextLength)
                            nEnd = nTextLength;
                        nLength = nEnd-nStart;

                        strncpy(papszLines[i], errormsg+nStart, nLength);
                        papszLines[i][nLength] = '\0';
                    }
                }
            } else {
                nLines = 1;
                papszLines = (char **)malloc(nLines*sizeof(char *));
                papszLines[0] = msStrdup(errormsg);
            }
            for (i=0; i<nLines; i++) {
                nYPos = (font->charHeight) * ((i*2) +1);
                nXPos = font->charWidth;;
                renderer->renderBitmapGlyphs(img, nXPos, nYPos, &ls, papszLines[i]);
            }
            if (papszLines) {
                for (i=0; i<nLines; i++) {
                    free(papszLines[i]);
                }
                free(papszLines);
            }
        }
    }

    /* actually write the image */
    if(!filename) {
        msIO_setHeader("Content-type","%s", MS_IMAGE_MIME_TYPE(format));
        msIO_sendHeaders();
    }
    msSaveImage(NULL,img,filename);
    msFreeImage(img);

    if (format->refcount == 0)
        msFreeOutputFormat(format);
    msFree(errormsg);
}
Exemplo n.º 7
0
int msDrawMarkerSymbol(mapObj *map, imageObj *image, pointObj *p, styleObj *style,
                       double scalefactor)
{
  int ret = MS_SUCCESS;
  if (!p)
    return MS_SUCCESS;
  if (style->symbol >= map->symbolset.numsymbols || style->symbol <= 0)
    return MS_SUCCESS; /* no such symbol, 0 is OK   */

  if (image) {
    if(MS_RENDERER_PLUGIN(image->format)) {
      rendererVTableObj *renderer = image->format->vtable;
      symbolStyleObj s;
      double p_x,p_y;
      symbolObj *symbol = map->symbolset.symbol[style->symbol];
      /* store a reference to the renderer to be used for freeing */
      symbol->renderer = renderer;
      if(preloadSymbol(&map->symbolset,symbol,renderer) != MS_SUCCESS) {
        return MS_FAILURE;
      }

      computeSymbolStyle(&s,style,symbol,scalefactor,image->resolutionfactor);
      s.style = style;
      if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP &&
          symbol->type != MS_SYMBOL_SVG) {
        return MS_SUCCESS; // nothing to do if no color, except for pixmap symbols
      }
      if(s.scale == 0) {
        return MS_SUCCESS;
      }



      /* TODO: skip the drawing of the symbol if it's smaller than a pixel ?
      if (s.size < 1)
       return; // size too small
       */

      p_x = p->x;
      p_y = p->y;

      if (style->polaroffsetpixel != 0 ||
          style->polaroffsetangle != 0) {
        double angle = style->polaroffsetangle * MS_DEG_TO_RAD;
        p_x +=  (style->polaroffsetpixel * cos(-angle)) * scalefactor;
        p_y +=  (style->polaroffsetpixel * sin(-angle)) * scalefactor;
      }

      p_x +=  style->offsetx * scalefactor;
      p_y +=  style->offsety * scalefactor;

      if(symbol->anchorpoint_x != 0.5 || symbol->anchorpoint_y != 0.5) {
        double sx,sy;
        double ox, oy;
        if(UNLIKELY(MS_FAILURE == msGetMarkerSize(map, style, &sx, &sy, scalefactor))) {
          return MS_FAILURE;
        }
        ox = (0.5 - symbol->anchorpoint_x) * sx;
        oy = (0.5 - symbol->anchorpoint_y) * sy;
        if(s.rotation != 0) {
          double sina, cosa;
          double rox,roy;
          sina = sin(-s.rotation);
          cosa = cos(-s.rotation);
          rox = ox * cosa - oy * sina;
          roy = ox * sina + oy * cosa;
          p_x += rox;
          p_y += roy;
        } else {
          p_x += ox;
          p_y += oy;
        }
      }

      if(renderer->use_imagecache) {
        imageObj *tile = getTile(image, symbol, &s, -1, -1,0);
        if(tile!=NULL)
          return renderer->renderTile(image, tile, p_x, p_y);
        else {
          msSetError(MS_RENDERERERR, "problem creating cached tile", "msDrawMarkerSymbol()");
          return MS_FAILURE;
        }
      }
      switch (symbol->type) {
        case (MS_SYMBOL_TRUETYPE): {
          unsigned int unicode;
          glyph_element *glyphc;
          face_element *face = msGetFontFace(symbol->font, &map->fontset);
          if(UNLIKELY(!face)) return MS_FAILURE;
          msUTF8ToUniChar(symbol->character,&unicode);
          unicode = msGetGlyphIndex(face,unicode);
          glyphc = msGetGlyphByIndex(face,s.scale,unicode);
          if(UNLIKELY(!glyphc)) return MS_FAILURE;
          ret = drawGlyphMarker(image, face, glyphc, p_x, p_y, s.scale, s.rotation, s.color, s.outlinecolor, s.outlinewidth);
        }
        break;
        case (MS_SYMBOL_PIXMAP): {
          assert(symbol->pixmap_buffer);
          ret = renderer->renderPixmapSymbol(image,p_x,p_y,symbol,&s);
        }
        break;
        case (MS_SYMBOL_ELLIPSE): {
          ret = renderer->renderEllipseSymbol(image, p_x, p_y,symbol, &s);
        }
        break;
        case (MS_SYMBOL_VECTOR): {
          ret = renderer->renderVectorSymbol(image, p_x, p_y, symbol, &s);
        }
        break;
        case (MS_SYMBOL_SVG): {
          if (renderer->supports_svg) {
            ret = renderer->renderSVGSymbol(image, p_x, p_y, symbol, &s);
          } else {
#if defined(USE_SVG_CAIRO) || defined(USE_RSVG)
            ret = msRenderRasterizedSVGSymbol(image, p_x,p_y, symbol, &s);
#else
            msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawMarkerSymbol()");
            return MS_FAILURE;
#endif
          }
        }
        break;
        default:
          break;
      }
      return ret;
    } else if( MS_RENDERER_IMAGEMAP(image->format) )
      msDrawMarkerSymbolIM(map, image, p, style, scalefactor);

  }
  return ret;
}
Exemplo n.º 8
0
int msDrawShadeSymbol(mapObj *map, imageObj *image, shapeObj *p, styleObj *style, double scalefactor)
{
  int ret = MS_SUCCESS;
  symbolObj *symbol;
  if (!p)
    return MS_SUCCESS;
  if (p->numlines <= 0)
    return MS_SUCCESS;

  if (style->symbol >= map->symbolset.numsymbols || style->symbol < 0)
    return MS_SUCCESS; /* no such symbol, 0 is OK */
  symbol = map->symbolset.symbol[style->symbol];

  /*
   * if only an outlinecolor was defined, and not a color,
   * switch to the line drawing function
   *
   * this behavior is kind of a mapfile hack, and must be
   * kept for backwards compatibility
   */
  if (symbol->type != MS_SYMBOL_PIXMAP && symbol->type != MS_SYMBOL_SVG ) {
    if (!MS_VALID_COLOR(style->color)) {
      if(MS_VALID_COLOR(style->outlinecolor))
        return msDrawLineSymbol(map, image, p, style, scalefactor);
      else {
        /* just do nothing if no color has been set */
        return MS_SUCCESS;
      }
    }
  }
  if (image) {
    if (MS_RENDERER_PLUGIN(image->format)) {
      rendererVTableObj *renderer = image->format->vtable;
      shapeObj *offsetPolygon = NULL;
      /* store a reference to the renderer to be used for freeing */
      if(style->symbol)
        symbol->renderer = renderer;

      if (style->offsetx != 0 || style->offsety != 0) {
        if(style->offsety==MS_STYLE_SINGLE_SIDED_OFFSET) {
          offsetPolygon = msOffsetPolyline(p, style->offsetx*scalefactor, MS_STYLE_SINGLE_SIDED_OFFSET);
        } else if(style->offsety==MS_STYLE_DOUBLE_SIDED_OFFSET) {
          offsetPolygon = msOffsetPolyline(p,style->offsetx * scalefactor ,MS_STYLE_DOUBLE_SIDED_OFFSET);
        } else {
          offsetPolygon = msOffsetPolyline(p, style->offsetx*scalefactor,style->offsety*scalefactor);
        }
      } else {
        offsetPolygon=p;
      }
      /* simple polygon drawing, without any specific symbol.
       * also draws an optional outline */
      if(style->symbol == 0 || symbol->type == MS_SYMBOL_SIMPLE) {
        ret = renderer->renderPolygon(image,offsetPolygon,&style->color);
        if(ret != MS_SUCCESS) goto cleanup;
        if(MS_VALID_COLOR(style->outlinecolor)) {
          strokeStyleObj s;
          INIT_STROKE_STYLE(s);
          s.color = &style->outlinecolor;
          s.color->alpha = style->color.alpha;
          s.width = (style->width == 0)?scalefactor:style->width*scalefactor;
          s.width = MS_MIN(s.width, style->maxwidth);
          s.width = MS_MAX(s.width, style->minwidth);
          ret = renderer->renderLine(image,offsetPolygon,&s);
        }
        goto cleanup; /*finished plain polygon*/
      } else if(symbol->type == MS_SYMBOL_HATCH) {
        double width, spacing;
        double pattern[MS_MAXPATTERNLENGTH];
        int i;

        if(MS_VALID_COLOR(style->backgroundcolor)) {
          ret = renderer->renderPolygon(image,offsetPolygon, &style->backgroundcolor);
          if(ret != MS_SUCCESS) goto cleanup;
        }
        width = (style->width <= 0)?scalefactor:style->width*scalefactor;
        width = MS_MIN(width, style->maxwidth*image->resolutionfactor);
        width = MS_MAX(width, style->minwidth*image->resolutionfactor);
        spacing = (style->size <= 0)?scalefactor:style->size*scalefactor;
        spacing = MS_MIN(spacing, style->maxsize*image->resolutionfactor);
        spacing = MS_MAX(spacing, style->minsize*image->resolutionfactor);

        /* scale the pattern by the factor applied to the width */
        for(i=0; i<style->patternlength; i++) {
          pattern[i] = style->pattern[i]*width/style->width;
        }

        ret = msHatchPolygon(image,offsetPolygon,spacing,width,pattern,style->patternlength,style->angle, &style->color);
        goto cleanup;
      } else {
        symbolStyleObj s;
        int pw,ph;
        imageObj *tile;
        int seamless = 0;

        if(preloadSymbol(&map->symbolset,symbol,renderer) != MS_SUCCESS) {
          return MS_FAILURE;
        }

        INIT_SYMBOL_STYLE(s);
        computeSymbolStyle(&s,style,symbol,scalefactor,image->resolutionfactor);
        s.style = style;

        if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP && symbol->type != MS_SYMBOL_SVG) {
          ret = MS_SUCCESS; /* nothing to do (colors are required except for PIXMAP symbols */
          goto cleanup;
        }

        if(s.backgroundcolor) {
          ret = renderer->renderPolygon(image,offsetPolygon, s.backgroundcolor);
          if(ret != MS_SUCCESS) goto cleanup;
        }

        if(s.scale != 1) {
          if (s.gap > 0) {
            pw = MS_MAX(MS_NINT(s.gap),symbol->sizex * s.scale);
            ph = MS_MAX(MS_NINT(s.gap),symbol->sizey * s.scale);
          } else {
            pw = MS_NINT(symbol->sizex * s.scale);
            ph = MS_NINT(symbol->sizey * s.scale);
          }
        } else {
          if (s.gap > 0) {
            pw = MS_MAX(s.gap,symbol->sizex);
            ph = MS_MAX(s.gap,symbol->sizey);
          } else {
            pw = symbol->sizex;
            ph = symbol->sizey;
          }
        }
        if(pw<1) pw=1;
        if(ph<1) ph=1;

        /* if we're doing vector symbols with an antialiased pixel rendererer, we want to enable
         * seamless mode, i.e. comute a tile that accounts for the blending of neighbouring
         * tiles at the tile border
         */
        if(symbol->type == MS_SYMBOL_VECTOR && style->gap == 0 &&
            (image->format->renderer == MS_RENDER_WITH_AGG ||
             image->format->renderer == MS_RENDER_WITH_CAIRO_RASTER)) {
          seamless = 1;
        }
        tile = getTile(image,symbol,&s,pw,ph,seamless);
        ret = renderer->renderPolygonTiled(image,offsetPolygon, tile);
      }

cleanup:
      if (offsetPolygon != p) {
        msFreeShape(offsetPolygon);
        msFree(offsetPolygon);
      }
      return ret;
    } else if( MS_RENDERER_IMAGEMAP(image->format) )
      msDrawShadeSymbolIM(map, image, p, style, scalefactor);
  }
  return ret;
}
Exemplo n.º 9
0
int msDrawLineSymbol(mapObj *map, imageObj *image, shapeObj *p,
                     styleObj *style, double scalefactor)
{
  int status = MS_SUCCESS;
  if (image) {
    if (MS_RENDERER_PLUGIN(image->format)) {
      rendererVTableObj *renderer = image->format->vtable;
      symbolObj *symbol;
      shapeObj *offsetLine = p;
      int i;
      double width;
      double finalscalefactor;

      if (p->numlines == 0)
        return MS_SUCCESS;

      if (style->symbol >= map->symbolset.numsymbols || style->symbol < 0)
        return MS_SUCCESS; /* no such symbol, 0 is OK   */

      symbol = map->symbolset.symbol[style->symbol];
      /* store a reference to the renderer to be used for freeing */
      symbol->renderer = renderer;

      width = style->width * scalefactor;
      width = MS_MIN(width,style->maxwidth*image->resolutionfactor);
      width = MS_MAX(width,style->minwidth*image->resolutionfactor);
      if(style->width != 0) {
        finalscalefactor = width / style->width;
      } else {
        finalscalefactor = 1.0;
      }

      if(style->offsety==MS_STYLE_SINGLE_SIDED_OFFSET) {
        offsetLine = msOffsetPolyline(p,style->offsetx * finalscalefactor ,MS_STYLE_SINGLE_SIDED_OFFSET);
      } else if(style->offsety==MS_STYLE_DOUBLE_SIDED_OFFSET) {
        offsetLine = msOffsetPolyline(p,style->offsetx * finalscalefactor ,MS_STYLE_DOUBLE_SIDED_OFFSET);
      } else if(style->offsetx!=0 || style->offsety!=0) {
        offsetLine = msOffsetPolyline(p, style->offsetx * finalscalefactor,
                                      style->offsety * finalscalefactor);
      }
      if(style->symbol == 0 || (symbol->type==MS_SYMBOL_SIMPLE)) {
        strokeStyleObj s;
        s.linecap = style->linecap;
        s.linejoin = style->linejoin;
        s.linejoinmaxsize = style->linejoinmaxsize;
        s.width = width;
        s.patternlength = style->patternlength;
        for(i=0; i<s.patternlength; i++)
          s.pattern[i] = style->pattern[i] * finalscalefactor;
        s.patternoffset = (style->initialgap<=0) ? 0 : (style->initialgap * finalscalefactor);

        if(MS_VALID_COLOR(style->color))
          s.color = &style->color;
        else if(MS_VALID_COLOR(style->outlinecolor))
          s.color = &style->outlinecolor;
        else {
          /* msSetError(MS_MISCERR,"no color defined for line styling","msDrawLineSymbol()");
           * not really an error */
          status = MS_SUCCESS;
          goto draw_line_cleanup;
        }
        status = renderer->renderLine(image,offsetLine,&s);
      } else {
        symbolStyleObj s;
        if(preloadSymbol(&map->symbolset, symbol, renderer) != MS_SUCCESS) {
          return MS_FAILURE;
        }

        INIT_SYMBOL_STYLE(s);
        computeSymbolStyle(&s,style,symbol,scalefactor,image->resolutionfactor);
        s.style = style;

        /* compute a markerStyle and use it on the line */
        if(style->gap<0) {
          /* special function that treats any other symbol used as a marker, not a brush */
          status = msImagePolylineMarkers(image,offsetLine,symbol,&s,-s.gap,
                                 style->initialgap * finalscalefactor, 1);
        } else if(style->gap>0) {
          status = msImagePolylineMarkers(image,offsetLine,symbol,&s,s.gap,
                                 style->initialgap * finalscalefactor,0);
        } else {
          if(renderer->renderLineTiled != NULL) {
            int pw,ph;
            imageObj* tile=NULL;
            if(s.scale != 1) {
              pw = MS_NINT(symbol->sizex * s.scale);
              ph = MS_NINT(symbol->sizey * s.scale);
            } else {
              pw = symbol->sizex;
              ph = symbol->sizey;
            }
            if(pw<1) pw=1;
            if(ph<1) ph=1;
            tile = getTile(image, symbol,&s,pw,ph,0);
            status = renderer->renderLineTiled(image, offsetLine, tile);
          } else {
            msSetError(MS_RENDERERERR, "renderer does not support brushed lines", "msDrawLineSymbol()");
            status = MS_FAILURE;
          }
        }
      }

draw_line_cleanup:
      if(offsetLine!=p) {
        msFreeShape(offsetLine);
        msFree(offsetLine);
      }
    } else if( MS_RENDERER_IMAGEMAP(image->format) )
      msDrawLineSymbolIM(map, image, p, style, scalefactor);
    else {
      msSetError(MS_RENDERERERR, "unsupported renderer", "msDrawShadeSymbol()");
      status = MS_FAILURE;
    }
  } else {
    status = MS_FAILURE;
  }
  return status;
}
Exemplo n.º 10
0
int msSaveImageGDAL( mapObj *map, imageObj *image, char *filename )

{
  int  bFileIsTemporary = MS_FALSE;
  GDALDatasetH hMemDS, hOutputDS;
  GDALDriverH  hMemDriver, hOutputDriver;
  int          nBands = 1;
  int          iLine;
  GByte       *pabyAlphaLine = NULL;
  char        **papszOptions = NULL;
  outputFormatObj *format = image->format;
  rasterBufferObj rb;
  GDALDataType eDataType = GDT_Byte;
  int bUseXmp = MS_FALSE;

  msGDALInitialize();
  memset(&rb,0,sizeof(rasterBufferObj));

#ifdef USE_EXEMPI
  if( map != NULL ) {
    bUseXmp = msXmpPresent(map);
  }
#endif


  /* -------------------------------------------------------------------- */
  /*      Identify the proposed output driver.                            */
  /* -------------------------------------------------------------------- */
  msAcquireLock( TLOCK_GDAL );
  hOutputDriver = GDALGetDriverByName( format->driver+5 );
  if( hOutputDriver == NULL ) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to find %s driver.",
                "msSaveImageGDAL()", format->driver+5 );
    return MS_FAILURE;
  }

  /* -------------------------------------------------------------------- */
  /*      We will need to write the output to a temporary file and        */
  /*      then stream to stdout if no filename is passed.  If the         */
  /*      driver supports virtualio then we hold the temporary file in    */
  /*      memory, otherwise we try to put it in a reasonable temporary    */
  /*      file location.                                                  */
  /* -------------------------------------------------------------------- */
  if( filename == NULL ) {
    const char *pszExtension = format->extension;
    if( pszExtension == NULL )
      pszExtension = "img.tmp";

    if( bUseXmp == MS_FALSE && GDALGetMetadataItem( hOutputDriver, GDAL_DCAP_VIRTUALIO, NULL )
        != NULL ) {
      CleanVSIDir( "/vsimem/msout" );
      filename = msTmpFile(map, NULL, "/vsimem/msout/", pszExtension );
    }

    if( filename == NULL && map != NULL)
      filename = msTmpFile(map, map->mappath,NULL,pszExtension);
    else if( filename == NULL ) {
      filename = msTmpFile(map, NULL, NULL, pszExtension );
    }

    bFileIsTemporary = MS_TRUE;
  }

  /* -------------------------------------------------------------------- */
  /*      Establish the characteristics of our memory, and final          */
  /*      dataset.                                                        */
  /* -------------------------------------------------------------------- */

  if( format->imagemode == MS_IMAGEMODE_RGB ) {
    nBands = 3;
    assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer );
    format->vtable->getRasterBufferHandle(image,&rb);
  } else if( format->imagemode == MS_IMAGEMODE_RGBA ) {
    pabyAlphaLine = (GByte *) calloc(image->width,1);
    if (pabyAlphaLine == NULL) {
      msReleaseLock( TLOCK_GDAL );
      msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", image->width);
      return MS_FAILURE;
    }
    nBands = 4;
    assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer );
    format->vtable->getRasterBufferHandle(image,&rb);
  } else if( format->imagemode == MS_IMAGEMODE_INT16 ) {
    nBands = format->bands;
    eDataType = GDT_Int16;
  } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) {
    nBands = format->bands;
    eDataType = GDT_Float32;
  } else if( format->imagemode == MS_IMAGEMODE_BYTE ) {
    nBands = format->bands;
    eDataType = GDT_Byte;
  } else {
#ifdef USE_GD
    assert( format->imagemode == MS_IMAGEMODE_PC256
            && format->renderer == MS_RENDER_WITH_GD );
#else
    {
      msReleaseLock( TLOCK_GDAL );
      msSetError( MS_MEMERR, "GD not compiled in. This is a bug.", "msSaveImageGDAL()");
      return MS_FAILURE;
    }
#endif

  }

  /* -------------------------------------------------------------------- */
  /*      Create a memory dataset which we can use as a source for a      */
  /*      CreateCopy().                                                   */
  /* -------------------------------------------------------------------- */
  hMemDriver = GDALGetDriverByName( "MEM" );
  if( hMemDriver == NULL ) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to find MEM driver.",
                "msSaveImageGDAL()" );
    return MS_FAILURE;
  }

  hMemDS = GDALCreate( hMemDriver, "msSaveImageGDAL_temp",
                       image->width, image->height, nBands,
                       eDataType, NULL );
  if( hMemDS == NULL ) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to create MEM dataset.",
                "msSaveImageGDAL()" );
    return MS_FAILURE;
  }

  /* -------------------------------------------------------------------- */
  /*      Copy the gd image into the memory dataset.                      */
  /* -------------------------------------------------------------------- */
  for( iLine = 0; iLine < image->height; iLine++ ) {
    int iBand;

    for( iBand = 0; iBand < nBands; iBand++ ) {
      GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 );

      if( format->imagemode == MS_IMAGEMODE_INT16 ) {
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      image->img.raw_16bit + iLine * image->width
                      + iBand * image->width * image->height,
                      image->width, 1, GDT_Int16, 2, 0 );

      } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) {
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      image->img.raw_float + iLine * image->width
                      + iBand * image->width * image->height,
                      image->width, 1, GDT_Float32, 4, 0 );
      } else if( format->imagemode == MS_IMAGEMODE_BYTE ) {
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      image->img.raw_byte + iLine * image->width
                      + iBand * image->width * image->height,
                      image->width, 1, GDT_Byte, 1, 0 );
      }
#ifdef USE_GD
      else if(format->renderer == MS_RENDER_WITH_GD) {
        gdImagePtr img = (gdImagePtr)image->img.plugin;
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      img->pixels[iLine],
                      image->width, 1, GDT_Byte, 0, 0 );
      }
#endif
      else {
        GByte *pabyData;
        unsigned char *pixptr = NULL;
        assert( rb.type == MS_BUFFER_BYTE_RGBA );
        switch(iBand) {
          case 0:
            pixptr = rb.data.rgba.r;
            break;
          case 1:
            pixptr = rb.data.rgba.g;
            break;
          case 2:
            pixptr = rb.data.rgba.b;
            break;
          case 3:
            pixptr = rb.data.rgba.a;
            break;
        }
        assert(pixptr);
        if( pixptr == NULL ) {
          msReleaseLock( TLOCK_GDAL );
          msSetError( MS_MISCERR, "Missing RGB or A buffer.\n",
                      "msSaveImageGDAL()" );
          return MS_FAILURE;
        }

        pabyData = (GByte *)(pixptr + iLine*rb.data.rgba.row_step);

        if( rb.data.rgba.a == NULL || iBand == 3 ) {
          GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                        pabyData, image->width, 1, GDT_Byte,
                        rb.data.rgba.pixel_step, 0 );
        } else { /* We need to un-pre-multiple RGB by alpha. */
          GByte *pabyUPM = (GByte*) malloc(image->width);
          GByte *pabyAlpha= (GByte *)(rb.data.rgba.a + iLine*rb.data.rgba.row_step);
          int i;

          for( i = 0; i < image->width; i++ ) {
            int alpha = pabyAlpha[i*rb.data.rgba.pixel_step];

            if( alpha == 0 )
              pabyUPM[i] = 0;
            else {
              int result = (pabyData[i*rb.data.rgba.pixel_step] * 255) / alpha;

              if( result > 255 )
                result = 255;

              pabyUPM[i] = result;
            }
          }

          GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                        pabyUPM, image->width, 1, GDT_Byte, 1, 0 );
          free( pabyUPM );
        }
      }
    }
  }

  if( pabyAlphaLine != NULL )
    free( pabyAlphaLine );

  /* -------------------------------------------------------------------- */
  /*      Attach the palette if appropriate.                              */
  /* -------------------------------------------------------------------- */
#ifdef USE_GD
  if( format->renderer == MS_RENDER_WITH_GD ) {
    GDALColorEntry sEntry;
    int  iColor;
    GDALColorTableH hCT;
    gdImagePtr img = (gdImagePtr)image->img.plugin;
    hCT = GDALCreateColorTable( GPI_RGB );

    for( iColor = 0; iColor < img->colorsTotal; iColor++ ) {
      sEntry.c1 = img->red[iColor];
      sEntry.c2 = img->green[iColor];
      sEntry.c3 = img->blue[iColor];

      if( iColor == gdImageGetTransparent( img ) )
        sEntry.c4 = 0;
      else if( iColor == 0
               && gdImageGetTransparent( img ) == -1
               && format->transparent )
        sEntry.c4 = 0;
      else
        sEntry.c4 = 255;

      GDALSetColorEntry( hCT, iColor, &sEntry );
    }

    GDALSetRasterColorTable( GDALGetRasterBand( hMemDS, 1 ), hCT );

    GDALDestroyColorTable( hCT );
  } else
#endif
    if( format->imagemode == MS_IMAGEMODE_RGB ) {
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
    } else if( format->imagemode == MS_IMAGEMODE_RGBA ) {
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 4 ), GCI_AlphaBand );
    }

  /* -------------------------------------------------------------------- */
  /*      Assign the projection and coordinate system to the memory       */
  /*      dataset.                                                        */
  /* -------------------------------------------------------------------- */

  if( map != NULL ) {
    char *pszWKT;

    GDALSetGeoTransform( hMemDS, map->gt.geotransform );

    pszWKT = msProjectionObj2OGCWKT( &(map->projection) );
    if( pszWKT != NULL ) {
      GDALSetProjection( hMemDS, pszWKT );
      msFree( pszWKT );
    }
  }

  /* -------------------------------------------------------------------- */
  /*      Possibly assign a nodata value.                                 */
  /* -------------------------------------------------------------------- */
  if( msGetOutputFormatOption(format,"NULLVALUE",NULL) != NULL ) {
    int iBand;
    const char *nullvalue = msGetOutputFormatOption(format,
                            "NULLVALUE",NULL);

    for( iBand = 0; iBand < nBands; iBand++ ) {
      GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 );
      GDALSetRasterNoDataValue( hBand, atof(nullvalue) );
    }
  }

  /* -------------------------------------------------------------------- */
  /*  Try to save resolution in the output file.                          */
  /* -------------------------------------------------------------------- */
  if( image->resolution > 0 ) {
    char res[30];

    sprintf( res, "%lf", image->resolution );
    GDALSetMetadataItem( hMemDS, "TIFFTAG_XRESOLUTION", res, NULL );
    GDALSetMetadataItem( hMemDS, "TIFFTAG_YRESOLUTION", res, NULL );
    GDALSetMetadataItem( hMemDS, "TIFFTAG_RESOLUTIONUNIT", "2", NULL );
  }

  /* -------------------------------------------------------------------- */
  /*      Create a disk image in the selected output format from the      */
  /*      memory image.                                                   */
  /* -------------------------------------------------------------------- */
  papszOptions = (char**)calloc(sizeof(char *),(format->numformatoptions+1));
  if (papszOptions == NULL) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()",
                (unsigned int)(sizeof(char *)*(format->numformatoptions+1)));
    return MS_FAILURE;
  }

  memcpy( papszOptions, format->formatoptions,
          sizeof(char *) * format->numformatoptions );

  hOutputDS = GDALCreateCopy( hOutputDriver, filename, hMemDS, FALSE,
                              papszOptions, NULL, NULL );

  free( papszOptions );

  if( hOutputDS == NULL ) {
    GDALClose( hMemDS );
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to create output %s file.\n%s",
                "msSaveImageGDAL()", format->driver+5,
                CPLGetLastErrorMsg() );
    return MS_FAILURE;
  }

  /* closing the memory DS also frees all associated resources. */
  GDALClose( hMemDS );

  GDALClose( hOutputDS );
  msReleaseLock( TLOCK_GDAL );


  /* -------------------------------------------------------------------- */
  /*      Are we writing license info into the image?                     */
  /*      If so, add it to the temp file on disk now.                     */
  /* -------------------------------------------------------------------- */
#ifdef USE_EXEMPI
  if ( bUseXmp == MS_TRUE ) {
    if( msXmpWrite(map, filename) == MS_FAILURE ) {
      /* Something bad happened. */
      msSetError( MS_MISCERR, "XMP write to %s failed.\n",
                  "msSaveImageGDAL()", filename);
      return MS_FAILURE;
    }
  }
#endif

  /* -------------------------------------------------------------------- */
  /*      Is this supposed to be a temporary file?  If so, stream to      */
  /*      stdout and delete the file.                                     */
  /* -------------------------------------------------------------------- */
  if( bFileIsTemporary ) {
    FILE *fp;
    unsigned char block[4000];
    int bytes_read;

    if( msIO_needBinaryStdout() == MS_FAILURE )
      return MS_FAILURE;

    /* We aren't sure how far back GDAL exports the VSI*L API, so
       we only use it if we suspect we need it.  But we do need it if
       holding temporary file in memory. */
    fp = VSIFOpenL( filename, "rb" );
    if( fp == NULL ) {
      msSetError( MS_MISCERR,
                  "Failed to open %s for streaming to stdout.",
                  "msSaveImageGDAL()", filename );
      return MS_FAILURE;
    }

    while( (bytes_read = VSIFReadL(block, 1, sizeof(block), fp)) > 0 )
      msIO_fwrite( block, 1, bytes_read, stdout );

    VSIFCloseL( fp );

    VSIUnlink( filename );
    CleanVSIDir( "/vsimem/msout" );

    free( filename );
  }

  return MS_SUCCESS;
}
Exemplo n.º 11
0
/************************************************************************
 *                            msTileExtractSubTile                      *
 *                                                                      * 
 ************************************************************************/
static imageObj* msTileExtractSubTile(const mapservObj *msObj, const imageObj *img) {
 
  int width, height, mini, minj, maxi, maxj;
  int zoom = 2;
  imageObj* imgOut = NULL;
  tileParams params;
  rendererVTableObj *renderer;
  rasterBufferObj imgBuffer;
  
  if( !MS_RENDERER_PLUGIN(msObj->map->outputformat) 
		  || msObj->map->outputformat->renderer != img->format->renderer ||
		  ! MS_MAP_RENDERER(msObj->map)->supports_pixel_buffer ) {
	  msSetError(MS_MISCERR,"unsupported or mixed renderers","msTileExtractSubTile()");
	  return NULL;
  }
  renderer = MS_MAP_RENDERER(msObj->map);
  
  if (renderer->getRasterBufferHandle((imageObj*)img,&imgBuffer) != MS_SUCCESS) {
	  return NULL;
  }
  

  /*
  ** Load the metatiling information from the map file.
  */
  msTileGetParams(msObj->map, &params);

  /*
  ** Initialize values for the metatile clip area.
  */
  width = img->width - 2*params.map_edge_buffer;
  height = img->height - 2*params.map_edge_buffer;
  mini = params.map_edge_buffer;
  minj = params.map_edge_buffer;
  maxi = img->width - params.map_edge_buffer - 1;
  maxj = img->height - params.map_edge_buffer - 1;

  if( msObj->TileMode == TILE_GMAP ) {
    int x, y, zoom;
    
    if( msObj->TileCoords ) {
      if( msTileGetGMapCoords(msObj->TileCoords, &x, &y, &zoom) == MS_FAILURE )
        return NULL;
    } 
    else {
      msSetError(MS_WEBERR, "Tile parameter not set.", "msTileSetup()");
      return NULL;
    }    

    if(msObj->map->debug)
      msDebug("msTileExtractSubTile(): gmaps coords (x: %d, y: %d)\n",x,y);

    /*
    ** The bottom N bits of the coordinates give us the subtile
    ** location relative to the metatile.
    */
    x = (0xffff ^ (0xffff << params.metatile_level)) & x;
    y = (0xffff ^ (0xffff << params.metatile_level)) & y;

    if(msObj->map->debug)
      msDebug("msTileExtractSubTile(): gmaps image coords (x: %d, y: %d)\n",x,y);
    
    mini = mini + x * params.tile_size;
    minj = minj + y * params.tile_size;

  }
  else if( msObj->TileMode == TILE_VE ) {
    int tsize;
    int i = 0;
    char j = 0;
  
    if( strlen( msObj->TileCoords ) - params.metatile_level < 0 ) {
      return(NULL);
    }
  
    /* 
    ** Process the last elements of the VE coordinate string to place the
    ** requested tile in the context of the metatile
    */
    for( i = strlen( msObj->TileCoords ) - params.metatile_level; 
         i < strlen( msObj->TileCoords ); 
         i++ ) 
    {
      j = msObj->TileCoords[i];
      tsize = width / zoom;
      if( j == '1' || j == '3' ) mini += tsize;
      if( j == '2' || j == '3' ) minj += tsize;
      zoom *= 2;
    }
  }
  else {
    return(NULL); /* Huh? Should have a mode. */
  }
  
  imgOut = msImageCreate(params.tile_size, params.tile_size, msObj->map->outputformat, NULL, NULL, msObj->map->resolution, msObj->map->defresolution, NULL);
  
  if( imgOut == NULL ) {
    return NULL;
  }
  
  if(msObj->map->debug)
    msDebug("msTileExtractSubTile(): extracting (%d x %d) tile, top corner (%d, %d)\n",params.tile_size,params.tile_size,mini,minj);
  
  
  
  renderer->mergeRasterBuffer(imgOut,&imgBuffer,1.0,mini, minj,0, 0,params.tile_size, params.tile_size);

  return imgOut;
}
Exemplo n.º 12
0
/**
 * Generic function to render chart layers.
 */
int msDrawChartLayer(mapObj *map, layerObj *layer, imageObj *image)
{

    rectObj     searchrect;
    const char *chartTypeProcessingKey=msLayerGetProcessingKey( layer,"CHART_TYPE" );
    int chartType=MS_CHART_TYPE_PIE;
    int status = MS_FAILURE;

    if (image && map && layer)
    {
        if( !(MS_RENDERER_PLUGIN(image->format) )) {
            msSetError(MS_MISCERR, "chart drawing currently only supports GD and AGG renderers", "msDrawChartLayer()");
            return MS_FAILURE;
        }

        if( layer->numclasses < 2 ) {
            msSetError(MS_MISCERR,"chart drawing requires at least 2 classes in layer", "msDrawChartLayer()");
            return MS_FAILURE;
        }

        if(chartTypeProcessingKey!=NULL) {
            if( strcasecmp(chartTypeProcessingKey,"PIE") == 0 ) {
                chartType=MS_CHART_TYPE_PIE;
            }
            else if( strcasecmp(chartTypeProcessingKey,"BAR") == 0 ) {
                chartType=MS_CHART_TYPE_BAR;
            }
            else if( strcasecmp(chartTypeProcessingKey,"VBAR") == 0 ) {
                chartType=MS_CHART_TYPE_VBAR;
            }
            else {
                msSetError(MS_MISCERR,"unknown chart type for processing key \"CHART_TYPE\", must be one of \"PIE\" or \"BAR\"", "msDrawChartLayer()");
                return MS_FAILURE;
            }
        }
        if(chartType == MS_CHART_TYPE_PIE) {
            pieLayerProcessDynamicDiameter(layer);
        }

        /* open this layer */
        status = msLayerOpen(layer);
        if(status != MS_SUCCESS) return MS_FAILURE;

        status = msLayerWhichItems(layer, MS_FALSE, NULL);
        if(status != MS_SUCCESS) {
            msLayerClose(layer);
            return MS_FAILURE;
        }
        /* identify target shapes */
        if(layer->transform == MS_TRUE)
            searchrect = map->extent;
        else {
            searchrect.minx = searchrect.miny = 0;
            searchrect.maxx = map->width-1;
            searchrect.maxy = map->height-1;
        }

#ifdef USE_PROJ
        if((map->projection.numargs > 0) && (layer->projection.numargs > 0))
            msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */
#endif

        status = msLayerWhichShapes(layer, searchrect, MS_FALSE);
        if(status == MS_DONE) { /* no overlap */
            msLayerClose(layer);
            return MS_SUCCESS;
        } else if(status != MS_SUCCESS) {
            msLayerClose(layer);
            return MS_FAILURE;
        }
        switch(chartType) {
        case MS_CHART_TYPE_PIE:
            status = msDrawPieChartLayer(map, layer, image);
            break;
        case MS_CHART_TYPE_BAR:
            status = msDrawBarChartLayer(map, layer, image);
            break;
        case MS_CHART_TYPE_VBAR:
            status = msDrawVBarChartLayer(map, layer, image);
            break;
        default:
            return MS_FAILURE;/*shouldn't be here anyways*/
        }

        msLayerClose(layer);
    }
    return status;
}
Exemplo n.º 13
0
PHP_METHOD(imageObj, saveImage)
{
    zval *zobj = getThis();
    zval *zmap = NULL;
    char *filename = NULL;
    long filename_len = 0;
    php_image_object *php_image;
    php_map_object *php_map;
    int status = MS_SUCCESS;
    /* stdout specific vars */
    int size=0;
    void *iptr=NULL;

    PHP_MAPSCRIPT_ERROR_HANDLING(TRUE);
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO",
                              &filename, &filename_len,
                              &zmap, mapscript_ce_map) == FAILURE) {
        PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
        return;
    }
    PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);

    php_image = (php_image_object *) zend_object_store_get_object(zobj TSRMLS_CC);
    if (zmap)
        php_map = (php_map_object *) zend_object_store_get_object(zmap TSRMLS_CC);

    if(filename_len > 0)
    {
        if ((status = msSaveImage((zmap ? php_map->map:NULL), php_image->image, filename) != MS_SUCCESS))
        {
            mapscript_throw_mapserver_exception("Failed writing image to %s" TSRMLS_CC, filename);
            return;
        }

        RETURN_LONG(status);
    }

    /* no filename - read stdout */

    /* if there is no output buffer active, set the header */
    //handle changes in PHP 5.4.x
    #if PHP_VERSION_ID < 50399
      if (OG(ob_nesting_level)<=0)
      {
          php_header(TSRMLS_C);
      }
    #else
      if (php_output_get_level(TSRMLS_C)<=0)
      {
          php_header(TSRMLS_C);
      }
    #endif

    if (MS_RENDERER_PLUGIN(php_image->image->format))
    {
        iptr = (void *)msSaveImageBuffer(php_image->image, &size, php_image->image->format);
    }
    else if (php_image->image->format->name && (strcasecmp(php_image->image->format->name, "imagemap")==0))
    {
        iptr = php_image->image->img.imagemap;
        size = strlen(php_image->image->img.imagemap);
    }

    if (size == 0) {
        mapscript_throw_mapserver_exception("Failed writing image to stdout" TSRMLS_CC);
        return;
    }
    else
    {
        php_write(iptr, size TSRMLS_CC);
        status = MS_SUCCESS;
        /* status = size;  why should we return the size ?? */
        msFree(iptr);
    }

    RETURN_LONG(status);
}
Exemplo n.º 14
0
/* {{{ proto void pasteImage(imageObj Src, int transparentColor [[,int dstx, int dsty], int angle])
   Pastes another imageObj on top of this imageObj. transparentColor is
   the color (0xrrggbb) from srcImg that should be considered transparent.
   Pass transparentColor=-1 if you don't want any transparent color.
   If optional dstx,dsty are provided then they define the position where the
   image should be copied (dstx,dsty = top-left corner position).
   The optional angle is a value between 0 and 360 degrees to rotate the
   source image counterclockwise.  Note that if a rotation is requested then
   the dstx and dsty coordinates specify the CENTER of the destination area.
   NOTE : this function only works for 8 bits GD images.
*/
PHP_METHOD(imageObj, pasteImage)
{
    long transparent=-1, dstx=0, dsty=0, angle=0;
    int angleSet=MS_FALSE;
    zval *zimage;
    zval *zobj = getThis();
    php_image_object *php_image, *php_imageSrc;
    /*int oldTransparentColor, newTransparentColor=-1, r, g, b;*/
    rendererVTableObj *renderer = NULL;
    rasterBufferObj rb;

    PHP_MAPSCRIPT_ERROR_HANDLING(TRUE);
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol|lll",
                              &zimage, mapscript_ce_image, &transparent,
                              &dstx, &dsty, &angle) == FAILURE) {
        PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
        return;
    }
    PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);

    if  (ZEND_NUM_ARGS() == 3) {
        mapscript_report_php_error(E_WARNING, "dstX parameter given but not dstY" TSRMLS_CC);
    }
    else
        angleSet = MS_TRUE;

    php_image = (php_image_object *) zend_object_store_get_object(zobj TSRMLS_CC);
    php_imageSrc = (php_image_object *) zend_object_store_get_object(zimage TSRMLS_CC);

    if (!MS_RENDERER_PLUGIN(php_imageSrc->image->format) ||
 	!MS_RENDERER_PLUGIN(php_image->image->format))
        {
            mapscript_throw_exception("PasteImage function should only be used with renderer plugin drivers." TSRMLS_CC);
            return;
        }

#ifdef undef //USE_AGG
    if( MS_RENDERER_AGG(php_imageSrc->image->format))
      msAlphaAGG2GD(php_imageSrc->image);
    if( MS_RENDERER_AGG(php_image->image->format))
      msAlphaAGG2GD(php_image->image);
#endif


    renderer = MS_IMAGE_RENDERER(php_image->image);
    memset(&rb,0,sizeof(rasterBufferObj));

    renderer->getRasterBufferHandle(php_imageSrc->image, &rb);
    renderer->mergeRasterBuffer(php_image->image, &rb, 1.0, 0, 0, dstx, dsty, rb.width, rb.height);

    /* Look for r,g,b in color table and make it transparent.
     * will return -1 if there is no exact match which will result in
     * no transparent color in the call to gdImageColorTransparent().
     */
/*    if (transparent != -1)
    {
        r = (transparent / 0x010000) & 0xff;
        g = (transparent / 0x0100) & 0xff;
        b = transparent & 0xff;
        newTransparentColor = gdImageColorExact(php_imageSrc->image->img.gd, r, g, b);
    }

    oldTransparentColor = gdImageGetTransparent(php_imageSrc->image->img.gd);
    gdImageColorTransparent(php_imageSrc->image->img.gd, newTransparentColor);

    if (!angleSet)
        gdImageCopy(php_image->image->img.gd, php_imageSrc->image->img.gd, dstx, dsty,
                    0, 0, php_imageSrc->image->img.gd->sx, php_imageSrc->image->img.gd->sy);
    else
        gdImageCopyRotated(php_image->image->img.gd, php_imageSrc->image->img.gd, dstx, dsty,
                           0, 0, php_imageSrc->image->img.gd->sx, php_imageSrc->image->img.gd->sy,
                           angle);

                           gdImageColorTransparent(php_imageSrc->image->img.gd, oldTransparentColor);*/

    RETURN_LONG(MS_SUCCESS);

}