Пример #1
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;
}
Пример #2
0
void msFreeMap(mapObj *map)
{
  int i;

  if(!map) return;

  /* printf("msFreeMap(): maybe freeing map at %p count=%d.\n",map, map->refcount); */
  if(MS_REFCNT_DECR_IS_NOT_ZERO(map)) {
    return;
  }
  if(map->debug >= MS_DEBUGLEVEL_VV)
    msDebug("msFreeMap(): freeing map at %p.\n",map);

  msCloseConnections(map);

  msFree(map->name);
  msFree(map->shapepath);
  msFree(map->mappath);

  msFreeProjection(&(map->projection));
  msFreeProjection(&(map->latlon));

  msFreeLabelCache(&(map->labelcache));

  msFree(map->imagetype);

  msFreeFontSet(&(map->fontset));

  msFreeSymbolSet(&map->symbolset); /* free symbols */
  msFree(map->symbolset.filename);

  freeWeb(&(map->web));

  freeScalebar(&(map->scalebar));
  freeReferenceMap(&(map->reference));
  freeLegend(&(map->legend));

  for(i=0; i<map->maxlayers; i++) {
    if(GET_LAYER(map, i) != NULL) {
      GET_LAYER(map, i)->map = NULL;
      if(freeLayer((GET_LAYER(map, i))) == MS_SUCCESS)
        free(GET_LAYER(map, i));
    }
  }
  msFree(map->layers);

  if(map->layerorder)
    free(map->layerorder);

  msFree(map->templatepattern);
  msFree(map->datapattern);
  msFreeHashItems(&(map->configoptions));
  if(map->outputformat && map->outputformat->refcount > 0 && --map->outputformat->refcount < 1)
    msFreeOutputFormat(map->outputformat);

  for(i=0; i<map->numoutputformats; i++ ) {
    if(map->outputformatlist[i]->refcount > 0 && --map->outputformatlist[i]->refcount < 1)
      msFreeOutputFormat(map->outputformatlist[i]);
  }
  if(map->outputformatlist != NULL)
    msFree(map->outputformatlist);

  msFreeQuery(&(map->query));

#ifdef USE_V8_MAPSCRIPT
  if (map->v8context)
    msV8FreeContext(map);
#endif

  msFree(map);
}
Пример #3
0
int KmlRenderer::startNewLayer(imageObj *img, layerObj *layer)
{
  char *layerName=NULL;
  const char *value=NULL;

  LayerNode = xmlNewNode(NULL, BAD_CAST "Folder");

  layerName = getLayerName(layer);
  xmlNewChild(LayerNode, NULL, BAD_CAST "name", BAD_CAST layerName);
  msFree(layerName);

  const char *layerVisibility = layer->status != MS_OFF ? "1" : "0";
  xmlNewChild(LayerNode, NULL, BAD_CAST "visibility", BAD_CAST layerVisibility);

  const char *layerDsiplayFolder = msLookupHashTable(&(layer->metadata), "kml_folder_display");
  if (layerDsiplayFolder == NULL)
    layerDsiplayFolder = msLookupHashTable(&(layer->map->web.metadata), "kml_folder_display");
  if (!layerDsiplayFolder || strlen(layerDsiplayFolder)<=0) {
    xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_check");
  }

  else {
    if (strcasecmp(layerDsiplayFolder, "checkHideChildren") == 0)
      xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_checkHideChildren");
    else if (strcasecmp(layerDsiplayFolder, "checkOffOnly") == 0)
      xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_checkOffOnly");
    else if (strcasecmp(layerDsiplayFolder, "radioFolder") == 0)
      xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_radioFolder");
    else
      xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_check");
  }


  /*Init few things on the first layer*/
  if (FirstLayer) {
    FirstLayer = MS_FALSE;
    map = layer->map;

    if (layer->map->mappath)
      snprintf(MapPath, sizeof(MapPath), "%s", layer->map->mappath);

    /*First rendered layer - check mapfile projection*/
    checkProjection(layer->map);

    /*check for image path and image url*/
    if (layer->map->debug && (layer->map->web.imageurl == NULL ||   layer->map->web.imagepath == NULL))
      msDebug("KmlRenderer::startNewLayer: imagepath and imageurl should be set in the web object\n");


    /*map rect for ground overlay*/
    MapExtent = layer->map->extent;
    MapCellsize = layer->map->cellsize;
    BgColor = layer->map->imagecolor;

    xmlNewChild(DocNode, NULL, BAD_CAST "name", BAD_CAST layer->map->name);
    aggFormat = msSelectOutputFormat( layer->map, "png24");
    aggFormat->transparent = MS_TRUE;

  }

  currentLayer = layer;

  if (!msLayerIsOpen(layer)) {
    if (msLayerOpen(layer) != MS_SUCCESS) {
      msSetError(MS_MISCERR, "msLayerOpen failed", "KmlRenderer::startNewLayer" );
      return MS_FAILURE;
    }
  }

  /*pre process the layer to set things that make sense for kml output*/
  if (img)
    processLayer(layer, img->format);
  else
    processLayer(layer, NULL);

  if (msLookupHashTable(&layer->metadata, "kml_description"))
    pszLayerDescMetadata = msLookupHashTable(&layer->metadata, "kml_description");
  else if (msLookupHashTable(&layer->metadata, "ows_description"))
    pszLayerDescMetadata = msLookupHashTable(&layer->metadata, "ows_description");

  value=msLookupHashTable(&layer->metadata, "kml_include_items");
  if (!value)
    value=msLookupHashTable(&layer->metadata, "ows_include_items");
  if (value)
    papszLayerIncludeItems = msStringSplit(value, ',', &nIncludeItems);

  value=msLookupHashTable(&layer->metadata, "kml_exclude_items");
  if (!value)
    value=msLookupHashTable(&layer->metadata, "ows_exclude_items");
  if (value)
    papszLayerExcludeItems = msStringSplit(value, ',', &nExcludeItems);


  if (msLookupHashTable(&layer->metadata, "kml_name_item"))
    pszLayerNameAttributeMetadata = msLookupHashTable(&layer->metadata, "kml_name_item");

  /*get all attributes*/
  if(msLayerWhichItems(layer, MS_TRUE, NULL) != MS_SUCCESS) {
    return MS_FAILURE;
  }


  NumItems = layer->numitems;
  if (NumItems) {
    Items = (char **)msSmallCalloc(NumItems, sizeof(char *));
    for (int i=0; i<NumItems; i++)
      Items[i] = msStrdup(layer->items[i]);
  }


  const char* elevationAttribute = msLookupHashTable(&layer->metadata, "kml_elevation_attribute");
  if( elevationAttribute ) {
    mElevationFromAttribute = true;
    for( int i = 0; i < layer->numitems; ++i ) {
      if( strcasecmp( layer->items[i], elevationAttribute ) == 0 ) {
        mElevationAttributeIndex = i;
      }
    }
  }

  setupRenderingParams(&layer->metadata);
  return MS_SUCCESS;
}
Пример #4
0
/* rebuild the clusters according to the current extent */
int RebuildClusters(layerObj *layer, int isQuery)
{
  mapObj* map;
  layerObj* srcLayer;
  double distance, maxDistanceX, maxDistanceY, cellSizeX, cellSizeY;
  rectObj searchrect;
  int status;
  clusterInfo* current;
  int depth;
#ifdef USE_CLUSTER_EXTERNAL
  int layerIndex;
#endif

  msClusterLayerInfo* layerinfo = layer->layerinfo;

  if (!layerinfo) {
    msSetError(MS_MISCERR, "Layer is not open: %s", "RebuildClusters()", layer->name);
    return MS_FAILURE;
  }

  if (!layer->map) {
    msSetError(MS_MISCERR, "No map associated with this layer: %s", "RebuildClusters()", layer->name);
    return MS_FAILURE;
  }

  if (layer->debug >= MS_DEBUGLEVEL_VVV)
    msDebug("Clustering started.\n");

  map = layer->map;

  layerinfo->current = layerinfo->finalized; /* restart */

  /* check whether all shapes should be returned from a query */
  if(msLayerGetProcessingKey(layer, "CLUSTER_GET_ALL_SHAPES") != NULL)
    layerinfo->get_all_shapes = MS_TRUE;
  else
    layerinfo->get_all_shapes = MS_FALSE;

  /* check whether the location of the shapes should be preserved (no averaging) */
  if(msLayerGetProcessingKey(layer, "CLUSTER_KEEP_LOCATIONS") != NULL)
    layerinfo->keep_locations = MS_TRUE;
  else
    layerinfo->keep_locations = MS_FALSE;

  /* check whether the maxdistance and the buffer parameters 
  are specified in map units (scale independent clustering) */
  if(msLayerGetProcessingKey(layer, "CLUSTER_USE_MAP_UNITS") != NULL)
    layerinfo->use_map_units = MS_TRUE;
  else
    layerinfo->use_map_units = MS_FALSE;

  /* identify the current extent */
  if(layer->transform == MS_TRUE)
    searchrect = map->extent;
  else {
    searchrect.minx = searchrect.miny = 0;
    searchrect.maxx = map->width-1;
    searchrect.maxy = map->height-1;
  }

  if (searchrect.minx == layerinfo->searchRect.minx &&
      searchrect.miny == layerinfo->searchRect.miny &&
      searchrect.maxx == layerinfo->searchRect.maxx &&
      searchrect.maxy == layerinfo->searchRect.maxy) {
    /* already built */
    return MS_SUCCESS;
  }

  /* destroy previous data*/
  clusterDestroyData(layerinfo);

  layerinfo->searchRect = searchrect;

  /* reproject the rectangle to layer coordinates */
#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

  /* determine the compare method */
  layerinfo->fnCompare = CompareRectangleRegion;
  if (layer->cluster.region) {
    if (EQUAL(layer->cluster.region, "ellipse"))
      layerinfo->fnCompare = CompareEllipseRegion;
  }

  /* trying to find a reasonable quadtree depth */
  depth = 0;
  distance = layer->cluster.maxdistance;
  if (layerinfo->use_map_units == MS_TRUE) {
    while ((distance < (searchrect.maxx - searchrect.minx) || distance < (searchrect.maxy - searchrect.miny)) && depth <= TREE_MAX_DEPTH) {
      distance *= 2;
      ++depth;
    }
    cellSizeX = 1;
    cellSizeY = 1;
  }
  else {
    while ((distance < map->width || distance < map->height) && depth <= TREE_MAX_DEPTH) {
      distance *= 2;
      ++depth;
    }
    cellSizeX = MS_CELLSIZE(searchrect.minx, searchrect.maxx, map->width);
    cellSizeY = MS_CELLSIZE(searchrect.miny, searchrect.maxy, map->height);
  }

  layerinfo->depth = depth;

  maxDistanceX = layer->cluster.maxdistance * cellSizeX;
  maxDistanceY = layer->cluster.maxdistance * cellSizeY;

  /* increase the search rectangle so that the neighbouring shapes are also retrieved */
  searchrect.minx -= layer->cluster.buffer * cellSizeX;
  searchrect.maxx += layer->cluster.buffer * cellSizeX;
  searchrect.miny -= layer->cluster.buffer * cellSizeY;
  searchrect.maxy += layer->cluster.buffer * cellSizeY;

  /* create the root node */
  if (layerinfo->root)
    clusterTreeNodeDestroy(layerinfo, layerinfo->root);
  layerinfo->root = clusterTreeNodeCreate(layerinfo, searchrect);

  srcLayer = &layerinfo->srcLayer;

  /* start retrieving the shapes */
  status = msLayerWhichShapes(srcLayer, searchrect, isQuery);
  if(status == MS_DONE) {
    /* no overlap */
    return MS_SUCCESS;
  } else if(status != MS_SUCCESS) {
    return MS_FAILURE;
  }

  /* step through the source shapes and populate the quadtree with the tentative clusters */
  if ((current = clusterInfoCreate(layerinfo)) == NULL)
    return MS_FAILURE;

  while((status = msLayerNextShape(srcLayer, &current->shape)) == MS_SUCCESS) {
#if defined(USE_PROJ) && defined(USE_CLUSTER_EXTERNAL)
    /* transform the shape to the projection of this layer */
    if(srcLayer->transform == MS_TRUE && srcLayer->project && layer->transform == MS_TRUE && layer->project &&msProjectionsDiffer(&(srcLayer->projection), &(layer->projection)))
      msProjectShape(&srcLayer->projection, &layer->projection, &current->shape);
#endif
    /* set up positions and variance */
    current->avgx = current->x = current->shape.bounds.minx;
    current->avgy = current->y = current->shape.bounds.miny;
    current->varx = current->vary = 0;
    /* set up the area of interest when searching for the neighboring shapes */
    current->bounds.minx = current->x - maxDistanceX;
    current->bounds.miny = current->y - maxDistanceY;
    current->bounds.maxx = current->x + maxDistanceX;
    current->bounds.maxy = current->y + maxDistanceY;

    /* if the shape doesn't overlap we must skip it to avoid further issues */
    if(!msRectOverlap(&searchrect, &current->bounds)) {
      msFreeShape(&current->shape);
      msInitShape(&current->shape);

      msDebug("Skipping an invalid shape falling outside of the given extent\n");
      continue;
    }

    /* construct the item array */
    if (layer->iteminfo)
      BuildFeatureAttributes(layer, layerinfo, &current->shape);

    /* evaluate the group expression */
    if (layer->cluster.group.string)
      current->group = msClusterGetGroupText(&layer->cluster.group, &current->shape);

    /*start a query for the related shapes */
    findRelatedShapes(layerinfo, layerinfo->root, current);

    /* add this shape to the tree */
    if (treeNodeAddShape(layerinfo, layerinfo->root, current, depth) != MS_SUCCESS) {
      clusterInfoDestroyList(layerinfo, current);
      return MS_FAILURE;
    }

    if ((current = clusterInfoCreate(layerinfo)) == NULL) {
      clusterInfoDestroyList(layerinfo, current);
      return MS_FAILURE;
    }
  }

  clusterInfoDestroyList(layerinfo, current);

  while (layerinfo->root) {
#ifdef TESTCOUNT
    int n;
    double avgx, avgy;
#endif

    /* pick up the best cluster from the tree and do the finalization */
    /* the initial rank must be big enough */
    layerinfo->rank = (searchrect.maxx - searchrect.minx) * (searchrect.maxx - searchrect.minx) +
                      (searchrect.maxy - searchrect.miny) * (searchrect.maxy - searchrect.miny) + 1;

    layerinfo->current = NULL;
    findBestCluster(layer, layerinfo, layerinfo->root);

    if (layerinfo->current == NULL) {
      if (layer->debug >= MS_DEBUGLEVEL_VVV)
        msDebug("Clustering terminated.\n");
      break; /* completed */
    }

    /* Update the feature count of the shape */
    InitShapeAttributes(layer, layerinfo->current);

    /* collecting the shapes of the cluster */
    collectClusterShapes(layerinfo, layerinfo->root, layerinfo->current);

    if (layer->debug >= MS_DEBUGLEVEL_VVV) {
      msDebug("processing cluster %p: rank=%lf fcount=%d ncoll=%d nfin=%d nfins=%d nflt=%d bounds={%lf %lf %lf %lf}\n", layerinfo->current, layerinfo->rank, layerinfo->current->numsiblings + 1,
              layerinfo->current->numcollected, layerinfo->numFinalized, layerinfo->numFinalizedSiblings,
              layerinfo->numFiltered, layerinfo->current->bounds.minx, layerinfo->current->bounds.miny,
              layerinfo->current->bounds.maxx, layerinfo->current->bounds.maxy);
      if (layerinfo->current->node) {
        char pszBuffer[TREE_MAX_DEPTH + 1];
        clusterTreeNode* node = layerinfo->current->node;
        int position = node->position;
        int i = 1;
        while (position > 0 && i <= TREE_MAX_DEPTH) {
          pszBuffer[TREE_MAX_DEPTH - i] = '0' + (position % 4);
          position = position >> 2;
          ++i;
        }
        pszBuffer[TREE_MAX_DEPTH] = 0;

        msDebug(" ->node %p: count=%d index=%d pos=%s subn={%p %p %p %p} rect={%lf %lf %lf %lf}\n",
                node, node->numshapes, node->index, pszBuffer + TREE_MAX_DEPTH - i + 1,
                node->subnode[0], node->subnode[1], node->subnode[2], node->subnode[3],
                node->rect.minx, node->rect.miny, node->rect.maxx, node->rect.maxy);
      }
    }
Пример #5
0
SHPTreeHandle msSHPDiskTreeOpen(const TCHAR* pszTree, int debug)
{
    TCHAR *pszFullname, *pszBasename;
    SHPTreeHandle	psTree;

    char		pabyBuf[16];
    int			i;
    char		bBigEndian;

    /* -------------------------------------------------------------------- */
    /*	Establish the byte order on this machine.			    */
    /* -------------------------------------------------------------------- */
    i = 1;
    if( *((uchar *) &i) == 1 )
        bBigEndian = MS_FALSE;
    else
        bBigEndian = MS_TRUE;

    /* -------------------------------------------------------------------- */
    /*	Initialize the info structure.					    */
    /* -------------------------------------------------------------------- */
    psTree = (SHPTreeHandle) malloc(sizeof(SHPTreeInfo));

    /* -------------------------------------------------------------------- */
    /*	Compute the base (layer) name.  If there is any extension	    */
    /*	on the passed in filename we will strip it off.			    */
    /* -------------------------------------------------------------------- */
    pszBasename = (TCHAR *) malloc((_tcslen(pszTree)+5) * sizeof(TCHAR) * 2);
    _tcscpy( pszBasename, pszTree );
    for( i = _tcslen(pszBasename)-1;
            i > 0 && pszBasename[i] != _T('.') && pszBasename[i] != _T('/') && pszBasename[i] != _T('\\');
            i-- ) {}

    if( pszBasename[i] == _T('.') )
        pszBasename[i] = _T('\0');

    /* -------------------------------------------------------------------- */
    /*	Open the .shp and .shx files.  Note that files pulled from	    */
    /*	a PC to Unix with upper case filenames won't work!		    */
    /* -------------------------------------------------------------------- */
    pszFullname = (TCHAR *) malloc((_tcslen(pszBasename) + _tcslen(_T(MS_INDEX_EXTENSION)) + 1) * sizeof(TCHAR) * 2);
    _stprintf( pszFullname, _T("%s%s"), pszBasename, _T(MS_INDEX_EXTENSION));

    if (FileExists(pszFullname))  // prevent codegurad warnings (open unexisting file for reading)
        psTree->zfp = openzip(pszFullname, "rb" );
    else
        psTree->zfp = NULL;


    msFree(pszBasename); // don't need these any more
    msFree(pszFullname);

    if( psTree->zfp == NULL ) {
        msFree(psTree);
        return( NULL );
    }

    zzip_fread( pabyBuf, 8, 1, psTree->zfp );

    memcpy( &psTree->signature, pabyBuf, 3 );
    if( strncmp(psTree->signature,"SQT",3) )
    {
        /* ---------------------------------------------------------------------- */
        /*     must check if the 2 first bytes equal 0 of max depth that cannot   */
        /*     be more than 65535. If yes, we must swap all value. The problem    */
        /*     here is if there's no Depth (bytea 5,6,7,8 in the file) all bytes  */
        /*     will be set to 0. So,we will test with the number of shapes (bytes */
        /*     1,2,3,4) that cannot be more than 65535 too.                       */
        /* ---------------------------------------------------------------------- */
#if MAPSHAPEERROR
        if (debug)
        {
            msDebug("WARNING in msSHPDiskTreeOpen(): %ls is in old index format "
                    "which has been deprecated.  It is strongly recommended to "
                    "regenerate it in new format.\n", pszTree);
        }
#endif
        if((pabyBuf[4] == 0 && pabyBuf[5] == 0 &&
                pabyBuf[6] == 0 && pabyBuf[7] == 0))
        {
            psTree->LSB_order = !(pabyBuf[0] == 0 && pabyBuf[1] == 0);
        }
        else
        {
            psTree->LSB_order = !(pabyBuf[4] == 0 && pabyBuf[5] == 0);
        }
        psTree->needswap = ((psTree->LSB_order) != (!bBigEndian));

        /* ---------------------------------------------------------------------- */
        /*     poor hack to see if this quadtree was created by a computer with a */
        /*     different Endian                                                   */
        /* ---------------------------------------------------------------------- */
        psTree->version = 0;
    }
    else
    {
        psTree->needswap = (( pabyBuf[3] == MS_NEW_MSB_ORDER ) ^ ( bBigEndian ));

        psTree->LSB_order = ( pabyBuf[3] == MS_NEW_LSB_ORDER );
        memcpy( &psTree->version, pabyBuf+4, 1 );
        memcpy( &psTree->flags, pabyBuf+5, 3 );

        zzip_fread( pabyBuf, 8, 1, psTree->zfp );
    }

    if( psTree->needswap ) SwapWord( 4, pabyBuf );
    memcpy( &psTree->nShapes, pabyBuf, 4 );

    if( psTree->needswap ) SwapWord( 4, pabyBuf+4 );
    memcpy( &psTree->nDepth, pabyBuf+4, 4 );

    return( psTree );
}
Пример #6
0
static int
msProjectRectAsPolygon(projectionObj *in, projectionObj *out,
                       rectObj *rect)
{
#ifdef USE_PROJ
  shapeObj polygonObj;
  lineObj  ring;
  /*  pointObj ringPoints[NUMBER_OF_SAMPLE_POINTS*4+4]; */
  pointObj *ringPoints;
  int     ix, iy;

  double dx, dy;

  /* If projecting from longlat to projected */
  if( out && !pj_is_latlong(out->proj) && in && pj_is_latlong(in->proj) &&
      fabs(rect->minx - -180.0) < 1e-5 && fabs(rect->miny - -90.0) < 1e-5 &&
      fabs(rect->maxx - 180.0) < 1e-5 && fabs(rect->maxy - 90.0) < 1e-5) {
    rect->minx = -1e15;
    rect->miny = -1e15;
    rect->maxx = 1e15;
    rect->maxy = 1e15;
    return MS_SUCCESS;
  }

  /* -------------------------------------------------------------------- */
  /*      Build polygon as steps around the source rectangle.             */
  /* -------------------------------------------------------------------- */
  dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS;
  dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS;

  if(dx==0 && dy==0) {
    pointObj foo;
    msDebug( "msProjectRect(): Warning: degenerate rect {%f,%f,%f,%f}\n",rect->minx,rect->miny,rect->minx,rect->miny );
    foo.x = rect->minx;
    foo.y = rect->miny;
    msProjectPoint(in,out,&foo);
    rect->minx=rect->maxx=foo.x;
    rect->miny=rect->maxy=foo.y;
    return MS_SUCCESS;
  }
  
  ringPoints = (pointObj*) calloc(sizeof(pointObj),NUMBER_OF_SAMPLE_POINTS*4+4);
  ring.point = ringPoints;
  ring.numpoints = 0;

  msInitShape( &polygonObj );
  polygonObj.type = MS_SHAPE_POLYGON;

  /* sample along top */
  if(dx != 0) {
    for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ ) {
      ringPoints[ring.numpoints].x = rect->minx + ix * dx;
      ringPoints[ring.numpoints++].y = rect->miny;
    }
  }

  /* sample on along right side */
  if(dy != 0) {
    for(iy = 1; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ ) {
      ringPoints[ring.numpoints].x = rect->maxx;
      ringPoints[ring.numpoints++].y = rect->miny + iy * dy;
    }
  }

  /* sample along bottom */
  if(dx != 0) {
    for(ix = NUMBER_OF_SAMPLE_POINTS-1; ix >= 0; ix-- ) {
      ringPoints[ring.numpoints].x = rect->minx + ix * dx;
      ringPoints[ring.numpoints++].y = rect->maxy;
    }
  }

  /* sample on along left side */
  if(dy != 0) {
    for(iy = NUMBER_OF_SAMPLE_POINTS-1; iy >= 0; iy-- ) {
      ringPoints[ring.numpoints].x = rect->minx;
      ringPoints[ring.numpoints++].y = rect->miny + iy * dy;
    }
  }

  msAddLineDirectly( &polygonObj, &ring );

  /* -------------------------------------------------------------------- */
  /*      Attempt to reproject.                                           */
  /* -------------------------------------------------------------------- */
  msProjectShapeLine( in, out, &polygonObj, 0 );

  /* If no points reprojected, try a grid sampling */
  if( polygonObj.numlines == 0 || polygonObj.line[0].numpoints == 0 ) {
    msFreeShape( &polygonObj );
    return msProjectRectGrid( in, out, rect );
  }

  /* -------------------------------------------------------------------- */
  /*      Collect bounds.                                                 */
  /* -------------------------------------------------------------------- */
  rect->minx = rect->maxx = polygonObj.line[0].point[0].x;
  rect->miny = rect->maxy = polygonObj.line[0].point[0].y;

  for( ix = 1; ix < polygonObj.line[0].numpoints; ix++ ) {
    pointObj  *pnt = polygonObj.line[0].point + ix;

    rect->minx = MS_MIN(rect->minx,pnt->x);
    rect->maxx = MS_MAX(rect->maxx,pnt->x);
    rect->miny = MS_MIN(rect->miny,pnt->y);
    rect->maxy = MS_MAX(rect->maxy,pnt->y);
  }

  msFreeShape( &polygonObj );

  /* -------------------------------------------------------------------- */
  /*      Special case to handle reprojection from "more than the         */
  /*      whole world" projected coordinates that sometimes produce a     */
  /*      region greater than 360 degrees wide due to various wrapping    */
  /*      logic.                                                          */
  /* -------------------------------------------------------------------- */
  if( out && pj_is_latlong(out->proj) && in && !pj_is_latlong(in->proj)
      && rect->maxx - rect->minx > 360.0 ) {
    rect->maxx = 180;
    rect->minx = -180;
  }

  return MS_SUCCESS;
#else
  msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()");
  return(MS_FAILURE);
#endif
}
Пример #7
0
int main(int argc, char *argv[])
{
  int iArg;
  int sendheaders = MS_TRUE;
  struct mstimeval execstarttime, execendtime;
  struct mstimeval requeststarttime, requestendtime;
  mapservObj* mapserv = NULL;

  /* -------------------------------------------------------------------- */
  /*      Initialize mapserver.  This sets up threads, GD and GEOS as     */
  /*      well as using MS_ERRORFILE and MS_DEBUGLEVEL env vars if set.   */
  /* -------------------------------------------------------------------- */
  if( msSetup() != MS_SUCCESS ) {
    msCGIWriteError(mapserv);
    msCleanup(0);
    exit(0);
  }

  if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING)
    msGettimeofday(&execstarttime, NULL);

  /* -------------------------------------------------------------------- */
  /*      Process arguments.  In normal use as a cgi-bin there are no     */
  /*      commandline switches, but we provide a few for test/debug       */
  /*      purposes, and to query the version info.                        */
  /* -------------------------------------------------------------------- */
  for( iArg = 1; iArg < argc; iArg++ ) {
    /* Keep only "-v", "-nh" and "QUERY_STRING=..." enabled by default.
     * The others will require an explicit -DMS_ENABLE_CGI_CL_DEBUG_ARGS
     * at compile time.
     */
    if( strcmp(argv[iArg],"-v") == 0 ) {
      printf("%s\n", msGetVersion());
      fflush(stdout);
      exit(0);
    } else if(strcmp(argv[iArg], "-nh") == 0) {
      sendheaders = MS_FALSE;
    } else if( strncmp(argv[iArg], "QUERY_STRING=", 13) == 0 ) {
      /* Debugging hook... pass "QUERY_STRING=..." on the command-line */
      putenv( "REQUEST_METHOD=GET" );
      putenv( argv[iArg] );
    }
#ifdef MS_ENABLE_CGI_CL_DEBUG_ARGS
    else if( iArg < argc-1 && strcmp(argv[iArg], "-tmpbase") == 0) {
      msForceTmpFileBase( argv[++iArg] );
    } else if( iArg < argc-1 && strcmp(argv[iArg], "-t") == 0) {
      char **tokens;
      int numtokens=0;

      if((tokens=msTokenizeMap(argv[iArg+1], &numtokens)) != NULL) {
        int i;
        for(i=0; i<numtokens; i++)
          printf("%s\n", tokens[i]);
        msFreeCharArray(tokens, numtokens);
      } else {
        msCGIWriteError(mapserv);
      }

      exit(0);
    } else if( strncmp(argv[iArg], "MS_ERRORFILE=", 13) == 0 ) {
      msSetErrorFile( argv[iArg] + 13, NULL );
    } else if( strncmp(argv[iArg], "MS_DEBUGLEVEL=", 14) == 0) {
      msSetGlobalDebugLevel( atoi(argv[iArg] + 14) );
    }
#endif /* MS_ENABLE_CGI_CL_DEBUG_ARGS */
    else {
      /* we don't produce a usage message as some web servers pass junk arguments */
    }
  }

  /* -------------------------------------------------------------------- */
  /*      Setup cleanup magic, mainly for FastCGI case.                   */
  /* -------------------------------------------------------------------- */
#ifndef WIN32
  signal( SIGUSR1, msCleanupOnSignal );
  signal( SIGTERM, msCleanupOnSignal );
#endif

#ifdef USE_FASTCGI
  msIO_installFastCGIRedirect();

#ifdef WIN32
  atexit( msCleanupOnExit );
#endif

  /* In FastCGI case we loop accepting multiple requests.  In normal CGI */
  /* use we only accept and process one request.  */
  while( FCGI_Accept() >= 0 ) {
#endif /* def USE_FASTCGI */

    /* -------------------------------------------------------------------- */
    /*      Process a request.                                              */
    /* -------------------------------------------------------------------- */
    mapserv = msAllocMapServObj();
    mapserv->sendheaders = sendheaders; /* override the default if necessary (via command line -nh switch) */

    mapserv->request->NumParams = loadParams(mapserv->request, NULL, NULL, 0, NULL);
    if( mapserv->request->NumParams == -1 ) {
      msCGIWriteError(mapserv);
      goto end_request;
    }

    mapserv->map = msCGILoadMap(mapserv);
    if(!mapserv->map) {
      msCGIWriteError(mapserv);
      goto end_request;
    }

    if( mapserv->map->debug >= MS_DEBUGLEVEL_TUNING)
      msGettimeofday(&requeststarttime, NULL);

#ifdef USE_FASTCGI
    if( mapserv->map->debug ) {
      static int nRequestCounter = 1;

      msDebug( "CGI Request %d on process %d\n", nRequestCounter, getpid() );
      nRequestCounter++;
    }
#endif




    if(msCGIDispatchRequest(mapserv) != MS_SUCCESS) {
      msCGIWriteError(mapserv);
      goto end_request;
    }


end_request:
    if(mapserv) {
      if(mapserv->map && mapserv->map->debug >= MS_DEBUGLEVEL_TUNING) {
        msGettimeofday(&requestendtime, NULL);
        msDebug("mapserv request processing time (msLoadMap not incl.): %.3fs\n",
                (requestendtime.tv_sec+requestendtime.tv_usec/1.0e6)-
                (requeststarttime.tv_sec+requeststarttime.tv_usec/1.0e6) );
      }
      msCGIWriteLog(mapserv,MS_FALSE);
      msFreeMapServObj(mapserv);
    }
#ifdef USE_FASTCGI
    /* FCGI_ --- return to top of loop */
    msResetErrorList();
    continue;
  } /* end fastcgi loop */
#endif

  /* normal case, processing is complete */
  if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) {
    msGettimeofday(&execendtime, NULL);
    msDebug("mapserv total execution time: %.3fs\n",
            (execendtime.tv_sec+execendtime.tv_usec/1.0e6)-
            (execstarttime.tv_sec+execstarttime.tv_usec/1.0e6) );
  }
  msCleanup(0);

