Geospatial PDF and CAD measurements

XFINIUM.PDF 4.2 brings support for creating geospatial enabled PDF files and CAD measurements.

The new classes supporting these features are located in Xfinium.Pdf.Spatial namespace.

The first step in supporting these features is to create a viewport. A viewport (implemented by PdfViewport class) defines an area on the page that lets you specify a measurement scale for the its content. The measurement scale can be either rectilinear or geospatial and it is defined by viewport’s Measure property.

// Create the pdf document
PdfFixedDocument document = new PdfFixedDocument();
// Create a new page in the document
PdfPage page = document.Pages.Add();

// Create a viewport.
PdfViewport vp = new PdfViewport();
vp.Name = "Sample viewport";
// Viewport position is given in standard PDF coordinates because 
// the orientation of the viewport is given by the lower-left (ll) and
// upper-right (ur) corners.
PdfPoint ll = page.ConvertVisualPointToStandardPoint(new PdfPoint(50, 50));
PdfPoint ur = page.ConvertVisualPointToStandardPoint(new PdfPoint(550, 550));
vp.Bounds = new PdfStandardRectangle(ll, ur);

// Add the viewport to the page
page.Viewports = new PdfViewportCollection();
page.Viewports.Add(vp);
' Create the pdf document
Dim document As New PdfFixedDocument()
' Create a new page in the document
Dim page As PdfPage = document.Pages.Add()

' Create a viewport that matches the rectangle above.
Dim vp As New PdfViewport()
vp.Name = "Sample viewport"
' Viewport position is given in standard PDF coordinates because 
' the orientation of the viewport is given by the lower-left (ll) and
' upper-right (ur) corners.
Dim ll As PdfPoint = page.ConvertVisualPointToStandardPoint(New PdfPoint(50, 50))
Dim ur As PdfPoint = page.ConvertVisualPointToStandardPoint(New PdfPoint(550, 550))
vp.Bounds = New PdfStandardRectangle(ll, ur)

' Add the viewport to the page
page.Viewports = New PdfViewportCollection()
page.Viewports.Add(vp)

Rectilinear (CAD) viewports

Rectilinear viewports use a rectilinear measure (a PdfRectilinearMeasure object) to define its measurement scale. These viewports are used when PDF documents, such as those created by CAD software, contain graphics that are intended to represent real-world objects. Users of such documents often require information about the scale and units of measurement of the corresponding real-world objects and their relationship to units in PDF user space.

Rectilinear measures require one or more number formats (PdfNumberFormat instances) that control the conversion from default PDF user space units (points) to real world units. When converting from PDF units to real world units, the number format objects let you perform the conversion and display the result either as a single real world unit with decimals or as a combination of real a world unit and its subdivisions.
For example if a measure distance is 1.4505 miles, it can be displayed either as ‘1.4505 miles’ or as ‘1 mi 2,378 ft 7 5/8 in’.

A rectilinear measure requires a few properties to be set in order to be valid:

  • ScaleRatio – sets the scale between PDF units and real world units, for example: “1 in = 1 mi”. It is used for display only.
  • X – a collection of number formats that control the measurement change along the X axis. The first number format in the collection shall contain the scale factor for converting from PDF units to the largest units in the measuring coordinate system along the X axis.
  • Y – a collection of number formats that control the measurement change along the Y axis. This property is optional and if it is not set, the same scale ratio is used for both for X and Y
  • Distance – A collection of number formats for measurement of distance in any direction.
  • Area – A collection for number formats for measurement of area.

A number format requires the following properties to be set:

  • MeasureUnit – a label used for displaying in the user interface the measure units represented by this object
  • ConversionFactor – The conversion factor used to multiply a value in partial units of the previous number format collection element to obtain a value in the units of this object.
  • FractionDisplay – specifies how the fractional value of the measurement result is displayed. It can be: Fraction (the denominator of the fraction is displayed by Denominator property), Decimal (the number of decimals is set by Precision property as a power of 10), Round and Truncate (both suppress the decimal part).

The code below shows how to set up a rectilinear measure and its number formats in order to display the measurement results as a combination of miles, feet and inches.

// Create a rectilinear measure for the viewport (CAD drawing for example).
PdfRectilinearMeasure rlm = new PdfRectilinearMeasure();
// Attach the measure to the viewport.
vp.Measure = rlm;
// Set the measure scale: 1 inch (72 points) in PDF corresponds to 1 mile
rlm.ScaleRatio = "1 in = 1 mi";

// Create a number format that controls the display of units for X axis.
PdfNumberFormat xNumberFormat = new PdfNumberFormat();
xNumberFormat.MeasureUnit = "mi";
// Conversion from PDF units to miles
// 1 point = 1/72 miles, 72 points (1 inch) = 1 mile
xNumberFormat.ConversionFactor = 1/72.0; 
// Display the measurement result with 5 decimals
xNumberFormat.FractionDisplay = PdfFractionDisplay.Decimal;
xNumberFormat.Precision = 100000;
rlm.X = new PdfNumberFormatCollection();
rlm.X.Add(xNumberFormat);

// Create a chain of number formats that control the display of units for distance.
rlm.Distance = new PdfNumberFormatCollection();
PdfNumberFormat miNumberFormat = new PdfNumberFormat();
miNumberFormat.MeasureUnit = "mi";
// Initial unit is miles; no conversion needed
miNumberFormat.ConversionFactor = 1; 
rlm.Distance.Add(miNumberFormat);

