Пример #1
0
int KmlRenderer::checkProjection(mapObj *map)
{
    projectionObj *projection= &map->projection;
#ifdef USE_PROJ
    if (projection && projection->numargs > 0 && pj_is_latlong(projection->proj))
    {
        return MS_SUCCESS;
    }
    else
    {
        char epsg_string[100];
        rectObj sRect;
        projectionObj out;

        /* for layer the do not have any projection set, set them with the current map
           projection*/
        if (projection && projection->numargs > 0)
        {
            layerObj *lp = NULL;
            int i =0;
            char *pszMapProjectString = msGetProjectionString(projection);
            if (pszMapProjectString)
            {
                for(i=0; i<map->numlayers; i++)
                {
                    lp = GET_LAYER(map, i);
                    if (lp->projection.numargs == 0 && lp->transform == MS_TRUE)
                    {
                        msFreeProjection(&lp->projection);
                        msLoadProjectionString(&lp->projection, pszMapProjectString);
                    }
                }
                msFree(pszMapProjectString);
            }
        }
        strcpy(epsg_string, "epsg:4326" );
        msInitProjection(&out);
        msLoadProjectionString(&out, epsg_string);

        sRect = map->extent;
        msProjectRect(projection, &out, &sRect);
        msFreeProjection(projection);
        msLoadProjectionString(projection, epsg_string);

        /*change also units and extents*/
        map->extent = sRect;
        map->units = MS_DD;


        if (map->debug)
          msDebug("KmlRenderer::checkProjection: Mapfile projection set to epsg:4326\n");

        return MS_SUCCESS;
    }

#else
    msSetError(MS_MISCERR, "Projection support not enabled", "KmlRenderer::checkProjection" );
    return MS_FAILURE;
#endif
}
Пример #2
0
static int FTLParseEpsgString(char *pszEpsg, projectionObj *psProj)
{
    int nStatus = MS_FALSE;
    int nTokens = 0;
    char **tokens = NULL;
    int nEpsgTmp=0;

#ifdef USE_PROJ
    if (pszEpsg && psProj)
    {
        nTokens = 0;
        tokens = msStringSplit(pszEpsg,'#', &nTokens);
        if (tokens && nTokens == 2)
        {
            char szTmp[32];
            sprintf(szTmp, "init=epsg:%s",tokens[1]);
            msInitProjection(psProj);
            if (msLoadProjectionString(psProj, szTmp) == 0)
              nStatus = MS_TRUE;
        }
        else if (tokens &&  nTokens == 1)
        {
            if (tokens)
              msFreeCharArray(tokens, nTokens);
            nTokens = 0;

            tokens = msStringSplit(pszEpsg,':', &nTokens);
            nEpsgTmp = -1;
            if (tokens &&  nTokens == 1)
            {
                nEpsgTmp = atoi(tokens[0]);
                
            }
            else if (tokens &&  nTokens == 2)
            {
                nEpsgTmp = atoi(tokens[1]);
            }
            if (nEpsgTmp > 0)
            {
                char szTmp[32];
                sprintf(szTmp, "init=epsg:%d",nEpsgTmp);
                msInitProjection(psProj);
                if (msLoadProjectionString(psProj, szTmp) == 0)
                  nStatus = MS_TRUE;
            }
        }
        if (tokens)
          msFreeCharArray(tokens, nTokens);
    }
#endif
    return nStatus;
}
Пример #3
0
void MSMap::PropertySetter (Local<String> property, Local<Value> value, const AccessorInfo& info) {
  MSMap *map = ObjectWrap::Unwrap<MSMap>(info.Holder());
  v8::String::AsciiValue n(property);
  if (strcmp(*n, "width") == 0) {
    map->this_->width = value->Int32Value();
  } else if (strcmp(*n, "height") == 0) {
    map->this_->height = value->Int32Value();
  } else if (strcmp(*n, "maxsize") == 0) {
    map->this_->maxsize = value->Int32Value();
  } else if (strcmp(*n, "units") == 0) {
    int32_t units = value->Int32Value();
    if (units >= MS_INCHES && units <= MS_NAUTICALMILES) {
      map->this_->units = (MS_UNITS) units;
    }
  } else if (strcmp(*n, "resolution") == 0) {
    map->this_->resolution = value->NumberValue();
  } else if (strcmp(*n, "defresolution") == 0) {
    map->this_->defresolution = value->NumberValue();
  } else if (strcmp(*n, "name") == 0) {
    REPLACE_STRING(map->this_->name, value);
  } else if (strcmp(*n, "imagetype") == 0) {
    REPLACE_STRING(map->this_->imagetype, value);
  } else if (strcmp(*n, "shapepath") == 0) {
    REPLACE_STRING(map->this_->shapepath, value);
  } else if (strcmp(*n, "projection") == 0) {
    v8::String::AsciiValue _v_(value->ToString());
    msLoadProjectionString(&(map->this_->projection), *_v_);
  } else if (strcmp(*n, "mappath") == 0) {
    REPLACE_STRING(map->this_->mappath, value);
  }
}
Пример #4
0
xmlNodePtr msOWSCommonBoundingBox(xmlNsPtr psNsOws, const char *crs, int dimensions, double minx, double miny, double maxx, double maxy)
{
  char LowerCorner[100];
  char UpperCorner[100];
  char dim_string[100];
  xmlNodePtr psRootNode = NULL;

  /* Do we need to reorient tuple axes? */
  if(crs && strstr(crs, "imageCRS") == NULL) {
    projectionObj proj;

    msInitProjection( &proj );
    if( msLoadProjectionString( &proj, (char *) crs ) == 0 ) {
      msAxisNormalizePoints( &proj, 1, &minx, &miny );
      msAxisNormalizePoints( &proj, 1, &maxx, &maxy );
    }
    msFreeProjection( &proj );
  }


  if (_validateNamespace(psNsOws) == MS_FAILURE)
    psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX);

  /* create element name */
  psRootNode = xmlNewNode(psNsOws, BAD_CAST "BoundingBox");

  /* add attributes to the root element */
  xmlNewProp(psRootNode, BAD_CAST "crs", BAD_CAST crs);

  snprintf( dim_string, sizeof(dim_string), "%d", dimensions );
  xmlNewProp(psRootNode, BAD_CAST "dimensions", BAD_CAST dim_string);

  snprintf(LowerCorner, sizeof(LowerCorner), "%.15g %.15g", minx, miny);
  snprintf(UpperCorner, sizeof(UpperCorner), "%.15g %.15g", maxx, maxy);

  /* add child elements */
  xmlNewChild(psRootNode, psNsOws,BAD_CAST "LowerCorner",BAD_CAST LowerCorner);
  xmlNewChild(psRootNode, psNsOws,BAD_CAST "UpperCorner",BAD_CAST UpperCorner);

  return psRootNode;
}
Пример #5
0
int mapObj_setProjection(mapObj* self, char *string) {
    return(msLoadProjectionString(&(self->projection), string));
  }