#ifdef _WIN32
  /* flush pending writes to stdout */
  fflush(stdout);
#endif

  exit( 0 );
}
Пример #8
0
int msOutputFormatValidate( outputFormatObj *format, int issue_error )

{
  int result = MS_TRUE;
  char *driver_ext;

  format->bands = atoi(msGetOutputFormatOption( format, "BAND_COUNT", "1" ));

  /* Enforce the requirement that JPEG be RGB and TRANSPARENT=OFF */
  driver_ext = strstr(format->driver,"/");
  if( driver_ext && ++driver_ext && !strcasecmp(driver_ext,"JPEG")) {
    if( format->transparent ) {
      if( issue_error )
        msSetError( MS_MISCERR,
                    "JPEG OUTPUTFORMAT %s has TRANSPARENT set ON, but this is not supported.\n"
                    "It has been disabled.\n",
                    "msOutputFormatValidate()", format->name );
      else
        msDebug( "JPEG OUTPUTFORMAT %s has TRANSPARENT set ON, but this is not supported.\n"
                 "It has been disabled.\n",
                 format->name );

      format->transparent = MS_FALSE;
      result = MS_FALSE;
    }
    if( format->imagemode == MS_IMAGEMODE_RGBA ) {
      if( issue_error )
        msSetError( MS_MISCERR,
                    "JPEG OUTPUTFORMAT %s has IMAGEMODE RGBA, but this is not supported.\n"
                    "IMAGEMODE forced to RGB.\n",
                    "msOutputFormatValidate()", format->name );
      else
        msDebug( "JPEG OUTPUTFORMAT %s has IMAGEMODE RGBA, but this is not supported.\n"
                 "IMAGEMODE forced to RGB.\n",
                 format->name );

      format->imagemode = MS_IMAGEMODE_RGB;
      result = MS_FALSE;
    }
  }

  if( format->transparent && format->imagemode == MS_IMAGEMODE_RGB ) {
    if( issue_error )
      msSetError( MS_MISCERR,
                  "OUTPUTFORMAT %s has TRANSPARENT set ON, but an IMAGEMODE\n"
                  "of RGB instead of RGBA.  Changing imagemode to RGBA.\n",
                  "msOutputFormatValidate()", format->name );
    else
      msDebug("OUTPUTFORMAT %s has TRANSPARENT set ON, but an IMAGEMODE\n"
              "of RGB instead of RGBA.  Changing imagemode to RGBA.\n",
              format->name );

    format->imagemode = MS_IMAGEMODE_RGBA;
    result = MS_FALSE;
  }

  /* Special checking around RAWMODE image modes. */
  if( format->imagemode == MS_IMAGEMODE_INT16
      || format->imagemode == MS_IMAGEMODE_FLOAT32
      || format->imagemode == MS_IMAGEMODE_BYTE ) {
    if( strncmp(format->driver,"GDAL/",5) != 0 ) {
      result = MS_FALSE;
      if( issue_error )
        msSetError( MS_MISCERR,
                    "OUTPUTFORMAT %s has IMAGEMODE BYTE/INT16/FLOAT32, but this is only supported for GDAL drivers.",
                    "msOutputFormatValidate()", format->name );
      else
        msDebug( "OUTPUTFORMAT %s has IMAGEMODE BYTE/INT16/FLOAT32, but this is only supported for GDAL drivers.",
                 format->name );
    }

    if( format->renderer != MS_RENDER_WITH_RAWDATA ) /* see bug 724 */
      format->renderer = MS_RENDER_WITH_RAWDATA;
  }

  return result;
}
Пример #9
0
int msUVRASTERLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)

