[mapserver-commits] r10781 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Tue Dec 7 10:05:26 EST 2010
Author: tbonfort
Date: 2010-12-07 07:05:26 -0800 (Tue, 07 Dec 2010)
New Revision: 10781
Modified:
trunk/mapserver/HISTORY.TXT
trunk/mapserver/mapagg.cpp
trunk/mapserver/mapcairo.c
trunk/mapserver/mapdraw.c
trunk/mapserver/mapdummyrenderer.c
trunk/mapserver/mapgd.c
trunk/mapserver/mapgraticule.c
trunk/mapserver/mapkml.cpp
trunk/mapserver/mapogl.cpp
trunk/mapserver/mapprimitive.c
trunk/mapserver/mapserver.h
trunk/mapserver/maptemplate.c
Log:
Add support for per layer tuning of the shape to pixel conversion (SIMPLIFY, ROUND, SNAPTOGRID, FULLRESOLUTION)
Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/HISTORY.TXT 2010-12-07 15:05:26 UTC (rev 10781)
@@ -13,6 +13,8 @@
Current Version (SVN trunk):
----------------------------
+- Add support for per layer tuning of the shape to pixel conversion (SIMPLIFY, ROUND,
+ SNAPTOGRID, FULLRESOLUTION)
- Fixed: Memory allocation results should always be checked (#3559)
Modified: trunk/mapserver/mapagg.cpp
===================================================================
--- trunk/mapserver/mapagg.cpp 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapagg.cpp 2010-12-07 15:05:26 UTC (rev 10781)
@@ -789,6 +789,7 @@
renderer->supports_pixel_buffer = 1;
renderer->use_imagecache = 0;
renderer->supports_clipping = 0;
+ renderer->default_transform_mode = MS_TRANSFORM_SIMPLIFY;
agg2InitCache(&(MS_RENDERER_CACHE(renderer)));
renderer->cleanup = agg2Cleanup;
@@ -825,7 +826,6 @@
renderer->startLayer = &agg2StartNewLayer;
renderer->endLayer = &agg2CloseNewLayer;
- renderer->transformShape = &msTransformShapeToPixel;
renderer->freeImage = &agg2FreeImage;
renderer->freeSymbol = &agg2FreeSymbol;
renderer->cleanup = agg2Cleanup;
Modified: trunk/mapserver/mapcairo.c
===================================================================
--- trunk/mapserver/mapcairo.c 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapcairo.c 2010-12-07 15:05:26 UTC (rev 10781)
@@ -790,6 +790,7 @@
#ifdef USE_CAIRO
renderer->supports_pixel_buffer=1;
renderer->supports_transparent_layers = 0;
+ renderer->default_transform_mode = MS_TRANSFORM_SIMPLIFY;
initializeCache(&MS_RENDERER_CACHE(renderer));
renderer->startLayer = startLayerRasterCairo;
renderer->endLayer = closeLayerRasterCairo;
@@ -798,8 +799,6 @@
renderer->saveImage=&saveImageCairo;
renderer->getRasterBufferHandle=&getRasterBufferHandleCairo;
renderer->getRasterBufferCopy=&getRasterBufferCopyCairo;
-
- renderer->transformShape=&msTransformShapeToPixel;
renderer->renderPolygon=&renderPolygonCairo;
renderer->renderGlyphs=&renderGlyphsCairo;
renderer->freeImage=&freeImageCairo;
@@ -827,6 +826,7 @@
renderer->use_imagecache=0;
renderer->supports_pixel_buffer=0;
renderer->supports_transparent_layers = 1;
+ renderer->default_transform_mode = MS_TRANSFORM_SIMPLIFY;
initializeCache(&MS_RENDERER_CACHE(renderer));
renderer->startLayer = startLayerVectorCairo;
renderer->endLayer = closeLayerVectorCairo;
@@ -834,7 +834,6 @@
renderer->createImage=&createImageCairo;
renderer->saveImage=&saveImageCairo;
renderer->getRasterBufferHandle=&getRasterBufferHandleCairo;
- renderer->transformShape=&msTransformShapeToPixel;
renderer->renderPolygon=&renderPolygonCairo;
renderer->renderGlyphs=&renderGlyphsCairo;
renderer->freeImage=&freeImageCairo;
Modified: trunk/mapserver/mapdraw.c
===================================================================
--- trunk/mapserver/mapdraw.c 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapdraw.c 2010-12-07 15:05:26 UTC (rev 10781)
@@ -1470,7 +1470,7 @@
msInitShape(&annoshape);
msCopyShape(shape, &annoshape);
- msTransformShape(&annoshape, map->extent, map->cellsize, image, MS_SIMPLIFY_DEFAULT);
+ msTransformShape(&annoshape, map->extent, map->cellsize, image);
if(layer->class[c]->label.anglemode == MS_FOLLOW ) {
annopaths = msPolylineLabelPath(map,image,&annoshape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, ®ularLines, &numRegularLines);
@@ -1484,7 +1484,7 @@
if(layer->transform == MS_TRUE) {
msClipPolylineRect(shape, cliprect);
if(shape->numlines == 0) return(MS_SUCCESS);
- msTransformShape(shape, map->extent, map->cellsize, image, MS_SIMPLIFY_DEFAULT);
+ msTransformShape(shape, map->extent, map->cellsize, image);
} else
msOffsetShapeRelativeTo(shape, layer);
@@ -1653,7 +1653,7 @@
if(layer->transform == MS_TRUE) {
msClipPolygonRect(shape, cliprect);
if(shape->numlines == 0) return(MS_SUCCESS);
- msTransformShape(shape, map->extent, map->cellsize, image, MS_SIMPLIFY_DEFAULT);
+ msTransformShape(shape, map->extent, map->cellsize, image);
} else
msOffsetShapeRelativeTo(shape, layer);
@@ -1795,7 +1795,7 @@
msInitShape(&annoshape);
msCopyShape(shape, &annoshape);
- msTransformShape(&annoshape, map->extent, map->cellsize, image, MS_SIMPLIFY_DEFAULT);
+ msTransformShape(&annoshape, map->extent, map->cellsize, image);
if(layer->class[c]->label.anglemode == MS_FOLLOW) {
annopaths = msPolylineLabelPath(map,image,&annoshape, minfeaturesize, &(map->fontset), shape->text, &(layer->class[c]->label), layer->scalefactor, &numpaths, ®ularLines, &numRegularLines);
@@ -1827,9 +1827,9 @@
msFreeShape(&nonClippedShape);
return(MS_SUCCESS);
}
- msTransformShape(shape, map->extent, map->cellsize, image, MS_SIMPLIFY_DEFAULT);
+ msTransformShape(shape, map->extent, map->cellsize, image);
if(hasGeomTransform)
- msTransformShape(&nonClippedShape, map->extent, map->cellsize, image, MS_SIMPLIFY_DEFAULT);
+ msTransformShape(&nonClippedShape, map->extent, map->cellsize, image);
} else {
msOffsetShapeRelativeTo(shape, layer);
}
@@ -2045,13 +2045,13 @@
msFreeShape(&nonClippedShape);
return(MS_SUCCESS);
}
- msTransformShape(shape, map->extent, map->cellsize, image, MS_SIMPLIFY_DEFAULT);
+ msTransformShape(shape, map->extent, map->cellsize, image);
if(hasGeomTransform)
- msTransformShape(&nonClippedShape, map->extent, map->cellsize, image, MS_SIMPLIFY_DEFAULT);
+ msTransformShape(&nonClippedShape, map->extent, map->cellsize, image);
} else {
msOffsetShapeRelativeTo(shape, layer);
if(hasGeomTransform)
- msTransformShape(&nonClippedShape, map->extent, map->cellsize, image, MS_SIMPLIFY_DEFAULT);
+ msTransformShape(&nonClippedShape, map->extent, map->cellsize, image);
}
for(s=0; s<layer->class[c]->numstyles; s++) {
@@ -2613,7 +2613,23 @@
if (image)
{
if( MS_RENDERER_PLUGIN(image->format) ) {
- MS_IMAGE_RENDERER(image)->startLayer(image, map, layer);
+ char *approximation_scale = msLayerGetProcessingKey( layer, "APPROXIMATION_SCALE" );
+ if(approximation_scale) {
+ if(!strncasecmp(approximation_scale,"ROUND",5)) {
+ MS_IMAGE_RENDERER(image)->transform_mode = MS_TRANSFORM_ROUND;
+ } else if(!strncasecmp(approximation_scale,"FULL",4)) {
+ MS_IMAGE_RENDERER(image)->transform_mode = MS_TRANSFORM_FULLRESOLUTION;
+ } else if(!strncasecmp(approximation_scale,"SIMPLIFY",8)) {
+ MS_IMAGE_RENDERER(image)->transform_mode = MS_TRANSFORM_SIMPLIFY;
+ } else {
+ MS_IMAGE_RENDERER(image)->transform_mode = MS_TRANSFORM_SNAPTOGRID;
+ MS_IMAGE_RENDERER(image)->approximation_scale = atof(approximation_scale);
+ }
+ } else {
+ MS_IMAGE_RENDERER(image)->transform_mode = MS_IMAGE_RENDERER(image)->default_transform_mode;
+ MS_IMAGE_RENDERER(image)->approximation_scale = MS_IMAGE_RENDERER(image)->default_approximation_scale;
+ }
+ MS_IMAGE_RENDERER(image)->startLayer(image, map, layer);
}
else if( MS_RENDERER_IMAGEMAP(image->format) )
msImageStartLayerIM(map, layer, image);
Modified: trunk/mapserver/mapdummyrenderer.c
===================================================================
--- trunk/mapserver/mapdummyrenderer.c 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapdummyrenderer.c 2010-12-07 15:05:26 UTC (rev 10781)
@@ -200,11 +200,6 @@
return MS_FAILURE;
}
-int transformShapeDummy(shapeObj *shape, rectObj extend, double cellsize, enum MS_SIMPLIFY_MODE simplify) {
- msSetError(MS_RENDERERERR,"transformShape not implemented","transformShape()");
- return MS_FAILURE;
-}
-
int freeImageDummy(imageObj *image) {
msSetError(MS_RENDERERERR,"freeImage not implemented","freeImage()");
return MS_FAILURE;
@@ -232,6 +227,7 @@
renderer->supports_clipping = 0;
renderer->supports_bitmap_fonts = 0;
renderer->renderer_data = NULL;
+ renderer->transform_mode = MS_TRANSFORM_SIMPLIFY;
renderer->startLayer = &startLayerDummy;
renderer->endLayer = &endLayerDummy;
renderer->renderLine=&renderLineDummy;
@@ -240,7 +236,6 @@
renderer->getRasterBufferHandle=&getRasterBufferHandleDummy;
renderer->getRasterBufferCopy=getRasterBufferCopyDummy;
renderer->initializeRasterBuffer=initializeRasterBufferDummy;
- renderer->transformShape=&msTransformShapeToPixel;
renderer->renderPolygon=&renderPolygonDummy;
renderer->renderGlyphs=&renderGlyphsDummy;
renderer->renderBitmapGlyphs = &renderGlyphsDummy;
Modified: trunk/mapserver/mapgd.c
===================================================================
--- trunk/mapserver/mapgd.c 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapgd.c 2010-12-07 15:05:26 UTC (rev 10781)
@@ -910,6 +910,7 @@
renderer->supports_pixel_buffer=1;
renderer->supports_transparent_layers = 0;
renderer->supports_bitmap_fonts = 1;
+ renderer->default_transform_mode = MS_TRANSFORM_ROUND;
for(i=0;i<5;i++) {
gdFontPtr f = msGetBitmapFont(i);
@@ -928,8 +929,6 @@
renderer->getRasterBufferCopy = &getRasterBufferCopyGD;
renderer->initializeRasterBuffer = initializeRasterBufferGD;
renderer->loadImageFromFile = msLoadGDRasterBufferFromFile;
-
- renderer->transformShape = &msTransformShapeToPixel;
renderer->renderPolygon = &renderPolygonGD;
renderer->renderGlyphs = &renderGlyphsGD;
renderer->renderBitmapGlyphs = &renderBitmapGlyphsGD;
Modified: trunk/mapserver/mapgraticule.c
===================================================================
--- trunk/mapserver/mapgraticule.c 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapgraticule.c 2010-12-07 15:05:26 UTC (rev 10781)
@@ -698,12 +698,7 @@
msClipPolylineRect(&shapegrid, cliprect);
- if(MS_RENDERER_PLUGIN(map->outputformat)) {
- rendererVTableObj *renderer = MS_MAP_RENDERER(map);
- renderer->transformShape(&shapegrid, map->extent, map->cellsize, MS_SIMPLIFY_DEFAULT);
- } else {
- msTransformShapeToPixel(&shapegrid, map->extent, map->cellsize, MS_SIMPLIFY_DEFAULT);
- }
+ msTransformShapeToPixelRound(&shapegrid, map->extent, map->cellsize);
@@ -1100,11 +1095,7 @@
#endif
if(pLayer->transform) {
- if(MS_RENDERER_PLUGIN(pLayer->map->outputformat)) {
- MS_MAP_RENDERER(pLayer->map)->transformShape(pShape, pLayer->map->extent, pLayer->map->cellsize, MS_SIMPLIFY_DEFAULT);
- } else {
- msTransformShapeToPixel(pShape, pLayer->map->extent, pLayer->map->cellsize, MS_SIMPLIFY_DEFAULT);
- }
+ msTransformShapeToPixelRound(pShape, pLayer->map->extent, pLayer->map->cellsize);
}
if(msGetLabelSize(pLayer->map, &pLayer->class[0]->label,pShape->text, size,&rectLabel,NULL) != MS_SUCCESS)
Modified: trunk/mapserver/mapkml.cpp
===================================================================
--- trunk/mapserver/mapkml.cpp 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapkml.cpp 2010-12-07 15:05:26 UTC (rev 10781)
@@ -165,11 +165,6 @@
return renderer->closeNewLayer(img, layer);
}
-int msTransformShapeKml(shapeObj *shape, rectObj extend, double cellsize, enum MS_SIMPLIFY_MODE simplifyMode)
-{
- return MS_SUCCESS;
-}
-
int msFreeImageKml(imageObj *image)
{
KmlRenderer* renderer = getKmlRenderer(image);
@@ -223,14 +218,13 @@
renderer->supports_bitmap_fonts = 0;
renderer->supports_clipping = 0;
renderer->use_imagecache = 0;
-
+ renderer->default_transform_mode = MS_TRANSFORM_NONE;
renderer->startLayer = msStartNewLayerKml;
renderer->endLayer = msCloseNewLayerKml;
renderer->renderLine=&msRenderLineKml;
renderer->createImage=&msCreateImageKml;
renderer->saveImage=&msSaveImageKml;
- renderer->transformShape=&msTransformShapeKml;
renderer->renderPolygon=&msRenderPolygonKml;
renderer->renderGlyphs=&msRenderGlyphsKml;
renderer->renderEllipseSymbol = &msRenderEllipseSymbolKml;
Modified: trunk/mapserver/mapogl.cpp
===================================================================
--- trunk/mapserver/mapogl.cpp 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapogl.cpp 2010-12-07 15:05:26 UTC (rev 10781)
@@ -201,7 +201,7 @@
renderer->supports_clipping = 0;
renderer->use_imagecache = 0;
renderer->supports_bitmap_fonts = 0;
-
+ renderer->transform_mode = MS_TRANSFORM_SIMPLIFY;
renderer->startLayer = msStartLayerOgl;
renderer->endLayer = msEndLayerOgl;
@@ -221,7 +221,6 @@
renderer->renderPolygonTiled = &msDrawPolygonTiledOgl;
renderer->renderLineTiled = &msDrawLineTiledOgl;
- renderer->transformShape=&msTransformShapeToPixel;
renderer->getTruetypeTextBBox = &msGetTruetypeTextBBoxOgl;
renderer->getRasterBufferHandle = msGetRasterBufferHandleOgl;
Modified: trunk/mapserver/mapprimitive.c
===================================================================
--- trunk/mapserver/mapprimitive.c 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapprimitive.c 2010-12-07 15:05:26 UTC (rev 10781)
@@ -816,89 +816,13 @@
return;
}
-/**
- * Generic function to transorm the shape coordinates to output coordinates
- */
-void msTransformShape(shapeObj *shape, rectObj extent, double cellsize,
- imageObj *image, enum MS_SIMPLIFY_MODE simplify_mode)
+void msTransformShapeSimplify(shapeObj *shape, rectObj extent, double cellsize)
{
- if (image != NULL && MS_RENDERER_PLUGIN(image->format)) {
- image->format->vtable->transformShape(shape, extent, cellsize, simplify_mode);
-
- return;
- }
-#ifdef USE_MING_FLASH
- if (image != NULL && MS_RENDERER_SWF(image->format) )
- {
- if (strcasecmp(msGetOutputFormatOption(image->format, "FULL_RESOLUTION",""),
- "FALSE") == 0)
- msTransformShapeToPixel(shape, extent, cellsize, simplify_mode);
- else
- msTransformShapeSWF(shape, extent, cellsize);
-
-
- return;
- }
-#endif
- msTransformShapeToPixel(shape, extent, cellsize, simplify_mode);
-}
-
-int msTransformShapeToPixel(shapeObj *shape, rectObj extent, double cellsize, enum MS_SIMPLIFY_MODE simplifyMode)
-{
- if(shape->numlines == 0) return;
- switch(simplifyMode) {
- case MS_SIMPLIFY_ROUND:
- return msTransformShapeToPixelIntegerPrecision(shape,extent,cellsize);
- break;
- case MS_SIMPLIFY_NAIVE:
- case MS_SIMPLIFY_NONE:
- case MS_SIMPLIFY_DEFAULT:
- default:
- return msTransformShapeToPixelDoublePrecision(shape,extent,cellsize);
- }
-
-}
-
-/*
-** converts from map coordinates to image coordinates
-*/
-int msTransformShapeToPixelIntegerPrecision(shapeObj *shape, rectObj extent, double cellsize)
-{
- int i,j,k; /* loop counters */
- double inv_cs = 1.0 / cellsize; /* invert and multiply much faster */
-
- if(shape->numlines == 0) return; /* nothing to transform */
-
- if(shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON) { /* remove duplicate vertices */
- for(i=0; i<shape->numlines; i++) { /* for each part */
- shape->line[i].point[0].x = MS_MAP2IMAGE_X_IC(shape->line[i].point[0].x, extent.minx, inv_cs);
- shape->line[i].point[0].y = MS_MAP2IMAGE_Y_IC(shape->line[i].point[0].y, extent.maxy, inv_cs);
- for(j=1, k=1; j < shape->line[i].numpoints; j++ ) {
- shape->line[i].point[k].x = MS_MAP2IMAGE_X_IC(shape->line[i].point[j].x, extent.minx, inv_cs);
- shape->line[i].point[k].y = MS_MAP2IMAGE_Y_IC(shape->line[i].point[j].y, extent.maxy, inv_cs);
- if(shape->line[i].point[k].x!=shape->line[i].point[k-1].x || shape->line[i].point[k].y!=shape->line[i].point[k-1].y)
- k++;
- }
- shape->line[i].numpoints = k; /* save actual number kept */
- }
- } else { /* points or untyped shapes */
- for(i=0; i<shape->numlines; i++) { /* for each part */
- for(j=1; j < shape->line[i].numpoints; j++ ) {
- shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC(shape->line[i].point[j].x, extent.minx, inv_cs);
- shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC(shape->line[i].point[j].y, extent.maxy, inv_cs);
- }
- }
- }
-}
-
-int msTransformShapeToPixelDoublePrecision(shapeObj *shape, rectObj extent, double cellsize)
-{
int i,j,k,beforelast; /* loop counters */
double dx,dy;
double inv_cs = 1.0 / cellsize; /* invert and multiply much faster */
+ if(shape->numlines == 0) return; /* nothing to transform */
pointObj *point;
- if(shape->numlines == 0) return; /* nothing to transform */
-
if(shape->type == MS_SHAPE_LINE) {
/*
* loop through the shape's lines, and do naive simplification
@@ -937,7 +861,7 @@
}
//skip degenerate line once more
if(shape->line[i].numpoints<2)
- shape->line[i].numpoints=0;
+ shape->line[i].numpoints=0;
}
}
else if(shape->type == MS_SHAPE_POLYGON) {
@@ -986,8 +910,158 @@
}
}
+/**
+ * Generic function to transorm the shape coordinates to output coordinates
+ */
+void msTransformShape(shapeObj *shape, rectObj extent, double cellsize, imageObj *image)
+{
+ if (image != NULL && MS_RENDERER_PLUGIN(image->format)) {
+ rendererVTableObj *renderer = MS_IMAGE_RENDERER(image);
+ if(renderer->transform_mode == MS_TRANSFORM_SNAPTOGRID) {
+ msTransformShapeToPixelSnapToGrid(shape, extent, cellsize, renderer->approximation_scale);
+ } else if(renderer->transform_mode == MS_TRANSFORM_SIMPLIFY) {
+ msTransformShapeSimplify(shape, extent, cellsize);
+ } else if(renderer->transform_mode == MS_TRANSFORM_ROUND) {
+ msTransformShapeToPixelRound(shape, extent, cellsize);
+ } else if(renderer->transform_mode == MS_TRANSFORM_FULLRESOLUTION) {
+ msTransformShapeToPixelDoublePrecision(shape,extent,cellsize);
+ } else if(renderer->transform_mode == MS_TRANSFORM_NONE) {
+ /* nothing to do */
+ return;
+ }
+ /* unknown, do nothing */
+ return;
+ }
+#ifdef USE_MING_FLASH
+ if (image != NULL && MS_RENDERER_SWF(image->format) )
+ {
+ if (strcasecmp(msGetOutputFormatOption(image->format, "FULL_RESOLUTION",""),
+ "FALSE") == 0)
+ msTransformShapeToPixelRound(shape, extent, cellsize);
+ else
+ msTransformShapeSWF(shape, extent, cellsize);
+
+ return;
+ }
+#endif
+ msTransformShapeToPixelRound(shape, extent, cellsize);
+}
+void msTransformShapeToPixelSnapToGrid(shapeObj *shape, rectObj extent, double cellsize, double grid_resolution)
+{
+ int i,j,k; /* loop counters */
+ double inv_cs;
+ if(shape->numlines == 0) return;
+ inv_cs = 1.0 / cellsize; /* invert and multiply much faster */
+
+
+ if(shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON) { /* remove duplicate vertices */
+ for(i=0; i<shape->numlines; i++) { /* for each part */
+ int snap = 1;
+ double x0,y0,x1,y1,x2,y2;
+ /*do a quick heuristic: will we risk having a degenerate shape*/
+ if(shape->type == MS_SHAPE_LINE) {
+ /*a line is degenerate if it has a single pixel. we check that the first and last pixel are different*/
+ x0 = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[0].x, extent.minx, inv_cs, grid_resolution);
+ y0 = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[0].y, extent.maxy, inv_cs, grid_resolution);
+ x1 = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[shape->line[i].numpoints-1].x, extent.minx, inv_cs, grid_resolution);
+ y1 = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[shape->line[i].numpoints-1].y, extent.maxy, inv_cs, grid_resolution);
+ if(x0 == x1 && y0 == y1) {
+ snap = 0;
+ }
+ } else if(shape->type == MS_SHAPE_POLYGON) {
+ x0 = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[0].x, extent.minx, inv_cs, grid_resolution);
+ y0 = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[0].y, extent.maxy, inv_cs, grid_resolution);
+ x1 = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[shape->line[i].numpoints/3].x, extent.minx, inv_cs, grid_resolution);
+ y1 = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[shape->line[i].numpoints/3].y, extent.maxy, inv_cs, grid_resolution);
+ x2 = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[shape->line[i].numpoints/3*2].x, extent.minx, inv_cs, grid_resolution);
+ y2 = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[shape->line[i].numpoints/3*2].y, extent.maxy, inv_cs, grid_resolution);
+ if((x0 == x1 && y0 == y1) ||
+ (x0 == x2 && y0 == y2) ||
+ (x1 == x2 && y1 == y2)) {
+ snap = 0;
+ }
+ }
+ if(snap) {
+ shape->line[i].point[0].x = x0;
+ shape->line[i].point[0].y = y0;
+ for(j=1, k=1; j < shape->line[i].numpoints; j++ ) {
+ shape->line[i].point[k].x = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[j].x, extent.minx, inv_cs, grid_resolution);
+ shape->line[i].point[k].y = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[j].y, extent.maxy, inv_cs, grid_resolution);
+ if(shape->line[i].point[k].x!=shape->line[i].point[k-1].x || shape->line[i].point[k].y!=shape->line[i].point[k-1].y)
+ k++;
+ }
+ shape->line[i].numpoints=k;
+ } else {
+ if(shape->type == MS_SHAPE_LINE) {
+ shape->line[i].point[0].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[0].x, extent.minx, inv_cs);
+ shape->line[i].point[0].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[0].y, extent.maxy, inv_cs);
+ shape->line[i].point[1].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[shape->line[i].numpoints-1].x, extent.minx, inv_cs);
+ shape->line[i].point[1].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[shape->line[i].numpoints-1].y, extent.maxy, inv_cs);
+ shape->line[i].numpoints = 2;
+ } else {
+ for(j=0; j < shape->line[i].numpoints; j++ ) {
+ shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[j].x, extent.minx, inv_cs);
+ shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[j].y, extent.maxy, inv_cs);
+ }
+ }
+ }
+ }
+ } else { /* points or untyped shapes */
+ for(i=0; i<shape->numlines; i++) { /* for each part */
+ for(j=1; j < shape->line[i].numpoints; j++ ) {
+ shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[j].x, extent.minx, inv_cs);
+ shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[j].y, extent.maxy, inv_cs);
+ }
+ }
+ }
+
+}
+
+void msTransformShapeToPixelRound(shapeObj *shape, rectObj extent, double cellsize)
+{
+ int i,j,k; /* loop counters */
+ double inv_cs;
+ if(shape->numlines == 0) return;
+ inv_cs = 1.0 / cellsize; /* invert and multiply much faster */
+ if(shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON) { /* remove duplicate vertices */
+ for(i=0; i<shape->numlines; i++) { /* for each part */
+ shape->line[i].point[0].x = MS_MAP2IMAGE_X_IC(shape->line[i].point[0].x, extent.minx, inv_cs);;
+ shape->line[i].point[0].y = MS_MAP2IMAGE_Y_IC(shape->line[i].point[0].y, extent.maxy, inv_cs);
+ for(j=1, k=1; j < shape->line[i].numpoints; j++ ) {
+ shape->line[i].point[k].x = MS_MAP2IMAGE_X_IC(shape->line[i].point[j].x, extent.minx, inv_cs);
+ shape->line[i].point[k].y = MS_MAP2IMAGE_Y_IC(shape->line[i].point[j].y, extent.maxy, inv_cs);
+ if(shape->line[i].point[k].x!=shape->line[i].point[k-1].x || shape->line[i].point[k].y!=shape->line[i].point[k-1].y)
+ k++;
+ }
+ shape->line[i].numpoints=k;
+ }
+ } else { /* points or untyped shapes */
+ for(i=0; i<shape->numlines; i++) { /* for each part */
+ for(j=1; j < shape->line[i].numpoints; j++ ) {
+ shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC(shape->line[i].point[j].x, extent.minx, inv_cs);
+ shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC(shape->line[i].point[j].y, extent.maxy, inv_cs);
+ }
+ }
+ }
+
+}
+
+void msTransformShapeToPixelDoublePrecision(shapeObj *shape, rectObj extent, double cellsize)
+{
+ int i,j; /* loop counters */
+ double inv_cs = 1.0 / cellsize; /* invert and multiply much faster */
+ for(i=0; i<shape->numlines; i++) {
+ for(j=0;j<shape->line[i].numpoints;j++) {
+ shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[j].x, extent.minx, inv_cs);
+ shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[j].y, extent.maxy, inv_cs);
+ }
+ }
+}
+
+
+
/*
** Converts from map coordinates to image coordinates
*/
Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/mapserver.h 2010-12-07 15:05:26 UTC (rev 10781)
@@ -395,12 +395,15 @@
#define MS_IMAGE2MAP_X(x,minx,cx) (minx + cx*x)
#define MS_IMAGE2MAP_Y(y,maxy,cy) (maxy - cy*y)
-/* this version of MS_MAP2IMAGE takes 1/cellsize and is much faster */
+/* these versions of MS_MAP2IMAGE takes 1/cellsize and is much faster */
#define MS_MAP2IMAGE_X_IC(x,minx,icx) (MS_NINT((x - minx)*icx))
#define MS_MAP2IMAGE_Y_IC(y,maxy,icy) (MS_NINT((maxy - y)*icy))
#define MS_MAP2IMAGE_X_IC_DBL(x,minx,icx) ((x - minx)*icx)
#define MS_MAP2IMAGE_Y_IC_DBL(y,maxy,icy) ((maxy - y)*icy)
+
+#define MS_MAP2IMAGE_X_IC_SNAP(x,minx,icx,res) ((MS_NINT((x - minx)*icx*res))/(res))
+#define MS_MAP2IMAGE_Y_IC_SNAP(y,maxy,icy,res) ((MS_NINT((maxy - y)*icy*res))/(res))
/* For CARTO symbols */
#define MS_PI 3.14159265358979323846
@@ -451,11 +454,12 @@
#define MS_FILE_DEFAULT MS_FILE_MAP
/* coordinate to pixel simplification modes, used in msTransformShape */
-enum MS_SIMPLIFY_MODE {
- MS_SIMPLIFY_DEFAULT, /* use renderer default */
- MS_SIMPLIFY_NONE, /* precise conversion */
- MS_SIMPLIFY_ROUND, /* round to closest pixel, removing identical points */
- MS_SIMPLIFY_NAIVE /* find better name */
+enum MS_TRANSFORM_MODE {
+ MS_TRANSFORM_NONE, /* no geographic to pixel transformation */
+ MS_TRANSFORM_ROUND, /* round to integer, might create degenerate geometries (used for GD)*/
+ MS_TRANSFORM_SNAPTOGRID, /* snap to a grid, should be user configurable in the future*/
+ MS_TRANSFORM_FULLRESOLUTION, /* keep full resolution */
+ MS_TRANSFORM_SIMPLIFY /* keep full resolution */
};
#ifndef SWIG
@@ -1921,16 +1925,17 @@
MS_DLL_EXPORT void msRectToPolygon(rectObj rect, shapeObj *poly);
MS_DLL_EXPORT void msClipPolylineRect(shapeObj *shape, rectObj rect);
MS_DLL_EXPORT void msClipPolygonRect(shapeObj *shape, rectObj rect);
-MS_DLL_EXPORT void msTransformShape(shapeObj *shape, rectObj extent, double cellsize, imageObj *image, enum MS_SIMPLIFY_MODE simplifyMode);
+MS_DLL_EXPORT void msTransformShape(shapeObj *shape, rectObj extent, double cellsize, imageObj *image);
MS_DLL_EXPORT void msTransformPoint(pointObj *point, rectObj *extent, double cellsize, imageObj *image);
MS_DLL_EXPORT void msOffsetPointRelativeTo(pointObj *point, layerObj *layer);
MS_DLL_EXPORT void msOffsetShapeRelativeTo(shapeObj *shape, layerObj *layer);
-MS_DLL_EXPORT int msTransformShapeToPixel(shapeObj *shape, rectObj extent, double cellsize, enum MS_SIMPLIFY_MODE simplify_mode);
-MS_DLL_EXPORT int msTransformShapeToPixelIntegerPrecision(shapeObj *shape, rectObj extent, double cellsize);
-MS_DLL_EXPORT int msTransformShapeToPixelDoublePrecision(shapeObj *shape, rectObj extent, double cellsize);
+MS_DLL_EXPORT void msTransformShapeSimplify(shapeObj *shape, rectObj extent, double cellsize);
+MS_DLL_EXPORT void msTransformShapeToPixelSnapToGrid(shapeObj *shape, rectObj extent, double cellsize, double grid_resolution);
+MS_DLL_EXPORT void msTransformShapeToPixelRound(shapeObj *shape, rectObj extent, double cellsize);
+MS_DLL_EXPORT void msTransformShapeToPixelDoublePrecision(shapeObj *shape, rectObj extent, double cellsize);
MS_DLL_EXPORT void msTransformPixelToShape(shapeObj *shape, rectObj extent, double cellsize);
MS_DLL_EXPORT void msImageCartographicPolyline(gdImagePtr im, shapeObj *p, styleObj *style, symbolObj *symbol, int c, double size, double scalefactor);
@@ -2563,6 +2568,10 @@
int supports_clipping;
int supports_bitmap_fonts;
int use_imagecache;
+ enum MS_TRANSFORM_MODE default_transform_mode;
+ enum MS_TRANSFORM_MODE transform_mode;
+ double default_approximation_scale;
+ double approximation_scale;
void *renderer_data;
@@ -2632,7 +2641,6 @@
int (*setClip)(imageObj *img, rectObj clipRect);
int (*resetClip)(imageObj *img);
- int (*transformShape)(shapeObj *shape, rectObj extend, double cellsize, enum MS_SIMPLIFY_MODE simplify);
int (*freeImage)(imageObj *image);
int (*freeSymbol)(symbolObj *symbol);
int (*cleanup)(void *renderer_data);
Modified: trunk/mapserver/maptemplate.c
===================================================================
--- trunk/mapserver/maptemplate.c 2010-12-07 03:53:20 UTC (rev 10780)
+++ trunk/mapserver/maptemplate.c 2010-12-07 15:05:26 UTC (rev 10781)
@@ -1610,7 +1610,7 @@
msClipPolylineRect(shape, layer->map->extent);
- msTransformShapeToPixel(shape, layer->map->extent, cellsize, MS_SIMPLIFY_DEFAULT);
+ msTransformShapeToPixelRound(shape, layer->map->extent, cellsize);
}
else
msOffsetShapeRelativeTo(shape, layer);
@@ -1653,7 +1653,7 @@
if (clip_to_map)
msClipPolygonRect(shape, layer->map->extent);
- msTransformShapeToPixel(shape, layer->map->extent, cellsize, MS_SIMPLIFY_DEFAULT);
+ msTransformShapeToPixelRound(shape, layer->map->extent, cellsize);
}
else
msOffsetShapeRelativeTo(shape, layer);
@@ -1738,7 +1738,7 @@
msClipPolylineRect(&tShape, layer->map->extent);
- msTransformShapeToPixel(&tShape, layer->map->extent, layer->map->cellsize, MS_SIMPLIFY_DEFAULT);
+ msTransformShapeToPixelRound(&tShape, layer->map->extent, layer->map->cellsize);
} else if(projectionString) {
projectionObj projection;
@@ -2046,7 +2046,7 @@
return(MS_FAILURE);
break;
}
- msTransformShapeToPixel(&tShape, layer->map->extent, layer->map->cellsize, MS_SIMPLIFY_DEFAULT);
+ msTransformShapeToPixelRound(&tShape, layer->map->extent, layer->map->cellsize);
#ifdef USE_GEOS
if(buffer != 0 && bufferUnits == MS_PIXELS) {
More information about the mapserver-commits
mailing list