PdfNumberFormat ftNumberFormat = new PdfNumberFormat();
ftNumberFormat.MeasureUnit = "ft";
// Conversion from miles to feet
ftNumberFormat.ConversionFactor = 5280; 
rlm.Distance.Add(ftNumberFormat);
PdfNumberFormat inNumberFormat = new PdfNumberFormat();
inNumberFormat.MeasureUnit = "in";
// Conversion from feet to inches
inNumberFormat.ConversionFactor = 12; 
// Fractions of inches rounded to nearest 1/8
inNumberFormat.FractionDisplay = PdfFractionDisplay.Fraction;
inNumberFormat.Denominator = 8; 
rlm.Distance.Add(inNumberFormat);

// Create a number format that controls the display of units area.
PdfNumberFormat areaNumberFormat = new PdfNumberFormat();
areaNumberFormat.MeasureUnit = "acres";
// Conversion from square miles to acres
areaNumberFormat.ConversionFactor = 640; 
rlm.Area = new PdfNumberFormatCollection();
rlm.Area.Add(xNumberFormat);
' Create a rectilinear measure for the viewport (CAD drawing for example).
Dim rlm As New PdfRectilinearMeasure()
' Attach the measure to the viewport.
vp.Measure = rlm
' Set the measure scale: 1 inch (72 points) in PDF corresponds to 1 mile
rlm.ScaleRatio = "1 in = 1 mi"

' Create a number format that controls the display of units for X axis.
Dim xNumberFormat As New PdfNumberFormat()
xNumberFormat.MeasureUnit = "mi"
' Conversion from PDF units to miles
' 1 point = 1/72 miles, 72 points (1 inch) = 1 mile
xNumberFormat.ConversionFactor = 1 / 72.0
' Conversion from user space units to miles
xNumberFormat.FractionDisplay = PdfFractionDisplay.[Decimal]
' Display the measurement result with 5 decimals
xNumberFormat.Precision = 100000
rlm.X = New PdfNumberFormatCollection()
rlm.X.Add(xNumberFormat)

' Create a chain of number formats that control the display of units for distance.
rlm.Distance = New PdfNumberFormatCollection()
Dim miNumberFormat As New PdfNumberFormat()
miNumberFormat.MeasureUnit = "mi"
' Initial unit is miles; no conversion needed
miNumberFormat.ConversionFactor = 1
rlm.Distance.Add(miNumberFormat)

Dim ftNumberFormat As New PdfNumberFormat()
ftNumberFormat.MeasureUnit = "ft"
' Conversion from miles to feet
ftNumberFormat.ConversionFactor = 5280
rlm.Distance.Add(ftNumberFormat)

Dim inNumberFormat As New PdfNumberFormat()
inNumberFormat.MeasureUnit = "in"
' Conversion from feet to inches
inNumberFormat.ConversionFactor = 12
' Fractions of inches rounded to nearest 1/8
inNumberFormat.FractionDisplay = PdfFractionDisplay.Fraction
inNumberFormat.Denominator = 8
rlm.Distance.Add(inNumberFormat)

' Create a number format that controls the display of units area.
Dim areaNumberFormat As New PdfNumberFormat()
areaNumberFormat.MeasureUnit = "acres"
' Conversion from square miles to acres
areaNumberFormat.ConversionFactor = 640
rlm.Area = New PdfNumberFormatCollection()
rlm.Area.Add(xNumberFormat)

In the screenshot below you can see how the distance between A and B is displayed as a combination of miles, feet and inches while the change along X and Y (dX and dY) is displayed as a float with 5 decimals. The measure’s scale ratio is displayed in the ‘Embedded scale ratio’ field.

Rectilinear measure

Geospatial viewports

Geospatial viewports use a geospatial measure (a PdfGeospatialMeasure object) to define its measurement scale. These viewports are used for displaying maps with an Earth-based coordinate system.

A geospatial measure requires a few properties to be set in order to be valid:

  • Bounds – an array of points that describes the bounds of an area for which geospatial transformations are valid. This basically defines the map boundary, also known as neatline. These points are expressed relative to a unit square that describes the bounds of the viewport. (0, 0) is the LL corner of the viewport, (1,1) is the UR corner. For example the point (0.5, 0.5) is located in the center of the viewport.
  • CoordinateSystem – the coordinate system of the map being displayed.
  • DisplayCoordinateSystem – a coordinate system for displaying the units to end-user. For example, a map may be created in a state plane coordinate system based on a 1927 datum, but it is possible to display its latitude and longitude values in the WGS84 datum corresponding to values reported by a GPS device.
  • GlobalPoints – an array of points in geographic space as degrees of latitude and longitude. These points are based on the coordinate system described by CoordinateSystem property.

A coordinate system can be either geographic (PdfGeographicCoordinateSystem) or projected (PdfProjectedCoordinateSystem). Both coordinate systems specify an EPSG reference code (http://www.epsg.org) and a Well Known Text (document 01-009, OpenGIS Implementation Specification: Coordinate Transformation Services, of the Open Geospatial Consortium).

2 thoughts on “Geospatial PDF and CAD measurements”

  1. Hi,

    Is it possible to change the actual document size for printing?
    E.g. it is 8.3 x 11.7 and i want to change it to something smaller if possible.

    1. The PageImposition sample shows how to extract the page content a a vector drawing and draw it on another page scaled at a smaller size. Let us know if this procedure does what you need.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.