{
  uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *) layer->layerinfo;
  imageObj *image_tmp;
  mapObj   map_tmp;
  unsigned int spacing;
  int width, height, u_src_off, v_src_off, i, x, y;
  char   **alteredProcessing = NULL;
  char **savedProcessing = NULL;

  if (layer->debug)
    msDebug("Entering msUVRASTERLayerWhichShapes().\n");

  if( uvlinfo == NULL )
    return MS_FAILURE;

  /* QUERY NOT SUPPORTED YET */
  if (isQuery == MS_TRUE) {
    msSetError( MS_MISCERR, "Query is not supported for UV layer.", "msUVRASTERLayerWhichShapes()" );
    return MS_FAILURE;
  }


  if( CSLFetchNameValue( layer->processing, "BANDS" ) == NULL ) {
    msSetError( MS_MISCERR, "BANDS processing option is required for UV layer. You have to specified 2 bands.",
                "msUVRASTERLayerWhichShapes()" );
    return MS_FAILURE;
  }
  /* -------------------------------------------------------------------- */
  /*      Determine desired spacing.  Default to 30 if not otherwise set  */
  /* -------------------------------------------------------------------- */
  spacing = 30;
  if( CSLFetchNameValue( layer->processing, "UV_SPACING" ) != NULL ) {
    spacing =
      atoi(CSLFetchNameValue( layer->processing, "UV_SPACING" ));
  }

  width = (int)ceil(layer->map->width/spacing);
  height = (int)ceil(layer->map->height/spacing);
  map_tmp.cellsize = layer->map->cellsize*spacing;

  if (layer->debug)
    msDebug("msUVRASTERLayerWhichShapes(): width: %d, height: %d, cellsize: %g\n",
            width, height, map_tmp.cellsize);

  /* Initialize our dummy map */
  MS_INIT_COLOR(map_tmp.imagecolor, 255,255,255,255);
  map_tmp.resolution = layer->map->resolution;
  map_tmp.defresolution = layer->map->defresolution;
  map_tmp.outputformat = (outputFormatObj *) msSmallCalloc(1,sizeof(outputFormatObj));
  uvlinfo->band_count = map_tmp.outputformat->bands = 2;
  map_tmp.outputformat->name = NULL;
  map_tmp.outputformat->driver = NULL;
  map_tmp.outputformat->refcount = 0;
  map_tmp.outputformat->vtable = NULL;
  map_tmp.outputformat->device = NULL;
  map_tmp.outputformat->renderer = MS_RENDER_WITH_RAWDATA;
  map_tmp.outputformat->imagemode = MS_IMAGEMODE_FLOAT32;

  map_tmp.mappath = layer->map->mappath;
  map_tmp.shapepath = layer->map->shapepath;
  map_tmp.extent.minx = layer->map->extent.minx-(0.5*layer->map->cellsize)+(0.5*map_tmp.cellsize);
  map_tmp.extent.miny = layer->map->extent.miny-(0.5*layer->map->cellsize)+(0.5*map_tmp.cellsize);
  map_tmp.extent.maxx = map_tmp.extent.minx+((width-1)*map_tmp.cellsize);
  map_tmp.extent.maxy = map_tmp.extent.miny+((height-1)*map_tmp.cellsize);
  map_tmp.gt.rotation_angle = 0.0;

  msInitProjection(&map_tmp.projection);
  msCopyProjection(&map_tmp.projection, &layer->map->projection);

  if (layer->debug == 5)
    msDebug("msUVRASTERLayerWhichShapes(): extent: %g %d %g %g\n",
            map_tmp.extent.minx, map_tmp.extent.miny,
            map_tmp.extent.maxx, map_tmp.extent.maxy);

  /* important to use that function, to compute map
     geotransform, used by the resampling*/
  msMapSetSize(&map_tmp, width, height);

  if (layer->debug == 5)
    msDebug("msUVRASTERLayerWhichShapes(): geotransform: %g %g %g %g %g %g\n",
            map_tmp.gt.geotransform[0], map_tmp.gt.geotransform[1],
            map_tmp.gt.geotransform[2], map_tmp.gt.geotransform[3],
            map_tmp.gt.geotransform[4], map_tmp.gt.geotransform[5]);

  uvlinfo->extent = map_tmp.extent;

  image_tmp = msImageCreate(width, height, map_tmp.outputformat,
                            NULL, NULL, map_tmp.resolution, map_tmp.defresolution,
                            &(map_tmp.imagecolor));

  /* Default set to AVERAGE resampling */
  if( CSLFetchNameValue( layer->processing, "RESAMPLE" ) == NULL ) {
    alteredProcessing = CSLDuplicate( layer->processing );
    alteredProcessing =
      CSLSetNameValue( alteredProcessing, "RESAMPLE",
                       "AVERAGE");
    savedProcessing = layer->processing;
    layer->processing = alteredProcessing;
  }

  if (msDrawRasterLayerLow(&map_tmp, layer, image_tmp, NULL ) == MS_FAILURE) {
    msSetError(MS_MISCERR, "Unable to draw raster data.", NULL, "msUVRASTERLayerWhichShapes()" );
    return MS_FAILURE;
  }

  /* restore the saved processing */
  if (alteredProcessing != NULL)
    layer->processing = savedProcessing;

  /* free old query arrays */
  if (uvlinfo->u) {
    for (i=0; i<uvlinfo->width; ++i) {
      free(uvlinfo->u[i]);
    }
    free(uvlinfo->u);
  }

  if (uvlinfo->v) {
    for (i=0; i<uvlinfo->height; ++i) {
      free(uvlinfo->v[i]);
    }
    free(uvlinfo->v);
  }

  /* Update our uv layer structure */
  uvlinfo->width = width;
  uvlinfo->height = height;
  uvlinfo->query_results = width*height;

  uvlinfo->u = (float **)msSmallMalloc(sizeof(float *)*width);
  uvlinfo->v = (float **)msSmallMalloc(sizeof(float *)*width);

  for (x = 0; x < width; ++x) {
    uvlinfo->u[x] = (float *)msSmallMalloc(height * sizeof(float));
    uvlinfo->v[x] = (float *)msSmallMalloc(height * sizeof(float));

    for (y = 0; y < height; ++y) {
      u_src_off = v_src_off = x + y * width;
      v_src_off += width*height;

      uvlinfo->u[x][y] = image_tmp->img.raw_float[u_src_off];
      uvlinfo->v[x][y] = image_tmp->img.raw_float[v_src_off];

      /* null vector? update the number of results  */
      if (uvlinfo->u[x][y] == 0 && uvlinfo->v[x][y] == 0)
        --uvlinfo->query_results;
    }
  }

  msFreeImage(image_tmp); /* we do not need the imageObj anymore */

  uvlinfo->which_rect = map_tmp.extent;
  uvlinfo->next_shape = 0;

  return MS_SUCCESS;
}
Пример #10
0
int main(int argc, char *argv[])
{
  int i,j,k;

  mapObj    	   *map=NULL;
  imageObj         *image = NULL;
     
  char **layers=NULL;
  int num_layers=0;

  int layer_found=0;

  char *outfile=NULL; /* no -o sends image to STDOUT */

  int iterations = 1;
  int draws = 0;

  for(i=1;i<argc;i++) { 
    if (strcmp(argv[i],"-c") == 0) { /* user specified number of draws */
      iterations = atoi(argv[i+1]);
      printf("We will draw %d times...\n", iterations);
      continue;
    }

    if(strcmp(argv[i], "-all_debug") == 0 && i < argc-1 ) /* global debug */
    {
        int debug_level = atoi(argv[++i]);

        msSetGlobalDebugLevel(debug_level);

        /* Send output to stderr by default */ 
        if (msGetErrorFile() == NULL)
            msSetErrorFile("stderr", NULL);

        continue;
    }
    
  }
  
  for(draws=0; draws<iterations; draws++) {

  struct mstimeval requeststarttime, requestendtime;

  if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) 
      msGettimeofday(&requeststarttime, NULL);
      
  if(argc > 1 && strcmp(argv[1], "-v") == 0) {
    printf("%s\n", msGetVersion());
    exit(0);
  }

  /* ---- check the number of arguments, return syntax if not correct ---- */
  if( argc < 3 ) {
    fprintf(stdout, "\nPurpose: convert a mapfile to an image\n\n");
    fprintf(stdout,
            "Syntax: shp2img -m mapfile [-o image] [-e minx miny maxx maxy] [-s sizex sizey]\n"
            "               [-l \"layer1 [layers2...]\"] [-i format]\n"
            "               [-all_debug n] [-map_debug n] [-layer_debug n] [-p n] [-c n] [-d layername datavalue]\n");


    fprintf(stdout,"  -m mapfile: Map file to operate on - required\n" );
    fprintf(stdout,"  -i format: Override the IMAGETYPE value to pick output format\n" );
    fprintf(stdout,"  -o image: output filename (stdout if not provided)\n");
    fprintf(stdout,"  -e minx miny maxx maxy: extents to render\n");
    fprintf(stdout,"  -s sizex sizey: output image size\n");
    fprintf(stdout,"  -l layers: layers / groups to enable - make sure they are quoted and space seperated if more than one listed\n" );
    fprintf(stdout,"  -all_debug n: Set debug level for map and all layers\n" );
    fprintf(stdout,"  -map_debug n: Set map debug level\n" );
    fprintf(stdout,"  -layer_debug layer_name n: Set layer debug level\n" );
    fprintf(stdout,"  -c n: draw map n number of times\n" );
    fprintf(stdout,"  -p n: pause for n seconds after reading the map\n" );
    fprintf(stdout,"  -d layername datavalue: change DATA value for layer\n" );


    exit(0);
  }

  if ( msSetup() != MS_SUCCESS )
  {
      msWriteError(stderr);
      exit(1);
  }
 
  /* Use MS_ERRORFILE and MS_DEBUGLEVEL env vars if set */
  if ( msDebugInitFromEnv() != MS_SUCCESS )
  {
      msWriteError(stderr);
      msCleanup(0);
      exit(1);
  }

  for(i=1;i<argc;i++) { /* Step though the user arguments, 1st to find map file */
 
    if(strcmp(argv[i],"-m") == 0) {
      map = msLoadMap(argv[i+1], NULL);
      if(!map) {
	msWriteError(stderr);
        msCleanup(0);
	exit(1);
      }
      msApplyDefaultSubstitutions(map);
    }
  }

  if(!map) {
    fprintf(stderr, "Mapfile (-m) option not specified.\n");
    msCleanup(0);
    exit(1);
  }


  for(i=1;i<argc;i++) { /* Step though the user arguments */

    if(strcmp(argv[i],"-m") == 0) { /* skip it */
      i+=1;
    }

    if(strcmp(argv[i],"-p") == 0) {
        int pause_length = atoi(argv[i+1]);
        time_t start_time = time(NULL);

        printf( "Start pause of %d seconds.\n", pause_length );
        while( time(NULL) < start_time + pause_length ) {}
        printf( "Done pause.\n" );
            
        i+=1;
    }

    if(strcmp(argv[i],"-o") == 0) { /* load the output image filename */
      outfile = argv[i+1];
      i+=1;
    }
    
    if(strcmp(argv[i],"-i") == 0) { 
      outputFormatObj *format;

      format = msSelectOutputFormat( map, argv[i+1] );

      if( format == NULL )
          printf( "No such OUTPUTFORMAT as %s.\n", argv[i+1] );
      else
      {
          msFree( (char *) map->imagetype );
          map->imagetype = msStrdup( argv[i+1] );
          msApplyOutputFormat( &(map->outputformat), format, 
                               map->transparent, map->interlace, 
                               map->imagequality );
      }
      i+=1;
    }

    if(strcmp(argv[i],"-d") == 0) { /* swap layer data */
      for(j=0; j<map->numlayers; j++) {
	 if(strcmp(GET_LAYER(map, j)->name, argv[i+1]) == 0) {
	   free(GET_LAYER(map, j)->data);
	   GET_LAYER(map, j)->data = msStrdup(argv[i+2]);
	   break;
	 }
      }
      i+=2;
    }

    if(strcmp(argv[i], "-all_debug") == 0 && i < argc-1 ) /* global debug */
    {
        int debug_level = atoi(argv[++i]);

        /* msSetGlobalDebugLevel() already called. Just need to force debug
         * level in map and all layers
         */
        map->debug = debug_level;
        for(j=0; j<map->numlayers; j++) {
            GET_LAYER(map, j)->debug = debug_level;
        }

    }
    
    if(strcmp(argv[i], "-map_debug") == 0 && i < argc-1 ) /* debug */
    {
        map->debug = atoi(argv[++i]);

        /* Send output to stderr by default */ 
        if (msGetErrorFile() == NULL)
            msSetErrorFile("stderr", NULL);
    }
    
    if(strcmp(argv[i], "-layer_debug") == 0 && i < argc-1 ) /* debug */
    {
        const char *layer_name = argv[++i];
        int debug_level = atoi(argv[++i]);
        int got_layer = 0;

        for(j=0; j<map->numlayers; j++) {
            if(strcmp(GET_LAYER(map, j)->name,layer_name) == 0 ) {
                GET_LAYER(map, j)->debug = debug_level;
                got_layer = 1;
            }
        }
        if( !got_layer )
            fprintf( stderr, 
                     " Did not find layer '%s' from -layer_debug switch.\n", 
                     layer_name );

        /* Send output to stderr by default */ 
        if (msGetErrorFile() == NULL)
            msSetErrorFile("stderr", NULL);
    }
    
    if(strcmp(argv[i],"-e") == 0) { /* change extent */
        if( argc <= i+4 ) {
            fprintf( stderr, 
                     "Argument -e needs 4 space separated numbers as argument.\n" ); 
            msCleanup(0);
            exit(1);
        }
      map->extent.minx = atof(argv[i+1]);
      map->extent.miny = atof(argv[i+2]);
      map->extent.maxx = atof(argv[i+3]);
      map->extent.maxy = atof(argv[i+4]);
      i+=4;
    }

    if (strcmp(argv[i], "-s") == 0) {
      msMapSetSize(map, atoi(argv[i+1]), atoi(argv[i+2]));
      i+=2;
    }    

    if(strcmp(argv[i],"-l") == 0) { /* load layer list */
      layers = msStringSplit(argv[i+1], ' ', &(num_layers));

      for(j=0; j<num_layers; j++) { /* loop over -l */
          layer_found=0;
          for(k=0; k<map->numlayers; k++) {
              if((GET_LAYER(map, k)->name && strcasecmp(GET_LAYER(map, k)->name, layers[j]) == 0) || (GET_LAYER(map, k)->group && strcasecmp(GET_LAYER(map, k)->group, layers[j]) == 0)) {
                  layer_found = 1;
                  break;
              }
          }
          if (layer_found==0) {
              fprintf(stderr, "Layer (-l) \"%s\" not found\n", layers[j]);
              msCleanup(0);
              exit(1);
          }
      }

      for(j=0; j<map->numlayers; j++) {
          if(GET_LAYER(map, j)->status == MS_DEFAULT)
              continue;
          else {
              GET_LAYER(map, j)->status = MS_OFF;
              for(k=0; k<num_layers; k++) {
                  if((GET_LAYER(map, j)->name && strcasecmp(GET_LAYER(map, j)->name, layers[k]) == 0) ||
                     (GET_LAYER(map, j)->group && strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0)) {
                      GET_LAYER(map, j)->status = MS_ON;
                      break;
                  }
              }
          }
      }

      msFreeCharArray(layers, num_layers);

      i+=1;
     }
  }
  
  image = msDrawMap(map, MS_FALSE);

  if(!image) {
    msWriteError(stderr);

    msFreeMap(map);
    msCleanup(0);
    exit(1);
  }

  if( msSaveImage(map, image, outfile) != MS_SUCCESS ) {
    msWriteError(stderr);
  }

  msFreeImage(image);
  msFreeMap(map);

  if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) {
    msGettimeofday(&requestendtime, NULL);
    msDebug("shp2img total time: %.3fs\n", 
            (requestendtime.tv_sec+requestendtime.tv_usec/1.0e6)-
            (requeststarttime.tv_sec+requeststarttime.tv_usec/1.0e6) );
  }

  msCleanup(0);

} /*   for(draws=0; draws<iterations; draws++) { */
  return(0);
} /* ---- END Main Routine ---- */
Пример #11
0
int msContourLayerOpen(layerObj *layer)
{
  char *decrypted_path;
  char szPath[MS_MAXPATHLEN];
  contourLayerInfo *clinfo;

  if (layer->debug)
    msDebug("Entering msContourLayerOpen().\n");

  /* If we don't have info, initialize an empty one now */
  if (layer->layerinfo == NULL)
    msContourLayerInfoInitialize(layer);

  clinfo = (contourLayerInfo *) layer->layerinfo;
  if (layer->data == NULL && layer->tileindex == NULL ) {
    msSetError(MS_MISCERR,
               "Layer %s has neither DATA nor TILEINDEX defined.",
               "msContourLayerOpen()",
               layer->name);
    return MS_FAILURE;
  }

  if( layer->tileindex != NULL )
  {
      char szTilename[MS_MAXPATHLEN];
      int status;
      int tilelayerindex, tileitemindex, tilesrsindex;
      rectObj searchrect;
      layerObj* tlp;
      shapeObj tshp;
      char tilesrsname[1];

      msInitShape(&tshp);
      searchrect = layer->map->extent;

      status = msDrawRasterSetupTileLayer(layer->map, layer,
                                 &searchrect, MS_FALSE,
                                 &tilelayerindex,
                                 &tileitemindex,
                                 &tilesrsindex,
                                 &tlp);
      if( status == MS_FAILURE )
      {
          return MS_FAILURE;
      }

      status = msDrawRasterIterateTileIndex(layer, tlp, &tshp,
                                            tileitemindex, -1,
                                            szTilename, sizeof(szTilename),
                                            tilesrsname, sizeof(tilesrsname));
      if( status == MS_FAILURE || status == MS_DONE ) {
          if( status == MS_DONE )
          {
              if (layer->debug)
                msDebug("No raster matching filter.\n");
          }
          msDrawRasterCleanupTileLayer(tlp, tilelayerindex);
          return MS_FAILURE;
      }

      msDrawRasterCleanupTileLayer(tlp, tilelayerindex);

      msDrawRasterBuildRasterPath(layer->map, layer, szTilename, szPath);
      decrypted_path = msStrdup(szPath);

      /* Cancel the time filter that might have been set on ours in case of */
      /* a inline tileindex */
      msFreeExpression(&layer->filter);
      msInitExpression(&layer->filter);
  }
  else
  {
      msTryBuildPath3(szPath, layer->map->mappath, layer->map->shapepath, layer->data);
      decrypted_path = msDecryptStringTokens(layer->map, szPath);
  }
  
  GDALAllRegister();

  /* Open the original Dataset */

  msAcquireLock(TLOCK_GDAL);
  if (decrypted_path) {
    clinfo->hOrigDS = GDALOpen(decrypted_path, GA_ReadOnly);
    msFree(decrypted_path);
  } else
    clinfo->hOrigDS = NULL;

  msReleaseLock(TLOCK_GDAL);

  if (clinfo->hOrigDS == NULL) {
    msSetError(MS_IMGERR,
               "Unable to open GDAL dataset.",
               "msContourLayerOpen()");
    return MS_FAILURE;
  }
  
  /* Open the raster source */
  if (msContourLayerReadRaster(layer, layer->map->extent) != MS_SUCCESS)
    return MS_FAILURE;

  /* Generate Contour Dataset */
  if (msContourLayerGenerateContour(layer) != MS_SUCCESS)
    return MS_FAILURE;

  if (clinfo->hDS) {
    GDALClose(clinfo->hDS);
    clinfo->hDS = NULL;  
    free(clinfo->buffer);
  }

  /* Open our virtual ogr layer */
  if (clinfo->hOGRDS && (msLayerOpen(&clinfo->ogrLayer) != MS_SUCCESS))
    return MS_FAILURE;
  
  return MS_SUCCESS;
}
Пример #12
0
int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join)
{
  char *maskeddata, *temp, *sql, *column;
  char *conn_decrypted;
  int i, test;
  PGresult *query_result;
  msPOSTGRESQLJoinInfo *joininfo;

  if(join->joininfo)
    return MS_SUCCESS;

  joininfo = (msPOSTGRESQLJoinInfo *)malloc(sizeof(msPOSTGRESQLJoinInfo));
  if(!joininfo) {
    msSetError(MS_MEMERR, "Error allocating join info struct.",
               "msPOSTGRESQLJoinConnect()");
    return MS_FAILURE;
  }
  joininfo->conn = NULL;
  joininfo->row_num = 0;
  joininfo->query_result = NULL;
  joininfo->from_index = 0;
  joininfo->to_column = join->to;
  joininfo->from_value = NULL;
  joininfo->layer_debug = layer->debug;
  join->joininfo = joininfo;

  /*
   * We need three things at a minimum, the connection string, a table
   * name, and a column to join on.
   */
  if(!join->connection) {
    msSetError(MS_QUERYERR, "No connection information provided.",
               "MSPOSTGRESQLJoinConnect()");
    return MS_FAILURE;
  }
  if(!join->table) {
    msSetError(MS_QUERYERR, "No join table name found.",
               "msPOSTGRESQLJoinConnect()");
    return MS_FAILURE;
  }
  if(!joininfo->to_column) {
    msSetError(MS_QUERYERR, "No join to column name found.",
               "msPOSTGRESQLJoinConnect()");
    return MS_FAILURE;
  }

  /* Establish database connection */
  conn_decrypted = msDecryptStringTokens(layer->map, join->connection);
  if (conn_decrypted != NULL) {
    joininfo->conn = PQconnectdb(conn_decrypted);
    free(conn_decrypted);
  }
  if(!joininfo->conn || PQstatus(joininfo->conn) == CONNECTION_BAD) {
    maskeddata = (char *)malloc(strlen(layer->connection) + 1);
    strcpy(maskeddata, join->connection);
    temp = strstr(maskeddata, "password="******"Unable to connect to PostgreSQL using the string %s.\n  Error reported: %s\n",
               "msPOSTGRESQLJoinConnect()",
               maskeddata, PQerrorMessage(joininfo->conn));
    free(maskeddata);
    if(!joininfo->conn) {
      free(joininfo->conn);
    }
    free(joininfo);
    join->joininfo = NULL;
    return MS_FAILURE;
  }

  /* Determine the number and names of columns in the join table. */
  sql = (char *)malloc(36 + strlen(join->table) + 1);
  sprintf(sql, "SELECT * FROM %s WHERE false LIMIT 0", join->table);

  if(joininfo->layer_debug) {
    msDebug("msPOSTGRESQLJoinConnect(): executing %s.\n", sql);
  }

  query_result = PQexec(joininfo->conn, sql);
  if(!query_result || PQresultStatus(query_result) != PGRES_TUPLES_OK) {
    msSetError(MS_QUERYERR, "Error determining join items: %s.",
               "msPOSTGRESQLJoinConnect()", PQerrorMessage(joininfo->conn));
    if(query_result) {
      PQclear(query_result);
      query_result = NULL;
    }
    free(sql);
    return MS_FAILURE;
  }
  free(sql);
  join->numitems = PQnfields(query_result);
  join->items = malloc(sizeof(char *) * (join->numitems));

  /* We want the join-to column to be first in the list. */
  test = 1;
  for(i = 0; i < join->numitems; i++) {
    column = PQfname(query_result, i);
    if(strcmp(column, joininfo->to_column) != 0) {
      join->items[i + test] = (char *)malloc(strlen(column) + 1);
      strcpy(join->items[i + test], column);
    } else {
      test = 0;
      join->items[0] = (char *)malloc(strlen(column) + 1);
      strcpy(join->items[0], column);
    }
  }
  PQclear(query_result);
  query_result = NULL;
  if(test == 1) {
    msSetError(MS_QUERYERR, "Unable to find join to column: %s",
               "msPOSTGRESQLJoinConnect()", joininfo->to_column);
    return MS_FAILURE;
  }

  if(joininfo->layer_debug) {
    for(i = 0; i < join->numitems; i++) {
      msDebug("msPOSTGRESQLJoinConnect(): Column %d named %s\n", i, join->items[i]);
    }
  }

  /* Determine the index of the join from column. */
  for(i = 0; i < layer->numitems; i++) {
    if(strcasecmp(layer->items[i], join->from) == 0) {
      joininfo->from_index = i;
      break;
    }
  }

  if(i == layer->numitems) {
    msSetError(MS_JOINERR, "Item %s not found in layer %s.",
               "msPOSTGRESQLJoinConnect()", join->from, layer->name);
    return MS_FAILURE;
  }

  return MS_SUCCESS;
}
Пример #13
0
int msPOSTGRESQLJoinNext(joinObj *join)
{
  msPOSTGRESQLJoinInfo *joininfo = join->joininfo;
  int i, length, row_count;
  char *sql, *columns;

  /* We need a connection, and a join value. */
  if(!joininfo || !joininfo->conn) {
    msSetError(MS_JOINERR, "Join has not been connected.\n",
               "msPOSTGRESQLJoinNext()");
    return MS_FAILURE;
  }

  if(!joininfo->from_value) {
    msSetError(MS_JOINERR, "Join has not been prepared.\n",
               "msPOSTGRESQLJoinNext()");
    return MS_FAILURE;
  }

  /* Free the previous results. */
  if(join->values) {
    msFreeCharArray(join->values, join->numitems);
    join->values = NULL;
  }

  /* We only need to execute the query if no results exist. */
  if(!joininfo->query_result) {
    /* Write the list of column names. */
    length = 0;
    for(i = 0; i < join->numitems; i++) {
      length += 8 + strlen(join->items[i]) + 2;
    }

    columns = (char *)malloc(length);
    if(!columns) {
      msSetError(MS_MEMERR, "Failure to malloc.\n",
                 "msPOSTGRESQLJoinNext()");
      return MS_FAILURE;
    }

    strcpy(columns, "");
    for(i = 0; i < join->numitems; i++) {
      strcat(columns, "\"");
      strcat(columns, join->items[i]);
      strcat(columns, "\"::text");
      if(i != join->numitems - 1) {
        strcat(columns, ", ");
      }
    }

    /* Create the query string. */
    sql = (char *)malloc(26 + strlen(columns) + strlen(join->table) +
                         strlen(join->to) + strlen(joininfo->from_value));
    if(!sql) {
      msSetError(MS_MEMERR, "Failure to malloc.\n",
                 "msPOSTGRESQLJoinNext()");
      return MS_FAILURE;
    }
    sprintf(sql, "SELECT %s FROM %s WHERE %s = '%s'", columns, join->table, join->to, joininfo->from_value);
    if(joininfo->layer_debug) {
      msDebug("msPOSTGRESQLJoinNext(): executing %s.\n", sql);
    }

    free(columns);

    joininfo->query_result = PQexec(joininfo->conn, sql);

    if(!joininfo->query_result ||
        PQresultStatus(joininfo->query_result) != PGRES_TUPLES_OK) {
      msSetError(MS_QUERYERR, "Error executing queri %s: %s\n",
                 "msPOSTGRESQLJoinNext()", sql,
                 PQerrorMessage(joininfo->conn));
      if(joininfo->query_result) {
        PQclear(joininfo->query_result);
        joininfo->query_result = NULL;
      }
      free(sql);
      return MS_FAILURE;
    }
    free(sql);
  }
  row_count = PQntuples(joininfo->query_result);

  /* see if we're done processing this set */
  if(joininfo->row_num >= row_count) {
    return(MS_DONE);
  }
  if(joininfo->layer_debug) {
    msDebug("msPOSTGRESQLJoinNext(): fetching row %ld.\n",
            joininfo->row_num);
  }

  /* Copy the resulting values into the joinObj. */
  join->values = (char **)malloc(sizeof(char *) * join->numitems);
  for(i = 0; i < join->numitems; i++) {
    join->values[i] = msStrdup(PQgetvalue(
                                 joininfo->query_result, joininfo->row_num, i));
  }

  joininfo->row_num++;

  return MS_SUCCESS;
}
Пример #14
0
static int msContourLayerReadRaster(layerObj *layer, rectObj rect)
{
  mapObj *map = layer->map;  
  char **bands;
  char pointer[64], memDSPointer[128];
  int band = 1;
  double adfGeoTransform[6], adfInvGeoTransform[6];
  double llx, lly, urx, ury;  
  rectObj copyRect, mapRect;
  int dst_xsize, dst_ysize;
  int virtual_grid_step_x, virtual_grid_step_y;
  int src_xoff, src_yoff, src_xsize, src_ysize;  
  double map_cellsize_x, map_cellsize_y, dst_cellsize_x, dst_cellsize_y;
  GDALRasterBandH hBand = NULL;
  CPLErr eErr;
  
  contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo;

  if (layer->debug)
    msDebug("Entering msContourLayerReadRaster().\n");

  if (clinfo == NULL || clinfo->hOrigDS == NULL) {
    msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!",
               "msContourLayerReadRaster()");
    return MS_FAILURE;    
  }

  bands = CSLTokenizeStringComplex(
               CSLFetchNameValue(layer->processing,"BANDS"), " ,", FALSE, FALSE );
  if (CSLCount(bands) > 0) {
    band = atoi(bands[0]);
    if (band < 1 || band > GDALGetRasterCount(clinfo->hOrigDS)) {
      msSetError( MS_IMGERR,
                  "BANDS PROCESSING directive includes illegal band '%d', should be from 1 to %d.",
                  "msContourLayerReadRaster()",
                  band, GDALGetRasterCount(clinfo->hOrigDS));
      CSLDestroy(bands);
      return MS_FAILURE;
    }
  }
  CSLDestroy(bands);

  hBand = GDALGetRasterBand(clinfo->hOrigDS, band);
  if (hBand == NULL)
  {
    msSetError(MS_IMGERR,
               "Band %d does not exist on dataset.",
               "msContourLayerReadRaster()", band);
    return MS_FAILURE;
  }

  if (layer->projection.numargs > 0 &&
      EQUAL(layer->projection.args[0], "auto")) {
    const char *wkt;
    wkt = GDALGetProjectionRef(clinfo->hOrigDS);
    if (wkt != NULL && strlen(wkt) > 0) {
      if (msOGCWKT2ProjectionObj(wkt, &(layer->projection),
                                 layer->debug) != MS_SUCCESS) {
        char  msg[MESSAGELENGTH*2];
        errorObj *ms_error = msGetErrorObj();

        snprintf( msg, sizeof(msg),
                  "%s\n"
                  "PROJECTION AUTO cannot be used for this "
                  "GDAL raster (`%s').",
                  ms_error->message, layer->data);
        msg[MESSAGELENGTH-1] = '\0';

        msSetError(MS_OGRERR, "%s","msDrawRasterLayer()",
                   msg);
        return MS_FAILURE;
      }
    }
  }
  
  /*
   * Compute the georeferenced window of overlap, and read the source data
   * downsampled to match output resolution, or at full resolution if
   * output resolution is lower than the source resolution.
   *
   * A large portion of this overlap calculation code was borrowed from 
   * msDrawRasterLayerGDAL(). 
   * Would be possible to move some of this to a reusable function?
   *
   * Note: This code works only if no reprojection is involved. It would
   * need rework to support cases where output projection differs from source
   * data file projection.
   */
  
  src_xsize = GDALGetRasterXSize(clinfo->hOrigDS);
  src_ysize = GDALGetRasterYSize(clinfo->hOrigDS);

  /* set the Dataset extent */
  msGetGDALGeoTransform(clinfo->hOrigDS, map, layer, adfGeoTransform);  
  clinfo->extent.minx = adfGeoTransform[0];
  clinfo->extent.maxy = adfGeoTransform[3];
  clinfo->extent.maxx = adfGeoTransform[0] + src_xsize * adfGeoTransform[1];
  clinfo->extent.miny = adfGeoTransform[3] + src_ysize * adfGeoTransform[5];
  
  if (layer->transform) {
    if (layer->debug)
      msDebug("msContourLayerReadRaster(): Entering transform.\n");

    InvGeoTransform(adfGeoTransform, adfInvGeoTransform);

    mapRect = rect;
    map_cellsize_x = map_cellsize_y = map->cellsize;      
#ifdef USE_PROJ
    /* if necessary, project the searchrect to source coords */
    if (msProjectionsDiffer( &(map->projection), &(layer->projection)))  {
      if ( msProjectRect(&map->projection, &layer->projection, &mapRect)
          != MS_SUCCESS ) {
        msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name);
        return MS_FAILURE;
      }

      map_cellsize_x = MS_CELLSIZE(mapRect.minx, mapRect.maxx, map->width);
      map_cellsize_y = MS_CELLSIZE(mapRect.miny, mapRect.maxy, map->height);

      /* if the projection failed to project the extent requested, we need to
         calculate the cellsize to preserve the initial map cellsize ratio */
      if ( (mapRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize)) ||
           (mapRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0)) ||
           (mapRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize)) || 
           (mapRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0)) ) {

        int src_unit, dst_unit;
        src_unit = GetMapserverUnitUsingProj(&map->projection);
        dst_unit = GetMapserverUnitUsingProj(&layer->projection);
        if (src_unit == -1 || dst_unit == -1) {
          msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name);
          return MS_FAILURE;
        }

        map_cellsize_x =  MS_CONVERT_UNIT(src_unit, dst_unit,
                                          MS_CELLSIZE(rect.minx, rect.maxx, map->width)); 
        map_cellsize_y = MS_CONVERT_UNIT(src_unit, dst_unit,
                                         MS_CELLSIZE(rect.miny, rect.maxy, map->height));
      }       
    }
