/************************************************************************ * 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, ¶ms); /* ** 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; }
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); }
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; }
/* 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, ¤t->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, ¤t->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, ¤t->bounds)) { msFreeShape(¤t->shape); msInitShape(¤t->shape); msDebug("Skipping an invalid shape falling outside of the given extent\n"); continue; } /* construct the item array */ if (layer->iteminfo) BuildFeatureAttributes(layer, layerinfo, ¤t->shape); /* evaluate the group expression */ if (layer->cluster.group.string) current->group = msClusterGetGroupText(&layer->cluster.group, ¤t->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); } }
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 ); }
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 }
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 ); }
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; }
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; }
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 ---- */
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; }
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; }
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; }
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; }
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 ); }
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); }
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 }
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 */ }
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 ); }