Observation Topology
Because observations received in observationHandler
of FUITextRecognitionViewController
are not ordered and finding relevant observations can become tedious, SAPMLTextObservationTopology
provides APIs for finding adjacent observations, making it easy to filter observations.
First of all, let us understand the concept of rows, columns, and blocks in a scanned image.
Rows, Columns, and Blocks
For illustration, a sample business card will be used.

SAPMLTextObservationTopology
provides a grid-like topology of the observations that can be traversed easily to find relevant observations. The SAPMLTextObservationTopology
instance can be created inside the observation handler using the following code:
recognitionView.observationHandler = { [weak self] observations in
let topology = SAPMLTextObservationTopology(observations)
return true
}
This topology instance has three key properties - rows
, columns
, and blocks
. Each represents the observations in an ordered way. Listed below is the topology created for the sample business card.

Finding a Relevant Observation
In the business card, finding the Job Title in the second row becomes easy using the rows
property of SAPMLTextObservationTopology
.
recognitionView.observationHandler = { [weak self] observations in
//creating topology of observations
let topology = SAPMLTextObservationTopology(observations)
//Second row contains the Job Title
if (topology.rows.count >= 2)
{
let jobTitleObservation = topology.rows[1]
recognitionView.showTexts(for: [jobTitleObservation], with: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) {
self.textField.text = (jobTitleObservation.value)
self.dismiss(animated: true)
}
return true
}
return false
}
Accessing Adjacent Observations
previousObservationInLine
, nextObservationInLine
, previousObservationInColumn
, and nextObservationInColumn
methods of SAPMLTextObservationTopology
help to find adjacent observations of a given SAPMLTextObservation
.
For example, to fetch the state and ZIP code, which is to the left of Email observation in the same line.
let stateAndZipcodeObservation = topology.previousObservationInLine(emailObservation)
// stateAndZipcodeObservation is "South Carolina, 29673" with comma as the delimiter
let separatedArray = stateAndZipcodeObservation.componentsSeparatedByString(",")
let stateObservation = separatedArray[0]
let zipCodeObservation = separatedArray[1]
Setting Custom blockCreationDistance While Creating a Topology
It is possible to influence the block creation within the topology API. blockCreationDistance
indicates how far two observations can be placed and still be considered to be in same block. The default value is 0.01. The larger the value, the more observations that are far away will be considered in same block.
let topology = SAPMLTextObservationTopology(observations, blockCreationDistance: 0.1)
-
When you receive observations in
observationHandler
, it can be tedious to filter out observations of interest. This class orders the array ofSAPMLTextObservation
into a grid topology that makes it easier for users to traverse and search observations inobservationHandler
.SAPMLTextObservationTopology
also helps in finding observations that are nearby for a givenSAPMLTextObservation
.## Example Initialization and Configuration
recognitionView.observationHandler = { observations let topology = SAPMLTextObservationTopology(observations) // Rows, Columns, and Blocks of these observations can be accessed by relevant instance variables return true; }
## Setting Custom blockCreationDistance While Creating a Topology This parameter in init helps in getting blocks that the user desires. blockCreationDistance indicates how far two observations can be from each other and still be in same block. The default value is 0.01. The larger the value, the more observations that are far away will be considered to be in the same block.
let topology = SAPMLTextObservationTopology(observations, blockCreationDistance: 0.1)
## Accessing Adjacent Observations
previousObservationInLine
,nextObservationInLine
,previousObservationInColumn
, andnextObservationInColumn
methods ofSAPMLTextObservationTopology
help a user get the adjacent observation of a givenSAPMLTextObservation
.For example, to get the last name observation that is known to be in the same line as the first name observation and last name is to the right of the first name. Do the following to get the last name observation from the first name observation.
See morelet lastNameObservation = topology.nextObservationInLine(firstNameObservation)
Declaration
Swift
public class SAPMLTextObservationTopology
-
Information about block of text detected and corresponding array of
See moreSAPMLTextRowObservation
in the block.Declaration
Swift
public class SAPMLTextBlockObservation : SAPMLTextObservation
-
Information about row in detected text and corresponding elements in the row.
See moreDeclaration
Swift
public class SAPMLTextRowObservation : SAPMLTextObservation
-
Information about column in detected text and corresponding elements in the column.
See moreDeclaration
Swift
public class SAPMLTextColumnObservation : SAPMLTextObservation