#endif
    
    if (map_cellsize_x == 0 || map_cellsize_y == 0) {
      if (layer->debug)
        msDebug("msContourLayerReadRaster(): Cellsize can't be 0.\n");
      return MS_FAILURE;
    }
    
    /* Adjust MapServer pixel model to GDAL pixel model */
    mapRect.minx -= map_cellsize_x*0.5;
    mapRect.maxx += map_cellsize_x*0.5;
    mapRect.miny -= map_cellsize_y*0.5;
    mapRect.maxy += map_cellsize_y*0.5;


    /*
     * If raw data cellsize (from geotransform) is larger than output map_cellsize
     * then we want to extract only enough data to match the output map resolution
     * which means that GDAL will automatically sample the data on read.
     *
     * To prevent bad contour effects on tile edges, we adjust the target cellsize 
     * to align the extracted window with a virtual grid based on the origin of the 
     * raw data and a virtual grid step size corresponding to an integer sampling step.
     *
     * If source data has a greater cellsize (i.e. lower res) that requested ouptut map
     * then we use the raw data cellsize as target cellsize since there is no point in 
     * interpolating the data for contours in this case.
     */

    virtual_grid_step_x = (int)floor(map_cellsize_x / ABS(adfGeoTransform[1]));
    if (virtual_grid_step_x < 1)
      virtual_grid_step_x = 1; /* Do not interpolate data if grid sampling step < 1 */

    virtual_grid_step_y = (int)floor(map_cellsize_y / ABS(adfGeoTransform[5]));
    if (virtual_grid_step_y < 1)
      virtual_grid_step_y = 1; /* Do not interpolate data if grid sampling step < 1 */
    
    /* target cellsize is a multiple of raw data cellsize based on grid step*/
    dst_cellsize_x = ABS(adfGeoTransform[1]) * virtual_grid_step_x;
    dst_cellsize_y = ABS(adfGeoTransform[5]) * virtual_grid_step_y;

    /* Compute overlap between source and target views */

    copyRect = mapRect;

    if (copyRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize))
      copyRect.minx = GEO_TRANS(adfGeoTransform,0,src_ysize);
    if (copyRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0))
      copyRect.maxx = GEO_TRANS(adfGeoTransform,src_xsize,0);
    if (copyRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize))
      copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_ysize);
    if (copyRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0))
      copyRect.maxy = GEO_TRANS(adfGeoTransform+3,src_xsize,0);
    
    if (copyRect.minx >= copyRect.maxx || copyRect.miny >= copyRect.maxy) {
      if (layer->debug)
        msDebug("msContourLayerReadRaster(): No overlap.\n");
      return MS_SUCCESS;
    }

    /*
     * Convert extraction window to raster coordinates
     */
    llx = GEO_TRANS(adfInvGeoTransform+0,copyRect.minx,copyRect.miny);
    lly = GEO_TRANS(adfInvGeoTransform+3,copyRect.minx,copyRect.miny);
    urx = GEO_TRANS(adfInvGeoTransform+0,copyRect.maxx,copyRect.maxy);
    ury = GEO_TRANS(adfInvGeoTransform+3,copyRect.maxx,copyRect.maxy);

    /* 
     * Align extraction window with virtual grid 
     * (keep in mind raster coordinates origin is at upper-left)
     * We also add an extra buffer to fix tile boundarie issues when zoomed
     */
    llx = floor(llx / virtual_grid_step_x) * virtual_grid_step_x - (virtual_grid_step_x*5);
    urx = ceil(urx / virtual_grid_step_x) * virtual_grid_step_x + (virtual_grid_step_x*5);
    ury = floor(ury / virtual_grid_step_y) * virtual_grid_step_y - (virtual_grid_step_x*5);
    lly = ceil(lly / virtual_grid_step_y) * virtual_grid_step_y + (virtual_grid_step_x*5);
    
    src_xoff = MAX(0,(int) floor(llx+0.5));
    src_yoff = MAX(0,(int) floor(ury+0.5));
    src_xsize = MIN(MAX(0,(int) (urx - llx + 0.5)),
                    GDALGetRasterXSize(clinfo->hOrigDS) - src_xoff);
    src_ysize = MIN(MAX(0,(int) (lly - ury + 0.5)),
                    GDALGetRasterYSize(clinfo->hOrigDS) - src_yoff);

    /* Update the geographic extent (buffer added) */
    /* TODO: a better way to go the geo_trans */
    copyRect.minx = GEO_TRANS(adfGeoTransform+0,src_xoff,0);
    copyRect.maxx = GEO_TRANS(adfGeoTransform+0,src_xoff+src_xsize,0);
    copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_yoff+src_ysize);
    copyRect.maxy = GEO_TRANS(adfGeoTransform+3,0,src_yoff);
    
    /* 
     * If input window is to small then stop here
     */
    if (src_xsize < 2 || src_ysize < 2)
    {
      if (layer->debug)
        msDebug("msContourLayerReadRaster(): input window too small, or no apparent overlap between map view and this window(1).\n");
      return MS_SUCCESS;
    }

    /* Target buffer size */
    dst_xsize = (int)ceil((copyRect.maxx - copyRect.minx) / dst_cellsize_x);
    dst_ysize = (int)ceil((copyRect.maxy - copyRect.miny) / dst_cellsize_y);

    if (dst_xsize == 0 || dst_ysize == 0) {
      if (layer->debug)
        msDebug("msContourLayerReadRaster(): no apparent overlap between map view and this window(2).\n");
      return MS_SUCCESS;
    }

    if (layer->debug)
      msDebug( "msContourLayerReadRaster(): src=%d,%d,%d,%d, dst=%d,%d,%d,%d\n",
               src_xoff, src_yoff, src_xsize, src_ysize,
               0, 0, dst_xsize, dst_ysize );
  } else {
    src_xoff = 0;
    src_yoff = 0;
    dst_xsize = src_xsize = MIN(map->width,src_xsize);
    dst_ysize = src_ysize = MIN(map->height,src_ysize);
    copyRect.minx = copyRect.miny = 0;
    copyRect.maxx = map->width;
    copyRect.maxy = map->height;
    dst_cellsize_y = dst_cellsize_x = 1;
  }

  /* -------------------------------------------------------------------- */
  /*      Allocate buffer, and read data into it.                         */
  /* -------------------------------------------------------------------- */

  clinfo->buffer = (double *) malloc(sizeof(double) * dst_xsize * dst_ysize);
  if (clinfo->buffer == NULL) {
    msSetError(MS_MEMERR, "Malloc(): Out of memory.", "msContourLayerReadRaster()");
    return MS_FAILURE;
  }

  eErr = GDALRasterIO(hBand, GF_Read,
                      src_xoff, src_yoff, src_xsize, src_ysize,
                      clinfo->buffer, dst_xsize, dst_ysize, GDT_Float64,
                      0, 0);

  if (eErr != CE_None) {
    msSetError( MS_IOERR, "GDALRasterIO() failed: %s",
                "msContourLayerReadRaster()", CPLGetLastErrorMsg() );
    free(clinfo->buffer);
    return MS_FAILURE;
  }

  memset(pointer, 0, sizeof(pointer));
  CPLPrintPointer(pointer, clinfo->buffer, sizeof(pointer));
  sprintf(memDSPointer,"MEM:::DATAPOINTER=%s,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=Float64",
          pointer, dst_xsize, dst_ysize);
  clinfo->hDS = GDALOpen(memDSPointer,  GA_ReadOnly);
  if (clinfo->hDS == NULL) {
    msSetError(MS_IMGERR,
               "Unable to open GDAL Memory dataset.",
               "msContourLayerReadRaster()");
    free(clinfo->buffer);
    return MS_FAILURE;
  }

  adfGeoTransform[0] = copyRect.minx;
  adfGeoTransform[1] = dst_cellsize_x;
  adfGeoTransform[2] = 0;
  adfGeoTransform[3] = copyRect.maxy;
  adfGeoTransform[4] = 0;
  adfGeoTransform[5] = -dst_cellsize_y;

  clinfo->cellsize = MAX(dst_cellsize_x, dst_cellsize_y);
  {
    char buf[64];
    sprintf(buf, "%lf", clinfo->cellsize);
    msInsertHashTable(&layer->metadata, "__data_cellsize__", buf);
  }
      
  GDALSetGeoTransform(clinfo->hDS, adfGeoTransform);
  return MS_SUCCESS;
}
Пример #15
0
void msConnPoolRegister( layerObj *layer, 
                         void *conn_handle, 
                         void (*close_func)( void * ) )