Пример #6
0
char *FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, layerObj *lp)
{
  char *pszExpression = NULL;
  shapeObj *psQueryShape = NULL;
  double dfDistance = -1;
  int nUnit = -1, nLayerUnit = -1;
  char *pszWktText = NULL;
  char szBuffer[256];
  char *pszTmp=NULL;
  projectionObj sProjTmp;
  rectObj sQueryRect;
  shapeObj *psTmpShape=NULL;
  int bBBoxQuery = 0;
  int bAlreadyReprojected = 0;

  if (psNode == NULL || lp == NULL)
    return NULL;

  if (psNode->eType != FILTER_NODE_TYPE_SPATIAL)
    return NULL;

  /* get the shape */
  if (FLTIsBBoxFilter(psNode)) {
    char szPolygon[512];
    FLTGetBBOX(psNode, &sQueryRect);

    snprintf(szPolygon, sizeof(szPolygon),
             "POLYGON((%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f))",
             sQueryRect.minx, sQueryRect.miny,
             sQueryRect.minx, sQueryRect.maxy,
             sQueryRect.maxx, sQueryRect.maxy,
             sQueryRect.maxx, sQueryRect.miny,
             sQueryRect.minx, sQueryRect.miny);

    psTmpShape = msShapeFromWKT(szPolygon);

    /* 
    ** This is a horrible hack to deal with world-extent requests and
    ** reprojection. msProjectRect() detects if reprojection from longlat to 
    ** projected SRS, and in that case it transforms the bbox to -1e-15,-1e-15,1e15,1e15
    ** to ensure that all features are returned.
    **
    ** Make wfs_200_cite_filter_bbox_world.xml and wfs_200_cite_postgis_bbox_world.xml pass
    */
    if (fabs(sQueryRect.minx - -180.0) < 1e-5 &&
        fabs(sQueryRect.miny - -90.0) < 1e-5 &&
        fabs(sQueryRect.maxx - 180.0) < 1e-5 &&
        fabs(sQueryRect.maxy - 90.0) < 1e-5)
    {
      if (lp->projection.numargs > 0) {
        if (psNode->pszSRS)
          msInitProjection(&sProjTmp);
        if (psNode->pszSRS) {
          /* Use the non EPSG variant since axis swapping is done in FLTDoAxisSwappingIfNecessary */
          if (msLoadProjectionString(&sProjTmp, psNode->pszSRS) == 0) {
            msProjectRect(&sProjTmp, &lp->projection, &sQueryRect);
          }
        } else if (lp->map->projection.numargs > 0)
          msProjectRect(&lp->map->projection, &lp->projection, &sQueryRect);
        if (psNode->pszSRS)
          msFreeProjection(&sProjTmp);
      }
      if (sQueryRect.minx <= -1e14) {
        msFreeShape(psTmpShape);
        msFree(psTmpShape);
        psTmpShape = (shapeObj*) msSmallMalloc(sizeof(shapeObj));
        msInitShape(psTmpShape);
        msRectToPolygon(sQueryRect, psTmpShape);
        bAlreadyReprojected = 1;
      }
    }

    bBBoxQuery = 1;
  } else {
    /* other geos type operations */

    /* project shape to layer projection. If the proj is not part of the filter query,
      assume that the cooredinates are in the map projection */

    psQueryShape = FLTGetShape(psNode, &dfDistance, &nUnit);

    if ((strcasecmp(psNode->pszValue, "DWithin") == 0 || strcasecmp(psNode->pszValue, "Beyond") == 0 ) && dfDistance > 0) {
      nLayerUnit = lp->units;
      if(nLayerUnit == -1) nLayerUnit = GetMapserverUnitUsingProj(&lp->projection);
      if(nLayerUnit == -1) nLayerUnit = lp->map->units;
      if(nLayerUnit == -1) nLayerUnit = GetMapserverUnitUsingProj(&lp->map->projection);

      if (nUnit >= 0 && nUnit != nLayerUnit)
        dfDistance *= msInchesPerUnit(nUnit,0)/msInchesPerUnit(nLayerUnit,0); /* target is layer units */
    }

    psTmpShape = psQueryShape;
  }

  if (psTmpShape) {

    /*
    ** target is layer projection
    */
    if (!bAlreadyReprojected && lp->projection.numargs > 0) {
      if (psNode->pszSRS)
        msInitProjection(&sProjTmp);
      if (psNode->pszSRS) {
        /* Use the non EPSG variant since axis swapping is done in FLTDoAxisSwappingIfNecessary */
        if (msLoadProjectionString(&sProjTmp, psNode->pszSRS) == 0) {
          msProjectShape(&sProjTmp, &lp->projection, psTmpShape);
        }
      } else if (lp->map->projection.numargs > 0)
        msProjectShape(&lp->map->projection, &lp->projection, psTmpShape);
      if (psNode->pszSRS)
        msFreeProjection(&sProjTmp);
    }

    /* function name */
    if (bBBoxQuery) {
      sprintf(szBuffer, "%s", "intersects");
    } else {
      if (strncasecmp(psNode->pszValue, "intersect", 9) == 0)
        sprintf(szBuffer, "%s", "intersects");
      else {
        pszTmp = msStrdup(psNode->pszValue);
        msStringToLower(pszTmp);
        sprintf(szBuffer, "%s", pszTmp);
        msFree(pszTmp);
      }
    }
    pszExpression = msStringConcatenate(pszExpression, szBuffer);
    pszExpression = msStringConcatenate(pszExpression, "(");

    /* geometry binding */
    sprintf(szBuffer, "%s", "[shape]");
    pszExpression = msStringConcatenate(pszExpression, szBuffer);
    pszExpression = msStringConcatenate(pszExpression, ",");

    /* filter geometry */
    pszWktText = msGEOSShapeToWKT(psTmpShape);
    sprintf(szBuffer, "%s", "fromText('");
    pszExpression = msStringConcatenate(pszExpression, szBuffer);
    pszExpression = msStringConcatenate(pszExpression, pszWktText);
    sprintf(szBuffer, "%s", "')");
    pszExpression = msStringConcatenate(pszExpression, szBuffer);
    msGEOSFreeWKT(pszWktText);

    /* (optional) beyond/dwithin distance, always 0.0 since we apply the distance as a buffer earlier */
    if ((strcasecmp(psNode->pszValue, "DWithin") == 0 || strcasecmp(psNode->pszValue, "Beyond") == 0)) {
      // pszExpression = msStringConcatenate(pszExpression, ",0.0");
      sprintf(szBuffer, ",%g", dfDistance);
      pszExpression = msStringConcatenate(pszExpression, szBuffer);      
    }

    /* terminate the function */
    pszExpression = msStringConcatenate(pszExpression, ") = TRUE");
  }

  /*
  ** Cleanup
  */
  if (bBBoxQuery) {
    msFreeShape(psTmpShape);
    msFree(psTmpShape);
  }

  return pszExpression;
}
Пример #7
0
static wfsParamsObj *msBuildRequestParams(mapObj *map, layerObj *lp,
    rectObj *bbox_ret)
{
  wfsParamsObj *psParams = NULL;
  rectObj bbox;
  const char *pszTmp;
  int nLength, i = 0;
  char *pszVersion, *pszTypeName;

  if (!map || !lp || !bbox_ret)
    return NULL;

  if (lp->connection == NULL)
    return NULL;

  psParams = msWFSCreateParamsObj();
  pszTmp = msOWSLookupMetadata(&(lp->metadata), "FO", "version");
  if (pszTmp)
    psParams->pszVersion = msStrdup(pszTmp);
  else {
    pszTmp = strstr(lp->connection, "VERSION=");
    if (!pszTmp)
      pszTmp = strstr(lp->connection, "version=");
    if (pszTmp) {
      pszVersion = strchr(pszTmp, '=')+1;
      if (strncmp(pszVersion, "0.0.14", 6) == 0)
        psParams->pszVersion = msStrdup("0.0.14");
      else if (strncmp(pszVersion, "1.0.0", 5) == 0)
        psParams->pszVersion = msStrdup("1.0.0");
    }
  }

  /*the service is always set to WFS : see bug 1302 */
  psParams->pszService = msStrdup("WFS");

  /*
  pszTmp = msOWSLookupMetadata(&(lp->metadata), "FO", "service");
  if (pszTmp)
    psParams->pszService = msStrdup(pszTmp);
  else
  {
      pszTmp = strstr(lp->connection, "SERVICE=");
      if (!pszTmp)
        pszTmp = strstr(lp->connection, "service=");
      if (pszTmp)
      {
          pszService = strchr(pszTmp, '=')+1;
          if (strncmp(pszService, "WFS", 3) == 0)
            psParams->pszService = msStrdup("WFS");
      }
  }
  */

  pszTmp = msOWSLookupMetadata(&(lp->metadata), "FO", "geometryname");
  if (pszTmp)
    psParams->pszGeometryName = msStrdup(pszTmp);

  pszTmp = msOWSLookupMetadata(&(lp->metadata), "FO", "typename");
  if (pszTmp)
    psParams->pszTypeName = msStrdup(pszTmp);
  else {
    pszTmp = strstr(lp->connection, "TYPENAME=");
    if (!pszTmp)
      pszTmp = strstr(lp->connection, "typename=");
    if (pszTmp) {
      pszTypeName = strchr(pszTmp, '=')+1;
      if (pszTypeName) {
        nLength = strlen(pszTypeName);
        if (nLength > 0) {
          for (i=0; i<nLength; i++) {
            if (pszTypeName[i] == '&')
              break;
          }

          if (i<nLength) {
            char *pszTypeNameTmp = NULL;
            pszTypeNameTmp = msStrdup(pszTypeName);
            pszTypeNameTmp[i] = '\0';
            psParams->pszTypeName = msStrdup(pszTypeNameTmp);
            free(pszTypeNameTmp);
          } else
            psParams->pszTypeName = msStrdup(pszTypeName);
        }
      }
    }
  }

  pszTmp = msOWSLookupMetadata(&(lp->metadata), "FO", "filter");
  if (pszTmp && strlen(pszTmp) > 0) {
    if (strstr(pszTmp, "<Filter>") !=NULL || strstr(pszTmp, "<ogc:Filter") != NULL)
      psParams->pszFilter = msStrdup(pszTmp);
    else {
      psParams->pszFilter = msStringConcatenate(psParams->pszFilter, "<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">");
      psParams->pszFilter = msStringConcatenate(psParams->pszFilter, (char*)pszTmp);
      psParams->pszFilter = msStringConcatenate(psParams->pszFilter, "</ogc:Filter>");
    }
  }

  pszTmp = msOWSLookupMetadata(&(lp->metadata), "FO", "maxfeatures");
  if (pszTmp)
    psParams->nMaxFeatures = atoi(pszTmp);

  /* Request is always GetFeature; */
  psParams->pszRequest = msStrdup("GetFeature");


  /* ------------------------------------------------------------------
   * Figure the SRS we'll use for the request.
   * - Fetch the map SRS (if it's EPSG)
   * - Check if map SRS is listed in layer wfs_srs metadata
   * - If map SRS is valid for this layer then use it
   * - Otherwise request layer in its default SRS and we'll reproject later
   * ------------------------------------------------------------------ */

  /* __TODO__ WFS servers support only one SRS... need to decide how we'll */
  /* handle this and document it well. */
  /* It's likely that we'll simply reproject the BBOX to teh layer's projection. */

  /* ------------------------------------------------------------------
   * Set layer SRS and reproject map extents to the layer's SRS
   * ------------------------------------------------------------------ */
#ifdef __TODO__
  /* No need to set lp->proj if it's already set to the right EPSG code */
  if ((pszTmp = msGetEPSGProj(&(lp->projection), NULL, MS_TRUE)) == NULL ||
      strcasecmp(pszEPSG, pszTmp) != 0) {
    char szProj[20];
    snprintf(szProj, sizeof(szProj), "init=epsg:%s", pszEPSG+5);
    if (msLoadProjectionString(&(lp->projection), szProj) != 0)
      return NULL;
  }
#endif

  bbox = map->extent;
  if (msProjectionsDiffer(&(map->projection), &(lp->projection))) {
    msProjectRect(&(map->projection), &(lp->projection), &bbox);
  }

  if (bbox_ret != NULL)
    *bbox_ret = bbox;

  return psParams;

}
Пример #8
0
/************************************************************************
 *                            msTileSetup                               *
 *                                                                      * 
 *  Called from mapserv.c, this is where the fun begins                 *
 *  Set up projections and test the parameters for legality.            *
 ************************************************************************/
int msTileSetup(mapservObj* msObj) {
#ifdef USE_TILE_API 

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

  /* 
  ** Ensure all the LAYERs have a projection. 
  */  
  if( msTileSetProjections(msObj->map) != 0 ) {
    return(MS_FAILURE);
  }

  /* 
  ** Set the projection string for this mode. 
  */
  if( msObj->TileMode == TILE_GMAP || msObj->TileMode == TILE_VE ) {
    outProjStr = SPHEREMERC_PROJ4;
  } else {
    return MS_FAILURE; /* Huh? No mode? */
  }
  if( msLoadProjectionString(&(msObj->map->projection), outProjStr) != 0 ) {
    msSetError(MS_CGIERR, "Unable to load projection string.", "msTileSetup()");
    return MS_FAILURE;
  }
  
  /*
  ** Set up the output extents for this tilemode and tile coordinates 
  */
  if( msObj->TileMode == TILE_GMAP ) {

    int x, y, zoom;
    double zoomfactor;
    
    if( msObj->TileCoords ) {
      if( msTileGetGMapCoords(msObj->TileCoords, &x, &y, &zoom) == MS_FAILURE )
        return MS_FAILURE;
    } 
    else {
      msSetError(MS_WEBERR, "Tile parameter not set.", "msTileSetup()");
      return MS_FAILURE;
    }
    
    if( params.metatile_level >= zoom ) {
      msTileResetMetatileLevel(msObj->map);
    }
    
    zoomfactor = pow(2.0, (double)zoom);
    
    /*
    ** Check the input request for sanity.
    */
    if( x >= zoomfactor || y >= zoomfactor ) {
      msSetError(MS_CGIERR, "GMap tile coordinates are too large for supplied zoom.", "msTileSetup()");
      return(MS_FAILURE);
    }
    if( x < 0 || y < 0 ) {
      msSetError(MS_CGIERR, "GMap tile coordinates should not be less than zero.", "msTileSetup()");
      return(MS_FAILURE);
    }

  }
  else if ( msObj->TileMode == TILE_VE ) {
    
    if( strspn( msObj->TileCoords, "0123" ) < strlen( msObj->TileCoords ) ) {
      msSetError(MS_CGIERR, "VE tile name should only include characters 0, 1, 2 and 3.", "msTileSetup()");
      return(MS_FAILURE);
    }

    if( params.metatile_level >= strlen(msObj->TileCoords) ) {
      msTileResetMetatileLevel(msObj->map);
    }

  }
  else {
    return(MS_FAILURE); /* Huh? Should have a mode. */
  }
     
  return MS_SUCCESS;
#else
  msSetError(MS_CGIERR, "Tile API is not available.", "msTileSetup()");
  return(MS_FAILURE);
#endif
}
Пример #9
0
/**
 * \private \memberof mapcache_source_mapserver
 * \sa mapcache_source::render_map()
 */
void _mapcache_source_mapserver_render_map(mapcache_context *ctx, mapcache_map *map) {
   errorObj *errors = NULL;
  
   struct mc_mapobj *mcmap = _get_mapboj(ctx,map);
   GC_CHECK_ERROR(ctx);

   if(mcmap->grid_link != map->grid_link) {
      if (msLoadProjectionString(&(mcmap->map->projection), map->grid_link->grid->srs) != 0) {
         errors = msGetErrorObj();
         ctx->set_error(ctx,500, "Unable to set projection on mapObj. MapServer reports: %s", errors->message);
         _release_mapboj(ctx,map,mcmap);
         return;
      }
      switch(map->grid_link->grid->unit) {
         case MAPCACHE_UNIT_DEGREES:
            mcmap->map->units = MS_DD;
            break;
         case MAPCACHE_UNIT_FEET:
            mcmap->map->units = MS_FEET;
            break;
         case MAPCACHE_UNIT_METERS:
            mcmap->map->units = MS_METERS;
            break;
      }
      mcmap->grid_link = map->grid_link;
   }

  
  /*
  ** WMS extents are edge to edge while MapServer extents are center of
  ** pixel to center of pixel.  Here we try to adjust the WMS extents
  ** in by half a pixel.
  */
   double	dx, dy;
   dx = (map->extent[2] - map->extent[0]) / (map->width*2);
   dy = (map->extent[3] - map->extent[1]) / (map->height*2);

   mcmap->map->extent.minx = map->extent[0] + dx;
   mcmap->map->extent.miny = map->extent[1] + dy;
   mcmap->map->extent.maxx = map->extent[2] - dx;
   mcmap->map->extent.maxy = map->extent[3] - dy;
   msMapSetSize(mcmap->map, map->width, map->height);

   imageObj *image = msDrawMap(mcmap->map, MS_FALSE);
   if(!image) {
      errors = msGetErrorObj();
      ctx->set_error(ctx,500, "MapServer failed to create image. MapServer reports: %s", errors->message);
      _release_mapboj(ctx,map,mcmap);
      return;
   }
   rasterBufferObj rb;
   
   if(image->format->vtable->supports_pixel_buffer) {
      image->format->vtable->getRasterBufferHandle(image,&rb);
   } else {
      ctx->set_error(ctx,500,"format %s has no pixel export",image->format->name);
      _release_mapboj(ctx,map,mcmap);
      return;
   }

   map->raw_image = mapcache_image_create(ctx);
   map->raw_image->w = map->width;
   map->raw_image->h = map->height;
   map->raw_image->stride = 4 * map->width;
   map->raw_image->data = malloc(map->width*map->height*4);
   memcpy(map->raw_image->data,rb.data.rgba.pixels,map->width*map->height*4);
   apr_pool_cleanup_register(ctx->pool, map->raw_image->data,(void*)free, apr_pool_cleanup_null);
   msFreeImage(image);
   _release_mapboj(ctx,map,mcmap);
    
}