ThinkGeo.com    |     Documentation    |     Premium Support

PointStyle Scaling High DPI Canvas

I'm printing PDFs using PdfSharp and XGraphics.  I started out by using the provided examples but my PDFs were coming out to be way too large in file size to be useful (since it was all vector data).  Average size was about 30MB.  I decided I'd try to generate a high-resolution (300dpi) image and force feed that to the PdfSharp.  It worked out much better.  However, I have a problem... my PointStyle are not scaling.  Everything looks great except I have very tiny points for my PointStyle and IconStyle.  LineStyle and AreaStyle are fine.  Any ideas on what I could do to have these come out properly?


 



 


 Any help/tips would be appreciated...


Thanks,


Abner




public void RaiseCallbackEvent( string ea )
{
string[] arguments = ea.Split( '|' );

if ( arguments.GetLength( 0 ) < 2 )
{
callbackResult = "ERROR: Could not acquire active layer list.";
return;
}

string[] bounds = arguments[0].Split( ',' );
string[] overlays = arguments[1].Split( ',' );

GdiPlusGeoCanvas Canvas = new GdiPlusGeoCanvas( );

PdfDocument document = new PdfDocument( );
PdfPage page = document.AddPage( );

page.Orientation = PageOrientation.Landscape;

GeoSolidBrush br = (GeoSolidBrush) Map.MapBackground.BackgroundBrush;

Bitmap MapBit = new Bitmap( 3200, 2400 );
MapBit.SetResolution( 300, 300 );

XGraphics gfx = XGraphics.FromPdfPage( page );

Graphics gf = Graphics.FromImage( MapBit );
gf.Clear( Color.FromArgb( (int) br.Color.AlphaComponent, (int) br.Color.RedComponent, (int) br.Color.GreenComponent, (int) br.Color.BlueComponent ) );

try
{
Map.CurrentExtent = new RectangleShape( double.Parse( bounds[0] ), double.Parse( bounds[1] ), double.Parse( bounds[2] ), double.Parse( bounds[3] ) );

Canvas.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
Canvas.Dpi = 300f;

Collection<SimpleCandidate> labelsInLayers = new Collection<SimpleCandidate>( );

for ( int i = 0; i < overlays.GetLength( 0 ); ++i )
{
if ( overlays[i] == "Legend" ) continue;

foreach ( Layer layer in ( (LayerOverlay) Map.CustomOverlays[overlays[i]] ).Layers )
{
//ExtentHelper.get

Canvas.BeginDrawing( MapBit, ExtentHelper.GetDrawingExtent( Map.CurrentExtent, (float) ( page.Width.Point ), (float) ( page.Height.Point ) ), GeographyUnit.Meter );
//Canvas.BeginDrawing( MapBit, Map.CurrentExtent, GeographyUnit.Meter );
layer.Open( );

layer.Draw( Canvas, labelsInLayers );
layer.Close( );
Canvas.EndDrawing( );
}
}

XImage img = XImage.FromGdiPlusImage( (System.Drawing.Image) MapBit );


string unique = System.Guid.NewGuid( ).ToString( ) + ".pdf";
string filename = Server.MapPath( "~/pdfexport/" + unique );

gfx.DrawImage( img, 10, 10 );
document.Save( filename );
document.Close( );

callbackResult = "pdfexport/" + unique;
}
catch ( Exception e )
{
callbackResult = "ERROR: " + e.Source + " " + e.Message;
}
}


Abner, 
  
 We have recreated your issue and it’s a bug in our product. It’s already in our schedule which might be fixed in our next version. Please keep an eye on our web site. 
  
 Any more questions please let me know. 
  
 Thanks, 
 Howard

Ok, thanks for the reply. 
  
 In the meantime, I think I can create a Custom PointStyle class that I can trick into thinking the Canvas is actually bigger than it is. 
  
 Maybe I wouldn’t have override much, except the DrawCore, and then multiply “something” X ( 300 / 72 ) so it would get bigger?  Whether “something” is the extent OR the size of the point, maybe you can recommend an idea.  It seems like the Pens are the right width so I think I just have to fool the PointStyle’s size.

Abner,



I think it's too much code to rewrite the PointStyle. If you are using our default symbol type, we recommend you set symbol size; for example:
pointStyle.SymbolSize = pointStyle.SymbolSize * (300 / 96); // default DPI equals 96.
Hope it makes sense.



Thanks,

Howard



I hooked it up... It works :) 




public class FlexIconStyle: IconStyle
{
public FlexIconStyle( )
: base( ) { }

public FlexIconStyle( GeoImage iconImage, string textColumnName, GeoFont textFont, GeoSolidBrush textSolidBrush )
: base( iconImage, textColumnName, textFont, textSolidBrush ) { }

public FlexIconStyle( string iconPathFilename, string textColumnName, GeoFont textFont, GeoSolidBrush textSolidBrush )
: base( iconPathFilename, textColumnName, textFont, textSolidBrush ) { }

protected override void DrawCore( IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers )
{
double Scale = this.IconImageScale;

this.IconImageScale = canvas.Dpi / 96F;

base.DrawCore( features, canvas, labelsInThisLayer, labelsInAllLayers );

this.IconImageScale = Scale;

}
}

public class FlexPointSymbolStyle: PointStyle
{
public FlexPointSymbolStyle( ) : base( ) { }
public FlexPointSymbolStyle( GeoImage image ) : base( image ) { }
public FlexPointSymbolStyle( GeoFont characterFont, int characterIndex, GeoSolidBrush characterSolidBrush ) : base( characterFont, characterIndex, characterSolidBrush ) { }
public FlexPointSymbolStyle( PointSymbolType symbolType, GeoSolidBrush symbolSolidBrush, int symbolSize ) : base( symbolType, symbolSolidBrush, symbolSize ) { }
public FlexPointSymbolStyle( PointSymbolType symbolType, GeoSolidBrush symbolSolidBrush, GeoPen symbolPen, int symbolSize ) : base( symbolType, symbolSolidBrush, symbolPen, symbolSize ) { }

protected override void DrawCore( IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers )
{
float Size = this.SymbolSize;

This.SymbolSize = Size * ( canvas.Dpi / 96F );

base.DrawCore( features, canvas, labelsInThisLayer, labelsInAllLayers );

this.SymbolSize = Size;
}
}






They vary slightly...



Thanks,

Abner



Abner, 
  
 Great; also thanks for your code. Please feel free to let me know if you have more questions. 
  
 Thanks, 
 Howard