{
    const char *close_connection = NULL;
    connectionObj *conn = NULL;

    if( layer->debug )
        msDebug( "msConnPoolRegister(%s,%s,%p)\n", 
                 layer->name, layer->connection, conn_handle );

/* -------------------------------------------------------------------- */
/*      We can't meaningful keep a connection with no connection or     */
/*      connection type string on the layer.                            */
/* -------------------------------------------------------------------- */
    if( layer->connection == NULL )
    {
        if( layer->tileindex != NULL
            && layer->connectiontype == MS_OGR )
        {
            /* this is ok, no need to make a fuss */
        }
        else
        {
            msDebug( "%s: Missing CONNECTION on layer %s.\n",
                     "msConnPoolRegister()", 
                     layer->name );
            
            msSetError( MS_MISCERR, 
                        "Missing CONNECTION on layer %s.",
                        "msConnPoolRegister()", 
                        layer->name );
        }
        return;
    }

/* -------------------------------------------------------------------- */
/*      Grow the array of connection information objects if needed.     */
/* -------------------------------------------------------------------- */
    msAcquireLock( TLOCK_POOL );

    if( connectionCount == connectionMax )
    {
        connectionMax += 10;
        connections = (connectionObj *) 
            realloc(connections,
                    sizeof(connectionObj) * connectionMax );
        if( connections == NULL )
        {
            msSetError(MS_MEMERR, NULL, "msConnPoolRegister()");
            msReleaseLock( TLOCK_POOL );
            return;
        }
    }

/* -------------------------------------------------------------------- */
/*      Set the new connection information.                             */
/* -------------------------------------------------------------------- */
    conn = connections + connectionCount;

    connectionCount++;

    conn->connectiontype = layer->connectiontype;
    conn->connection = msStrdup( layer->connection );
    conn->close = close_func;
    conn->ref_count = 1;
    conn->thread_id = msGetThreadId();
    conn->last_used = time(NULL);
    conn->conn_handle = conn_handle;
    conn->debug = layer->debug;

/* -------------------------------------------------------------------- */
/*      Categorize the connection handling information.                 */
/* -------------------------------------------------------------------- */
    close_connection = 
        msLayerGetProcessingKey( layer, "CLOSE_CONNECTION" );

    if( close_connection == NULL )
        close_connection = "NORMAL";

    if( strcasecmp(close_connection,"NORMAL") == 0 )
        conn->lifespan = MS_LIFE_ZEROREF;
    else if( strcasecmp(close_connection,"DEFER") == 0 )
        conn->lifespan = MS_LIFE_FOREVER;
    else if( strcasecmp(close_connection,"ALWAYS") == 0 )
        conn->lifespan = MS_LIFE_SINGLE;
    else
    {
        msDebug("msConnPoolRegister(): "
                "Unrecognised CLOSE_CONNECTION value '%s'\n",
                close_connection );

        msSetError( MS_MISCERR, "Unrecognised CLOSE_CONNECTION value '%s'",
                    "msConnPoolRegister()", 
                    close_connection );
        conn->lifespan = MS_LIFE_ZEROREF;
    }

    msReleaseLock( TLOCK_POOL );
}
Пример #16
0
int msContourLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
{
  int i;
  rectObj newRect;
  contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo;

  if (layer->debug)
    msDebug("Entering msContourLayerWhichShapes().\n");

  if (clinfo == NULL) {
    msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!",
               "msContourLayerWhichShapes()");
    return MS_FAILURE;
  }

  newRect = rect;
  
