Commit 6ff28f09 authored by Bas Couwenberg's avatar Bas Couwenberg

Imported Upstream version 7.0.2

parent 4661a0d7
......@@ -17,7 +17,7 @@ include(CheckCSourceCompiles)
set (MapServer_VERSION_MAJOR 7)
set (MapServer_VERSION_MINOR 0)
set (MapServer_VERSION_REVISION 1)
set (MapServer_VERSION_REVISION 2)
set (MapServer_VERSION_SUFFIX "")
set(TARGET_VERSION_MAJOR ${MapServer_VERSION_MAJOR})
......
......@@ -8,7 +8,9 @@ next. Developers are strongly encouraged to document their changes and
their impacts on the users here. (Please add the most recent changes to
the top of the list.)
For a complete change history, please see the Git log comments.
For a complete change history, please see the Git log comments. For more
details about recent point releases, please see the online changelog at:
http://mapserver.org/development/changelog/
7.0.0 release (2015/07/24)
--------------------------
......
......@@ -189,10 +189,16 @@ int msHitTestLayer(mapObj *map, layerObj *layer, layer_hittest *hittest) {
status = msLayerWhichShapes(layer, searchrect, MS_FALSE);
if(status == MS_DONE) { /* no overlap */
#ifdef USE_GEOS
msFreeShape(&searchpoly);
#endif
msLayerClose(layer);
hittest->status = 0;
return MS_SUCCESS;
} else if(status != MS_SUCCESS) {
#ifdef USE_GEOS
msFreeShape(&searchpoly);
#endif
msLayerClose(layer);
return MS_FAILURE;
}
......@@ -245,6 +251,7 @@ int msHitTestLayer(mapObj *map, layerObj *layer, layer_hittest *hittest) {
hittest->status = 1;
if(maxfeatures >=0 && featuresdrawn >= maxfeatures) {
msFreeShape(&shape);
status = MS_DONE;
break;
}
......@@ -258,6 +265,10 @@ int msHitTestLayer(mapObj *map, layerObj *layer, layer_hittest *hittest) {
msFreeShape(&shape);
}
#ifdef USE_GEOS
msFreeShape(&searchpoly);
#endif
if (classgroup)
msFree(classgroup);
......
......@@ -318,6 +318,7 @@ int msComputeKernelDensityDataset(mapObj *map, imageObj *image, layerObj *kernel
msSetError(MS_MISCERR,"msComputeKernelDensityDataset()","failed to create in-memory gdal dataset for interpolated data");
status = MS_FAILURE;
free(iValues);
return status;
}
adfGeoTransform[0] = map->extent.minx - map->cellsize * 0.5; /* top left x */
adfGeoTransform[1] = map->cellsize;/* w-e pixel resolution */
......
......@@ -174,7 +174,7 @@ static cairoFaceCache* getCairoFontFace(cairoCacheData *cache, FT_Face ftface) {
cur->options = cairo_font_options_create();
cairo_font_options_set_hint_style(cur->options,CAIRO_HINT_STYLE_NONE);
return cur;
}
}
#define msCairoSetSourceColor(cr, c) cairo_set_source_rgba((cr),(c)->red/255.0,(c)->green/255.0,(c)->blue/255.0,(c)->alpha/255.0);
......@@ -1043,8 +1043,7 @@ int msRenderRasterizedSVGSymbol(imageObj *img, double x, double y, symbolObj *sy
height = surface_h = symbol->sizey;
}
if (style->rotation != 0) {
surface_w = MS_NINT(width * 1.415);
surface_h = MS_NINT(height * 1.415);
surface_w = surface_h = MS_NINT(MS_MAX(height, width) * 1.415);
}
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, surface_w, surface_h);
......
......@@ -250,10 +250,8 @@ int getNextShape(mapObj *map, layerObj *layer, double *values, int *nvalues, sty
status = msLayerNextShape(layer, shape);
if(status == MS_SUCCESS) {
#ifdef USE_PROJ
if(layer->project && msProjectionsDiffer(&(layer->projection), &(map->projection)))
if(layer->project)
msProjectShape(&layer->projection, &map->projection, shape);
else
layer->project = MS_FALSE;
#endif
if(msBindLayerToShape(layer, shape, MS_DRAWMODE_FEATURES|MS_DRAWMODE_LABELS) != MS_SUCCESS)
......@@ -363,6 +361,9 @@ int msDrawPieChartLayer(mapObj *map, layerObj *layer, imageObj *image)
return MS_FAILURE;
}
}
#ifdef USE_PROJ
layer->project = msProjectionsDiffer(&(layer->projection), &(map->projection));
#endif
/* step through the target shapes */
msInitShape(&shape);
......
......@@ -1497,6 +1497,52 @@ int msClusterLayerOpen(layerObj *layer)
return MS_SUCCESS;
}
int msClusterLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *filteritem)
{
msClusterLayerInfo* layerinfo = layer->layerinfo;
if (!layerinfo) {
msSetError(MS_MISCERR, "Layer is not open: %s", "msClusterLayerTranslateFilter()", layer->name);
return MS_FAILURE;
}
return layerinfo->srcLayer.vtable->LayerTranslateFilter(&layerinfo->srcLayer, filter, filteritem);
}
char* msClusterLayerEscapeSQLParam(layerObj *layer, const char* pszString)
{
msClusterLayerInfo* layerinfo = layer->layerinfo;
if (!layerinfo) {
msSetError(MS_MISCERR, "Layer is not open: %s", "msClusterLayerEscapeSQLParam()", layer->name);
return msStrdup("");
}
return layerinfo->srcLayer.vtable->LayerEscapeSQLParam(&layerinfo->srcLayer, pszString);
}
int msClusterLayerGetAutoProjection(layerObj *layer, projectionObj* projection)
{
msClusterLayerInfo* layerinfo = layer->layerinfo;
if (!layerinfo) {
msSetError(MS_MISCERR, "Layer is not open: %s", "msClusterLayerGetAutoProjection()", layer->name);
return MS_FAILURE;
}
return layerinfo->srcLayer.vtable->LayerGetAutoProjection(&layerinfo->srcLayer, projection);
}
int msClusterLayerGetPaging(layerObj *layer)
{
return MS_FALSE;
}
void msClusterLayerEnablePaging(layerObj *layer, int value)
{
return;
}
void msClusterLayerCopyVirtualTable(layerVTableObj* vtable)
{
vtable->LayerInitItemInfo = msClusterLayerInitItemInfo;
......@@ -1514,6 +1560,14 @@ void msClusterLayerCopyVirtualTable(layerVTableObj* vtable)
vtable->LayerGetNumFeatures = msClusterLayerGetNumFeatures;
vtable->LayerGetAutoStyle = msClusterLayerGetAutoStyle;
vtable->LayerTranslateFilter = msClusterLayerTranslateFilter;
/* vtable->LayerSupportsCommonFilters, use driver implementation */
vtable->LayerEscapeSQLParam = msClusterLayerEscapeSQLParam;
/* vtable->LayerEscapePropertyName, use driver implementation */
vtable->LayerEnablePaging = msClusterLayerEnablePaging;
vtable->LayerGetPaging = msClusterLayerGetPaging;
vtable->LayerGetAutoProjection = msClusterLayerGetAutoProjection;
}
#ifdef USE_CLUSTER_PLUGIN
......@@ -1531,8 +1585,7 @@ PluginInitializeVirtualTable(layerVTableObj* vtable, layerObj *layer)
#endif
int
msClusterLayerInitializeVirtualTable(layerObj *layer)
int msClusterLayerInitializeVirtualTable(layerObj *layer)
{
assert(layer != NULL);
assert(layer->vtable != NULL);
......
......@@ -925,6 +925,19 @@ int msCopyScaleToken(scaleTokenObj *src, scaleTokenObj *dst) {
return MS_SUCCESS;
}
int msCopyCompositingFilter(CompositingFilter **pdst, CompositingFilter *src) {
CompositingFilter *dst = NULL;
if(!src) {
*pdst = NULL;
return MS_SUCCESS;
}
if(!dst) {
dst = *pdst = msSmallMalloc(sizeof(CompositingFilter));
}
dst->filter = msStrdup(src->filter);
return MS_SUCCESS;
}
int msCopyCompositer(LayerCompositer **ldst, LayerCompositer *src) {
LayerCompositer *dst = NULL;
if(!src) {
......@@ -942,7 +955,7 @@ int msCopyCompositer(LayerCompositer **ldst, LayerCompositer *src) {
dst->comp_op = src->comp_op;
dst->opacity = src->opacity;
dst->next = NULL;
/* TODO dst->filter */
msCopyCompositingFilter(&dst->filter, src->filter);
src = src->next;
}
return MS_SUCCESS;
......
This diff is collapsed.
......@@ -1270,6 +1270,9 @@ LoadGDALImages( GDALDatasetH hDS, int band_numbers[4], int band_count,
if( bGotNoData && pafRawData[i] == fNoDataValue )
continue;
if( CPLIsNan(pafRawData[i]) )
continue;
if( !bMinMaxSet ) {
dfScaleMin = dfScaleMax = pafRawData[i];
bMinMaxSet = TRUE;
......@@ -1764,6 +1767,9 @@ msDrawRasterLayerGDAL_16BitClassification(
if( bGotNoData && pafRawData[i] == fNoDataValue )
continue;
if( CPLIsNan(pafRawData[i]) )
continue;
if( !bGotFirstValue ) {
fDataMin = fDataMax = pafRawData[i];
bGotFirstValue = TRUE;
......@@ -1915,6 +1921,9 @@ msDrawRasterLayerGDAL_16BitClassification(
continue;
}
if( CPLIsNan(fRawValue) )
continue;
if(SKIP_MASK(j,i))
continue;
......
This diff is collapsed.
......@@ -205,10 +205,9 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
pInfo->pboundinglines[0].point[1].y = rectMapCoordinates.maxy;
#ifdef USE_PROJ
if(layer->project && msProjectionsDiffer(&(layer->projection), &(layer->map->projection)))
layer->project = msProjectionsDiffer(&(layer->projection), &(layer->map->projection));
if(layer->project)
msProjectLine(&layer->map->projection, &layer->projection, &pInfo->pboundinglines[0]);
else
layer->project = MS_FALSE;
#endif
/*
......@@ -222,10 +221,8 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
pInfo->pboundinglines[1].point[1].y = rectMapCoordinates.miny;
#ifdef USE_PROJ
if(layer->project && msProjectionsDiffer(&(layer->projection), &(layer->map->projection)))
if(layer->project)
msProjectLine(&layer->map->projection, &layer->projection, &pInfo->pboundinglines[1]);
else
layer->project = MS_FALSE;
#endif
/*
......@@ -239,10 +236,8 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
pInfo->pboundinglines[2].point[1].y = rectMapCoordinates.maxy;
#ifdef USE_PROJ
if(layer->project && msProjectionsDiffer(&(layer->projection), &(layer->map->projection)))
if(layer->project)
msProjectLine(&layer->map->projection, &layer->projection, &pInfo->pboundinglines[2]);
else
layer->project = MS_FALSE;
#endif
/*
......@@ -256,10 +251,8 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
pInfo->pboundinglines[3].point[1].y = rectMapCoordinates.maxy;
#ifdef USE_PROJ
if(layer->project && msProjectionsDiffer(&(layer->projection), &(layer->map->projection)))
if(layer->project)
msProjectLine(&layer->map->projection, &layer->projection, &pInfo->pboundinglines[3]);
else
layer->project = MS_FALSE;
#endif
}
......@@ -680,7 +673,7 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map,
msCopyShape(&shapegrid, &tmpshape);
/* status = msDrawShape(map, layer, &tmpshape, image, -1); */
if(layer->project && msProjectionsDiffer(&(layer->projection), &(map->projection)))
if(layer->project)
msProjectShape(&layer->projection, &map->projection, &shapegrid);
msClipPolylineRect(&shapegrid, cliprect);
......@@ -1045,7 +1038,7 @@ static int _AdjustLabelPosition( layerObj *pLayer, shapeObj *pShape, msGraticule
ptPoint = pShape->line->point[0];
#ifdef USE_PROJ
if(pLayer->project && msProjectionsDiffer( &pLayer->projection, &pLayer->map->projection ))
if(pLayer->project)
msProjectShape( &pLayer->projection, &pLayer->map->projection, pShape );
#endif
......@@ -1087,7 +1080,7 @@ static int _AdjustLabelPosition( layerObj *pLayer, shapeObj *pShape, msGraticule
msTransformPixelToShape( pShape, pLayer->map->extent, pLayer->map->cellsize );
#ifdef USE_PROJ
if(pLayer->project && msProjectionsDiffer( &pLayer->map->projection, &pLayer->projection ))
if(pLayer->project)
msProjectShape( &pLayer->map->projection, &pLayer->projection, pShape );
#endif
......
......@@ -273,7 +273,7 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char
ts->rotation = l->angle * MS_DEG_TO_RAD;
}
int msAddLabelGroup(mapObj *map, imageObj *image, int layerindex, int classindex, shapeObj *shape, pointObj *point, double featuresize)
int msAddLabelGroup(mapObj *map, imageObj *image, layerObj* layer, int classindex, shapeObj *shape, pointObj *point, double featuresize)
{
int l,s, priority;
labelCacheSlotObj *cacheslot;
......@@ -283,9 +283,12 @@ int msAddLabelGroup(mapObj *map, imageObj *image, int layerindex, int classindex
classObj *classPtr=NULL;
int numtextsymbols = 0;
textSymbolObj **textsymbols, *ts;
int layerindex = layer->index;
layerPtr = (GET_LAYER(map, layerindex)); /* set up a few pointers for clarity */
classPtr = GET_LAYER(map, layerindex)->class[classindex];
// We cannot use GET_LAYER here because in drawQuery the drawing may happen
// on a temp layer only.
layerPtr = layer;
classPtr = layer->class[classindex];
if(classPtr->numlabels == 0) return MS_SUCCESS; /* not an error just nothing to do */
......
......@@ -523,7 +523,7 @@ int msLegendCalcSize(mapObj *map, int scale_independent, int *size_x, int *size_
if(*text) {
initTextSymbol(&ts);
msPopulateTextSymbolForLabelAndString(&ts,&map->legend.label,msStrdup(text),lp->scalefactor*resolutionfactor,resolutionfactor, 0);
msPopulateTextSymbolForLabelAndString(&ts,&map->legend.label,msStrdup(text),resolutionfactor,resolutionfactor, 0);
if(UNLIKELY(MS_FAILURE == msGetTextSymbolSize(map,&ts,&rect))) {
freeTextSymbol(&ts);
return MS_FAILURE;
......@@ -638,7 +638,7 @@ imageObj *msDrawLegend(mapObj *map, int scale_independent, map_hittest *hittest)
cur = (legendlabel*) msSmallMalloc(sizeof(legendlabel));
initTextSymbol(&cur->ts);
if(*text) {
msPopulateTextSymbolForLabelAndString(&cur->ts,&map->legend.label,msStrdup(text),lp->scalefactor*map->resolution/map->defresolution,map->resolution/map->defresolution, 0);
msPopulateTextSymbolForLabelAndString(&cur->ts,&map->legend.label,msStrdup(text),map->resolution/map->defresolution,map->resolution/map->defresolution, 0);
if(UNLIKELY(MS_FAILURE == msComputeTextPath(map,&cur->ts))) {
ret = MS_FAILURE;
goto cleanup;
......@@ -697,11 +697,13 @@ imageObj *msDrawLegend(mapObj *map, int scale_independent, map_hittest *hittest)
pnt.y += cur->height;
if(cur->ts.annotext) {
pnt.y -= cur->ts.textpath->bounds.bbox.maxy;
ret = msDrawTextSymbol(map,image,pnt,&cur->ts);
pointObj textPnt = pnt;
textPnt.y -= cur->ts.textpath->bounds.bbox.maxy;
textPnt.y += map->legend.label.offsety;
textPnt.x += map->legend.label.offsetx;
ret = msDrawTextSymbol(map,image,textPnt,&cur->ts);
if(UNLIKELY(ret == MS_FAILURE))
goto cleanup;
pnt.y += cur->ts.textpath->bounds.bbox.maxy;
freeTextSymbol(&cur->ts);
}
......
......@@ -58,7 +58,12 @@ void msLibXml2GenerateList(xmlNodePtr psParent, xmlNsPtr psNs, const char *elnam
int i = 0;
tokens = msStringSplit(values, delim, &n);
for (i=0; i<n; i++) {
xmlNewChild(psParent, psNs, BAD_CAST elname, BAD_CAST tokens[i]);
// Not sure we really need to distinguish empty vs non-empty case, but
// this does change the result of msautotest/wxs/expected/wcs_empty_cap111.xml otherwise
if( tokens[i] && tokens[i][0] != '\0' )
xmlNewTextChild(psParent, psNs, BAD_CAST elname, BAD_CAST tokens[i]);
else
xmlNewChild(psParent, psNs, BAD_CAST elname, BAD_CAST tokens[i]);
}
msFreeCharArray(tokens, n);
}
......
......@@ -38,6 +38,7 @@
#include <assert.h>
#include "mapserver.h"
#include "maptime.h"
#include "mapows.h"
#ifdef USE_MSSQL2008
......@@ -420,7 +421,7 @@ void setMSSQL2008LayerInfo(layerObj *layer, msMSSQL2008LayerInfo *MSSQL2008layer
void handleSQLError(layerObj *layer)
{
SQLCHAR SqlState[6], Msg[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER NativeError;
SQLLEN NativeError;
SQLSMALLINT i, MsgLen;
SQLRETURN rc;
msMSSQL2008LayerInfo *layerinfo = getMSSQL2008LayerInfo(layer);
......@@ -602,14 +603,14 @@ static int executeSQL(msODBCconn *conn, const char * sql)
}
/* Get columns name from query results */
static int columnName(msODBCconn *conn, int index, char *buffer, int bufferLength)
static int columnName(msODBCconn *conn, int index, char *buffer, int bufferLength, layerObj *layer, char pass_field_def)
{
SQLRETURN rc;
SQLCHAR columnName[SQL_COLUMN_NAME_MAX_LENGTH + 1];
SQLSMALLINT columnNameLen;
SQLSMALLINT dataType;
SQLUINTEGER columnSize;
SQLULEN columnSize;
SQLSMALLINT decimalDigits;
SQLSMALLINT nullable;
......@@ -629,6 +630,72 @@ static int columnName(msODBCconn *conn, int index, char *buffer, int bufferLengt
strlcpy(buffer, (const char *)columnName, bufferLength);
else
strlcpy(buffer, (const char *)columnName, SQL_COLUMN_NAME_MAX_LENGTH + 1);
if (pass_field_def) {
char md_item_name[256];
char gml_width[32], gml_precision[32];
const char *gml_type = NULL;
gml_width[0] = '\0';
gml_precision[0] = '\0';
switch( dataType ) {
case SQL_INTEGER:
case SQL_SMALLINT:
case SQL_TINYINT:
gml_type = "Integer";
break;
case SQL_BIGINT:
gml_type = "Long";
break;
case SQL_REAL:
case SQL_FLOAT:
case SQL_DOUBLE:
case SQL_DECIMAL:
case SQL_NUMERIC:
gml_type = "Real";
if( decimalDigits > 0 )
sprintf( gml_precision, "%d", decimalDigits );
break;
case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
case SQL_TYPE_TIMESTAMP:
gml_type = "Date";
break;
case SQL_BIT:
gml_type = "Boolean";
break;
default:
gml_type = "Character";
break;
}
if( columnSize > 0 )
sprintf( gml_width, "%d", columnSize );
snprintf( md_item_name, sizeof(md_item_name), "gml_%s_type", buffer );
if( msOWSLookupMetadata(&(layer->metadata), "G", "type") == NULL )
msInsertHashTable(&(layer->metadata), md_item_name, gml_type );
snprintf( md_item_name, sizeof(md_item_name), "gml_%s_width", buffer );
if( strlen(gml_width) > 0
&& msOWSLookupMetadata(&(layer->metadata), "G", "width") == NULL )
msInsertHashTable(&(layer->metadata), md_item_name, gml_width );
snprintf( md_item_name, sizeof(md_item_name), "gml_%s_precision",buffer );
if( strlen(gml_precision) > 0
&& msOWSLookupMetadata(&(layer->metadata), "G", "precision")==NULL )
msInsertHashTable(&(layer->metadata), md_item_name, gml_precision );
snprintf( md_item_name, sizeof(md_item_name), "gml_%s_nillable",buffer );
if( nullable > 0 )
msInsertHashTable(&(layer->metadata), md_item_name, "true" );
}
return 1;
} else {
setStmntError(conn);
......@@ -726,7 +793,7 @@ int msMSSQL2008LayerOpen(layerObj *layer)
"This error occured when trying to make a connection to the specified SQL server. \n"
"<br>\nMost commonly this is caused by <br>\n"
"(1) incorrect connection string <br>\n"
"(2) you didnt specify a 'user id=...' in your connection string <br>\n"
"(2) you didn't specify a 'user id=...' in your connection string <br>\n"
"(3) SQL server isnt running <br>\n"
"(4) TCPIP not enabled for SQL Client or server <br>\n\n",
"msMSSQL2008LayerOpen()", maskeddata, errMess);
......@@ -909,7 +976,11 @@ static int prepare_database(layerObj *layer, rectObj rect, char **query_string)
char buffer[10000] = "";
for(t = 0; t < layer->numitems; t++) {
#ifdef USE_ICONV
snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "convert(nvarchar(max), [%s]),", layer->items[t]);
#else
snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "convert(varchar(max), [%s]),", layer->items[t]);
#endif
}
if (layerinfo->geometry_format == MSSQLGEOMETRY_NATIVE)
......@@ -1578,8 +1649,8 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor
{
msMSSQL2008LayerInfo *layerinfo;
int result;
SQLINTEGER needLen = 0;
SQLINTEGER retLen = 0;
SQLLEN needLen = 0;
SQLLEN retLen = 0;
char dummyBuffer[1];
char *wkbBuffer;
char *valueBuffer;
......@@ -1606,7 +1677,7 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor
shape->type = MS_SHAPE_NULL;
while(shape->type == MS_SHAPE_NULL) {
/* SQLRETURN rc = SQLFetchScroll(layerinfo->conn->hstmt, SQL_FETCH_ABSOLUTE, (SQLINTEGER) (*record) + 1); */
/* SQLRETURN rc = SQLFetchScroll(layerinfo->conn->hstmt, SQL_FETCH_ABSOLUTE, (SQLLEN) (*record) + 1); */
/* We only do forward fetches. the parameter 'record' is ignored, but is incremented */
SQLRETURN rc = SQLFetch(layerinfo->conn->hstmt);
......@@ -1632,7 +1703,7 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor
if (needLen > 0) {
/* allocate the buffer - this will be a null-terminated string so alloc for the null too */
valueBuffer = (char*) msSmallMalloc( needLen + 1 );
valueBuffer = (char*) msSmallMalloc( needLen + 2 );
if ( valueBuffer == NULL ) {
msSetError( MS_QUERYERR, "Could not allocate value buffer.", "msMSSQL2008LayerGetShapeRandom()" );
return MS_FAILURE;
......@@ -1647,7 +1718,13 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor
valueBuffer[retLen] = 0; /* null terminate it */
/* Pop the value into the shape's value array */
#ifdef USE_ICONV
valueBuffer[retLen + 1] = 0;
shape->values[t] = msConvertWideStringToUTF8((wchar_t*)valueBuffer, "UCS-2LE");
msFree(valueBuffer);
#else
shape->values[t] = valueBuffer;
#endif
} else
/* Copy empty sting for NULL values */
shape->values[t] = msStrdup("");
......@@ -1914,6 +1991,13 @@ int msMSSQL2008LayerGetItems(layerObj *layer)
char found_geom = 0;
int item_num;
SQLSMALLINT cols = 0;
const char *value;
/*
* Pass the field definitions through to the layer metadata in the
* "gml_[item]_{type,width,precision}" set of metadata items for
* defining fields.
*/
char pass_field_def = 0;
if(layer->debug) {
msDebug("in msMSSQL2008LayerGetItems (find column names)\n");
......@@ -1957,10 +2041,15 @@ int msMSSQL2008LayerGetItems(layerObj *layer)
found_geom = 0; /* havent found the geom field */
item_num = 0;
/* consider populating the field definitions in metadata */
if((value = msOWSLookupMetadata(&(layer->metadata), "G", "types")) != NULL
&& strcasecmp(value,"auto") == 0 )
pass_field_def = 1;
for(t = 0; t < cols; t++) {
char colBuff[256];
columnName(layerinfo->conn, t + 1, colBuff, sizeof(colBuff));
columnName(layerinfo->conn, t + 1, colBuff, sizeof(colBuff), layer, pass_field_def);
if(strcmp(colBuff, layerinfo->geom_column) != 0) {
/* this isnt the geometry column */
......@@ -2038,7 +2127,7 @@ int msMSSQL2008LayerRetrievePK(layerObj *layer, char **urid_name, char* table_na
{
char buff[100];
SQLINTEGER retLen;
SQLLEN retLen;
rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_BINARY, buff, sizeof(buff), &retLen);
rc = SQLFetch(layerinfo->conn->hstmt);
......@@ -2099,7 +2188,7 @@ static int msMSSQL2008LayerParseData(layerObj *layer, char **geom_column_name, c
} else {
slength = strspn(pos_srid + 12, "-0123456789");
if(!slength) {
msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", "Error parsing MSSQL2008 data variable: You specified 'using SRID=#' but didnt have any numbers!<br><br>\n\nMore Help:<br><br>\n\n", data);
msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", "Error parsing MSSQL2008 data variable: You specified 'using SRID=#' but didn't have any numbers!<br><br>\n\nMore Help:<br><br>\n\n", data);
msFree(data);
return MS_FAILURE;
......
......@@ -42,7 +42,9 @@
#include "mapows.h"
#include <ctype.h>
#if 0
static int FLTHasUniqueTopLevelDuringFilter(FilterEncodingNode *psFilterNode);
#endif
int FLTIsNumeric(const char *pszValue)
{
......@@ -569,8 +571,6 @@ int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, int iLayerI
/************************************************************************/
int FLTIsSimpleFilter(FilterEncodingNode *psNode)
{
return MS_FALSE;
if (FLTValidForBBoxFilter(psNode)) {
if (FLTNumberOfFilterType(psNode, "DWithin") == 0 &&
FLTNumberOfFilterType(psNode, "Intersect") == 0 &&
......@@ -614,17 +614,43 @@ int FLTApplyFilterToLayer(FilterEncodingNode *psNode, mapObj *map, int iLayerInd
/************************************************************************/
int FLTLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map, int iLayerIndex)
{
/* ==================================================================== */
/* Check here to see if it is a simple filter and if that is */
/* the case, we are going to use the FILTER element on */
/* the layer. */
/* ==================================================================== */
layerObj* lp = GET_LAYER(map, iLayerIndex);
if (FLTIsSimpleFilter(psNode) && !(lp->connectiontype == MS_OGR && !FLTHasUniqueTopLevelDuringFilter(psNode)) ) {
return FLTApplySimpleSQLFilter(psNode, map, iLayerIndex);
return FLTLayerApplyPlainFilterToLayer(psNode, map, iLayerIndex);
}
/************************************************************************/
/* FLTGetTopBBOX */
/* */
/* Return the "top" BBOX if there's a unique one. */
/************************************************************************/
static int FLTGetTopBBOXInternal(FilterEncodingNode *psNode, FilterEncodingNode** ppsTopBBOX, int *pnCount)
{
if (psNode->pszValue && strcasecmp(psNode->pszValue, "BBOX") == 0) {
(*pnCount) ++;
if( *pnCount == 1 )
{
*ppsTopBBOX = psNode;
return TRUE;
}
*ppsTopBBOX = NULL;
return FALSE;
}
else if (psNode->pszValue && strcasecmp(psNode->pszValue, "AND") == 0) {
return FLTGetTopBBOXInternal(psNode->psLeftNode, ppsTopBBOX, pnCount) &&
FLTGetTopBBOXInternal(psNode->psRightNode, ppsTopBBOX, pnCount);
}
else
{
return TRUE;
}
}
return FLTLayerApplyPlainFilterToLayer(psNode, map, iLayerIndex);
static FilterEncodingNode* FLTGetTopBBOX(FilterEncodingNode *psNode)
{
int nCount = 0;
FilterEncodingNode* psTopBBOX = NULL;
FLTGetTopBBOXInternal(psNode, &psTopBBOX, &nCount);
return psTopBBOX;
}
/************************************************************************/
......@@ -637,12 +663,56 @@ int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
{
char *pszExpression =NULL;
int status =MS_FALSE;
layerObj* lp = GET_LAYER(map, iLayerIndex);
pszExpression = FLTGetCommonExpression(psNode, GET_LAYER(map, iLayerIndex));
if(map->debug == MS_DEBUGLEVEL_VVV)
msDebug("FLTLayerApplyPlainFilterToLayer(): %s\n", pszExpression);
pszExpression = FLTGetCommonExpression(psNode, lp);
if (pszExpression) {
status = FLTApplyFilterToLayerCommonExpression(map, iLayerIndex, pszExpression);
FilterEncodingNode* psTopBBOX;
rectObj rect = map->extent;
psTopBBOX = FLTGetTopBBOX(psNode);
if( psTopBBOX )
{
int can_remove_expression = MS_TRUE;
const char* pszEPSG = FLTGetBBOX(psNode, &rect);
if(pszEPSG && map->projection.numargs > 0) {
projectionObj sProjTmp;
msInitProjection(&sProjTmp);
/* Use the non EPSG variant since axis swapping is done in FLTDoAxisSwappingIfNecessary */
if (msLoadProjectionString(&sProjTmp, pszEPSG) == 0) {
rectObj oldRect = rect;
msProjectRect(&sProjTmp, &map->projection, &rect);
/* If reprojection is involved, do not remove the expression */
if( rect.minx != oldRect.minx ||
rect.miny != oldRect.miny ||
rect.maxx != oldRect.maxx ||
rect.maxy != oldRect.maxy )
{
can_remove_expression = MS_FALSE;
}
}
msFreeProjection(&sProjTmp);
}
/* Small optimization: if the query is just a BBOX, then do a */
/* msQueryByRect() */
if( psTopBBOX == psNode && can_remove_expression )
{