#ifdef USE_PROJ
    /* if necessary, project the searchrect to source coords */
    if (msProjectionsDiffer( &(layer->map->projection), &(layer->projection)))  {
      if (msProjectRect(&layer->projection, &layer->map->projection, &newRect)
          != MS_SUCCESS ) {
        msDebug("msContourLayerWhichShapes(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name);
        return MS_FAILURE;
      }
    }
#endif

  /* regenerate the raster io */
  if (clinfo->hOGRDS)
    msConnPoolRelease(&clinfo->ogrLayer, clinfo->hOGRDS);
  
  msLayerClose(&clinfo->ogrLayer);
  
  /* Open the raster source */
  if (msContourLayerReadRaster(layer, newRect) != MS_SUCCESS)
    return MS_FAILURE;

  /* Generate Contour Dataset */
  if (msContourLayerGenerateContour(layer) != MS_SUCCESS)
    return MS_FAILURE;

  if (clinfo->hDS) {
    GDALClose(clinfo->hDS);
    clinfo->hDS = NULL;
    free(clinfo->buffer);
  }
  
  if (!clinfo->hOGRDS) /* no overlap */
    return MS_DONE;
  
  /* Open our virtual ogr layer */
  if (msLayerOpen(&clinfo->ogrLayer) != MS_SUCCESS)
    return MS_FAILURE;

  clinfo->ogrLayer.numitems = layer->numitems;
  clinfo->ogrLayer.items = (char **) msSmallMalloc(sizeof(char *)*layer->numitems);
  for (i=0; i<layer->numitems;++i) {
    clinfo->ogrLayer.items[i] = msStrdup(layer->items[i]);
  }

  return msLayerWhichShapes(&clinfo->ogrLayer, rect, isQuery);
}
Пример #17
0
int msProjectRectGrid(projectionObj *in, projectionObj *out, rectObj *rect)
{
#ifdef USE_PROJ
  pointObj prj_point;
  rectObj prj_rect;
  int   rect_initialized = MS_FALSE, failure=0;
  int     ix, iy;

  double dx, dy;
  double x, y;

  dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS;
  dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS;

  /* first ensure the top left corner is processed, even if the rect
     turns out to be degenerate. */

  prj_point.x = rect->minx;
  prj_point.y = rect->miny;
#ifdef USE_POINT_Z_M
  prj_point.z = 0.0;
  prj_point.m = 0.0;
#endif /* USE_POINT_Z_M */

  msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
                    &failure);

  failure = 0;
  for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ ) {
    x = rect->minx + ix * dx;

    for(iy = 0; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ ) {
      y = rect->miny + iy * dy;

      prj_point.x = x;
      prj_point.y = y;
      msProjectGrowRect(in,out,&prj_rect,&rect_initialized,&prj_point,
                        &failure);
    }
  }

  if( !rect_initialized ) {
    prj_rect.minx = 0;
    prj_rect.maxx = 0;
    prj_rect.miny = 0;
    prj_rect.maxy = 0;

    msSetError(MS_PROJERR, "All points failed to reproject.", "msProjectRect()");
  } else {
    msDebug( "msProjectRect(): some points failed to reproject, doing internal sampling.\n" );
  }

  rect->minx = prj_rect.minx;
  rect->miny = prj_rect.miny;
  rect->maxx = prj_rect.maxx;
  rect->maxy = prj_rect.maxy;

  if( !rect_initialized )
    return MS_FAILURE;
  else
    return(MS_SUCCESS);
#else
  msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()");
  return(MS_FAILURE);
#endif
}
Пример #18
0
int msWFSLayerOpen(layerObj *lp,
                   const char *pszGMLFilename, rectObj *defaultBBOX)
{
#ifdef USE_WFS_LYR
  int status = MS_SUCCESS;
  msWFSLayerInfo *psInfo = NULL;

  if ( msCheckParentPointer(lp->map,"map")==MS_FAILURE )
    return MS_FAILURE;

  if (lp->wfslayerinfo != NULL) {
    psInfo =(msWFSLayerInfo*)lp->wfslayerinfo;

    /* Layer already opened.  If explicit filename requested then check */
    /* that file was already opened with the same filename. */
    /* If no explicit filename requested then we'll try to reuse the */
    /* previously opened layer... this will happen in a msDrawMap() call. */
    if (pszGMLFilename == NULL ||
        (psInfo->pszGMLFilename && pszGMLFilename &&
         strcmp(psInfo->pszGMLFilename, pszGMLFilename) == 0) ) {
      if (lp->layerinfo == NULL) {
        if (msWFSLayerWhichShapes(lp, psInfo->rect, MS_FALSE) == MS_FAILURE) /* no access to context (draw vs. query) here, although I doubt it matters... */
          return MS_FAILURE;
      }
      return MS_SUCCESS;  /* Nothing to do... layer is already opened */
    } else {
      /* Hmmm... should we produce a fatal error? */
      /* For now we'll just close the layer and reopen it. */
      if (lp->debug)
        msDebug("msWFSLayerOpen(): Layer already opened (%s)\n",
                lp->name?lp->name:"(null)" );
      msWFSLayerClose(lp);
    }
  }

  /* ------------------------------------------------------------------
   * Alloc and fill msWFSLayerInfo inside layer obj
   * ------------------------------------------------------------------ */
  lp->wfslayerinfo = psInfo = msAllocWFSLayerInfo();

  if (pszGMLFilename)
    psInfo->pszGMLFilename = msStrdup(pszGMLFilename);
  else {
    psInfo->pszGMLFilename = msTmpFile(lp->map,
                                       lp->map->mappath,
                                       NULL,
                                       "tmp.gml");
  }

  if (defaultBBOX) {
    /* __TODO__ If new bbox differs from current one then we should */
    /* invalidate current GML file in cache */
    psInfo->rect = *defaultBBOX;
  } else {
    /* Use map bbox by default */
    psInfo->rect = lp->map->extent;
  }

  /* We will call whichshapes() now and force downloading layer right */
  /* away.  This saves from having to call DescribeFeatureType and */
  /* parsing the response (being lazy I guess) and anyway given the */
  /* way we work with layers right now the bbox is unlikely to change */
  /* between now and the time whichshapes() would have been called by */
  /* the MapServer core. */
#ifdef USE_PROJ
  if((lp->map->projection.numargs > 0) && (lp->projection.numargs > 0))
    msProjectRect(&lp->map->projection, &lp->projection, &psInfo->rect); /* project the searchrect to source coords */
#endif

  if (msWFSLayerWhichShapes(lp, psInfo->rect, MS_FALSE) == MS_FAILURE)  /* no access to context (draw vs. query) here, although I doubt it matters... */
    status = MS_FAILURE;


  return status;
#else
  /* ------------------------------------------------------------------
   * WFS CONNECTION Support not included...
   * ------------------------------------------------------------------ */
  msSetError(MS_WFSCONNERR, "WFS CLIENT CONNECTION support is not available.",
             "msWFSLayerOpen()");
  return(MS_FAILURE);

#endif /* USE_WFS_LYR */
}
Пример #19
0
SHPTreeHandle msSHPDiskTreeOpen(struct zzip_dir *zdir, const char * pszTree,
                                int debug)
{
  char    *pszFullname, *pszBasename;
  SHPTreeHandle psTree;

  char    pabyBuf[16];
  int     i;
#ifdef SHAPELIB_DISABLED
  char    bBigEndian;

  /* -------------------------------------------------------------------- */
  /*  Establish the byte order on this machine.         */
  /* -------------------------------------------------------------------- */
  i = 1;
  if( *((uchar *) &i) == 1 )
    bBigEndian = MS_FALSE;
  else
    bBigEndian = MS_TRUE;
#endif /* SHAPELIB_DISABLED */

  /* -------------------------------------------------------------------- */
  /*  Initialize the info structure.              */
  /* -------------------------------------------------------------------- */
  psTree = (SHPTreeHandle) msSmallMalloc(sizeof(SHPTreeInfo));

  /* -------------------------------------------------------------------- */
  /*  Compute the base (layer) name.  If there is any extension     */
  /*  on the passed in filename we will strip it off.         */
  /* -------------------------------------------------------------------- */
  pszBasename = (char *) msSmallMalloc(strlen(pszTree)+5);
  strcpy( pszBasename, pszTree );
  for( i = strlen(pszBasename)-1;
       i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
       && pszBasename[i] != '\\';
       i-- ) {}

  if( pszBasename[i] == '.' )
    pszBasename[i] = '\0';

  /* -------------------------------------------------------------------- */
  /*  Open the .shp and .shx files.  Note that files pulled from      */
  /*  a PC to Unix with upper case filenames won't work!        */
  /* -------------------------------------------------------------------- */
  pszFullname = (char *) msSmallMalloc(strlen(pszBasename) + 5);
  sprintf( pszFullname, "%s%s", pszBasename, MS_INDEX_EXTENSION);
  psTree->fp = zzip_open_rb(zdir, pszFullname);

  msFree(pszBasename); /* don't need these any more */
  msFree(pszFullname);

  if( psTree->fp == NULL ) {
    msFree(psTree);
    return( NULL );
  }

  zzip_fread( pabyBuf, 8, 1, psTree->fp );

  memcpy( &psTree->signature, pabyBuf, 3 );
  if( strncmp(psTree->signature,"SQT",3) ) {
    /* ---------------------------------------------------------------------- */
    /*     must check if the 2 first bytes equal 0 of max depth that cannot   */
    /*     be more than 65535. If yes, we must swap all value. The problem    */
    /*     here is if there's no Depth (bytea 5,6,7,8 in the file) all bytes  */
    /*     will be set to 0. So,we will test with the number of shapes (bytes */
    /*     1,2,3,4) that cannot be more than 65535 too.                       */
    /* ---------------------------------------------------------------------- */
    if (debug) {
      msDebug("WARNING in msSHPDiskTreeOpen(): %s is in old index format "
              "which has been deprecated.  It is strongly recommended to "
              "regenerate it in new format.\n", pszTree);
    }
    if((pabyBuf[4] == 0 && pabyBuf[5] == 0 &&
        pabyBuf[6] == 0 && pabyBuf[7] == 0)) {
      psTree->LSB_order = !(pabyBuf[0] == 0 && pabyBuf[1] == 0);
    } else {
      psTree->LSB_order = !(pabyBuf[4] == 0 && pabyBuf[5] == 0);
    }
    psTree->needswap = ((psTree->LSB_order) != (!bBigEndian));

    /* ---------------------------------------------------------------------- */
    /*     poor hack to see if this quadtree was created by a computer with a */
    /*     different Endian                                                   */
    /* ---------------------------------------------------------------------- */
    psTree->version = 0;
  } else {
    psTree->needswap = (( pabyBuf[3] == MS_NEW_MSB_ORDER ) ^ ( bBigEndian ));

    psTree->LSB_order = ( pabyBuf[3] == MS_NEW_LSB_ORDER );
    memcpy( &psTree->version, pabyBuf+4, 1 );
    memcpy( &psTree->flags, pabyBuf+5, 3 );

    zzip_fread( pabyBuf, 8, 1, psTree->fp );
  }

  if( psTree->needswap ) SwapWord( 4, pabyBuf );
  memcpy( &psTree->nShapes, pabyBuf, 4 );

  if( psTree->needswap ) SwapWord( 4, pabyBuf+4 );
  memcpy( &psTree->nDepth, pabyBuf+4, 4 );

  return( psTree );
}