ArcObjects Library Reference  

Location Library Overview


Supported with: ArcGIS Engine, ArcGIS Desktop, ArcGIS Server

Library dependencies: System, SystemUI, Geometry, Display, Server, Output, GeoDatabase, GISClient, DataSourcesFile, DataSourcesGDB, DataSourcesOleDB, DataSourcesRaster, GeoDatabaseDistributed, Carto, NetworkAnalyst

Additional library information: Contents, Object Model Diagram

 

This content is also available in versions that specifically target .NET and Java developers. Click on the appropriate link to view either version.
        .NET overview of the Location assembly
        Java overview of the Location package


The Location library contains objects that support geocoding and linear referencing.

Geocoding

The geocoding objects provide a framework for creating and managing address locators. Locator objects create geometry for non-spatial descriptions of locations. An AddressLocator is a particular type of locator that creates geometries for text representing addresses. AddressLocators can be stored either on disk or in a file, personal, or ArcSDE geodatabase. AddressLocators can also be used to create GeocodeServer objects that are served using ArcGIS Server. The geocoding objects also provide an extensible framework for creating new types of custom locators.

The geocoding objects can logically be grouped as follows:

 

Locator Workspaces

A locator workspace contains locators and templates for creating new locators, or locator styles. The LocatorWorkspace abstract class allows you to create, store, and retrieve its locators and locator styles. There are three main types of workspaces for locators; each type corresponds to the storage mechanism to be used for its locators:

LocatorManager is an object that retrieves LocatorWorkspace objects from the file system, a geodatabase, or from an ArcGIS Server.

The following examples illustrate how to use a LocatorManager object to open various types of locator workspaces:

Use the ILocatorWorkspace interface to manage the locators and locator styles in a locator workspace. You can use this interface to retrieve Locator and LocatorStyle objects from the locator workspace, as well as create, modify, and delete locators contained in the workspace. Use the GetLocator and GetLocatorStyle methods to retrieve locators and locator styles, respectively, by name from a LocatorWorkspace. The Locators and LocatorNames methods return enumerations of Locator and LocatorName objects, respectively, from the LocatorWorkspace, while the AddLocator method adds a new locator to the workspace. Use RebuildLocator in ILocatorWorkspace2 to rebuild an address locator, particularly if the reference data was modified.

When using the methods on ILocatorWorkspace to refer to locators in an ArcSDE database and styles by name, you must specify a user name as a part of the Locator or LocatorStyle name. The names of ArcSDE locators and locator styles stored in a DatabaseLocatorWorkspace are prefixed with the name of the ArcSDE user who owns them.

Also note that some of the methods on ILocatorWorkspace require you to pass a locator category as a parameter. AddressLocators and AddressLocatorStyles used with ArcGIS have a category of "Address".

Samples

The following samples illustrate the use of the LocatorWorkspace objects.

 

Address Locator Styles

As mentioned earlier, a locator style is a template for creating a new locator. ArcGIS includes the implementation of the LocatorStyle abstract class on which to base new address locators: the ESRIFDOAddressLocatorStyle class is a template for creating locators that use Feature-Data-Object (FDO) reference data, such as shapefiles or geodatabase feature classes.

Each locator style class supports the interfaces required to specify the reference data and geocoding options for a Locator object. To create a new locator, a developer retrieves the LocatorStyle on which the new locator will be based from a LocatorWorkspace, specifies all of the properties on the style as required to define the new Locator, and stores the modified LocatorStyle in the LocatorWorkspace using the AddLocator method on the ILocatorWorkspace interface.

The following example illustrates how to use the LocatorWorkspace and Address Locator Style objects to create a new ArcSDE Locator:


[Visual Basic 6.0]
Dim pConnectionProperties As esriSystem.IPropertySet
Dim pWorkspaceFactory As esriGeoDatabase.IWorkspaceFactory2
Dim pLocatorManager As esriLocation.ILocatorManager2
Dim pLocatorStyle As esriGeoDatabase.ILocatorStyle
Dim pLocatorWorkspace As esriGeoDatabase.ILocatorWorkspace
Dim pLocator As esriGeoDatabase.ILocator
Dim pFeatureWorkspace As esriGeoDatabase.IFeatureWorkspace
Dim pDataset As esriGeoDatabase.IDataset
Dim pReferenceDataTables As esriLocation.IReferenceDataTables
Dim pEnumReferenceDataTable As esriLocation.IEnumReferenceDataTable
Dim pReferenceDataTableEdit As esriLocation.IReferenceDataTableEdit

'+++ open an ArcSDE Workspace
Set pConnectionProperties = New esriSystem.PropertySet
With pConnectionProperties
  .SetProperty "server", "mendota"
  .SetProperty "instance", "esri_sde"
  .SetProperty "database", "arcobjects"
  .SetProperty "user", "sde"
  .SetProperty "password", "sde"
  .SetProperty "version", "SDE.Default"
End With
Set pWorkspaceFactory = New esriDataSourcesGDB.SdeWorkspaceFactory
Set pFeatureWorkspace = pWorkspaceFactory.Open(pConnectionProperties, 0)

'+++ open the DatabaseLocatorWorkspace for the ArcSDE Workspace
Set pLocatorManager = New esriLocation.LocatorManager
Set pLocatorWorkspace = pLocatorManager.GetLocatorWorkspace(pFeatureWorkspace)

'+++ get the US Streets LocatorStyle
Set pLocatorStyle = pLocatorWorkspace.GetLocatorStyle("SDE.US Streets")

'+++ open the feature workspace containing the reference data
'+++ set the reference data on the new locator

Set pDataset = pFeatureWorkspace.OpenFeatureClass("sde.SDE.altanta_st")
Set pReferenceDataTables = pLocatorStyle
Set pEnumReferenceDataTable = pReferenceDataTables.Tables
pEnumReferenceDataTable.Reset
Set pReferenceDataTableEdit = pEnumReferenceDataTable.Next
Set pReferenceDataTableEdit.Name = pDataset.FullName

'+++ store the locator if the reference data are properly specified
If pReferenceDataTables.HasEnoughInfo Then
   Set pLocator = pLocatorWorkspace.AddLocator("My New SDE Locator", pLocatorStyle, "", Nothing)
End If

Locators and locator styles support the ISimpleStandardization interface, which can be used to standardize single addresses or tables and feature classes containing address information. The most common usage for this interface is to use the SimpleStandardizeTable method to standardize the address information in a feature class that will be used as reference data for a locator. It's a good idea to standardize the address information in reference data feature classes, so that address locators created using those reference data feature classes will standardize addresses in the same way that they are standardized in the reference data.

The InputTable parameter is a reference to the table or feature class containing the address information that you want to standardize.

The inputFieldsToConcatenate parameter is a comma-delimited string containing the names of the fields in the input dataset that, when concatenated, form an address that can be standardized. Note that this set of field names should include a numeric field that can represent a house number. When standardizing a dataset, you must first create the table or feature class that will contain the standardized records, and pass it to the SimpleStandardizeTable method using the OutputTable parameter. At a minimum, the standardized dataset must contain an ObjectID field, and all of the standardization fields defined by the SimpleStandardizeFields property. It's also a good idea to create a Shape field in the output dataset (that is, create an output feature class) if you are standardizing the address information in a feature class, and to copy the shapes from the input feature class to the output feature class.

The outputFieldNames parameter is a comma-delimited string that contains the names of the standardization fields in the standardized dataset. The names of the fields in this string must be specified in the same order as the order of the Field objects in the Fields collection returned by the SimpleStandardizeFields property.

The fieldsToCopy parameter is a PropertySet defining which fields from the input dataset to copy to the output dataset. The names of the properties are the names of the fields in the output dataset, and the names of the properties are the names of the corresponding fields in the input dataset.

The following example illustrates how to standardize the address information in a feature class using the ISimpleStandardization interface:


[Visual Basic 6.0]
Dim pConnectionProperties As esriSystem.IPropertySet
Dim pWorkspaceFactory As esriGeoDatabase.IWorkspaceFactory
Dim pFeatureWorkspace As esriGeoDatabase.IFeatureWorkspace
Dim pFeatureClass As esriGeoDatabase.IFeatureClass
Dim pLocatorManager As esriLocation.ILocatorManager
Dim pLocatorWorkspace As esriGeoDatabase.ILocatorWorkspace
Dim pSimpleStandardization As esriLocation.ISimpleStandardization
Dim pFieldsEdit As esriGeoDatabase.IFieldsEdit
Dim pFieldEdit As esriGeoDatabase.IFieldEdit
Dim pStandardizationFields As esriGeoDatabase.IFields
Dim strStandardizedFieldNames() As String
Dim lngStandardizationFieldsIndex As Long
Dim pUID As New esriSystem.UID
Dim pStandardizedFeatureClass As esriGeoDatabase.IFeatureClass
Dim pFieldsToCopy As esriSystem.IPropertySet

'+++ open an ArcSDE Workspace
Set pConnectionProperties = New esriSystem.PropertySet
With pConnectionProperties
  .SetProperty "server", "mendota"
  .SetProperty "instance", "esri_sde"
  .SetProperty "database", "arcobjects"
  .SetProperty "user", "sde"
  .SetProperty "password", "sde"
  .SetProperty "version", "SDE.Default"
End With
Set pWorkspaceFactory = New esriDataSourcesGDB.SdeWorkspaceFactory
Set pFeatureWorkspace = pWorkspaceFactory.Open(pConnectionProperties, 0)

'+++ open the FeatureClass to standardize
Set pFeatureClass = pFeatureWorkspace.OpenFeatureClass("arcobjects.SDE.Redlands_Street")

'+++ get the LocatorStyle to use to standardize the FeatureClass
Set pLocatorManager = New esriLocation.LocatorManager
Set pLocatorWorkspace = pLocatorManager.GetLocatorWorkspace(pFeatureWorkspace)
Set pSimpleStandardization = pLocatorWorkspace.GetLocatorStyle("SDE.US Streets")

'+++ create the FeatureClass to which to write the standardization results
'+++ the FeatureClass must contain an ObjectID Field, a shape Field, and the standardization Fields
Set pFieldsEdit = New esriGeoDatabase.Fields
Set pFieldEdit = New esriGeoDatabase.Field
pFieldEdit.Name = "ObjectID"
pFieldEdit.Type = esriFieldTypeOID
pFieldsEdit.AddField pFieldEdit
pFieldsEdit.AddField _
  pFeatureClass.Fields.Field(pFeatureClass.Fields.FindField(pFeatureClass.ShapeFieldName))
Set pStandardizationFields = pSimpleStandardization.SimpleStandardizeFields
ReDim strStandardizedFieldNames(0 To pStandardizationFields.FieldCount - 1)
For lngStandardizationFieldsIndex = 0 To pStandardizationFields.FieldCount - 1
  pFieldsEdit.AddField pStandardizationFields.Field(lngStandardizationFieldsIndex)
  strStandardizedFieldNames(lngStandardizationFieldsIndex) = _
    pStandardizationFields.Field(lngStandardizationFieldsIndex).Name
Next lngStandardizationFieldsIndex
pUID.Value = "esriGeodatabase.Feature"
Set pStandardizedFeatureClass = pFeatureWorkspace.CreateFeatureClass("Redlands_Standardized", _
  pFieldsEdit, pUID, Nothing, esriFTSimple, pFeatureClass.ShapeFieldName, "")

'+++ standardize the FeatureClass
Set pFieldsToCopy = New esriSystem.PropertySet
pFieldsToCopy.SetProperty pFeatureClass.ShapeFieldName, pFeatureClass.ShapeFieldName
pSimpleStandardization.SimpleStandardizeTable pFeatureClass, "OBJECTID,FULL_NAME", "", _
  pStandardizedFeatureClass, Join(strStandardizedFieldNames, ","), pFieldsToCopy, Nothing

Samples

The following samples illustrate the use of the locator style objects.

 

Address Locator Reference Data

The reference data objects are used to specify and manage the reference data used by ESRIFDOAddressLocators.

Each ESRIFDOAddressLocator has a ReferenceDataTableEnumerator, which is an enumeration of ReferenceDataTable objects used by the locator.

Use the Tables property on the IReferenceDataTables interface on the locator or locator style to get the ReferenceDataTableEnumerator.

ReferenceDataTable objects are used to specify the FDO data sources that an ESRIFDOAddressLocator uses. The Name property on the IReferenceDataTable interface returns a reference to a TableName object that represents the FDO data source used as reference data by the locator. Each ReferenceDataTable has an enumeration of ReferenceDataIndex objects, which specify the geocoding indexes that an ESRIFDOAddressLocator uses to quickly find potential candidates for addresses. ReferenceDataTable objects also have enumerations of ReferenceDataField objects, which are used to specify which fields in the FDO data source contain address information.

The following example illustrates how to use the Locator Workspace, Address Locator Style, and Address Locator Reference Data objects to create a new ESRIFDOAddressLocator:


[Visual Basic 6.0]
Dim pLocatorManager As esriLocation.ILocatorManager2
Dim pLocatorWorkspace As esriGeoDatabase.ILocatorWorkspace
Dim pLocatorStyle As esriGeoDatabase.ILocatorStyle
Dim pWorkspaceFactory As esriGeoDatabase.IWorkspaceFactory2
Dim pFeatureWorkspace As esriGeoDatabase.IFeatureWorkspace
Dim pDataset As esriGeoDatabase.IDataset
Dim pReferenceDataTables As esriLocation.IReferenceDataTables
Dim pEnumReferenceDataTable As esriLocation.IEnumReferenceDataTable
Dim pReferenceDataTableEdit As esriLocation.IReferenceDataTableEdit
Dim pLocator As esriGeoDatabase.ILocator

'+++ open the default LocalLocatorWorkspace to get the LocatorStyle
Set pLocatorManager = New esriLocation.LocatorManager
Set pLocatorWorkspace = pLocatorManager.GetLocatorWorkspaceFromPath("")

'+++ get the LocatorStyle on which to base the new Locator
Set pLocatorStyle = pLocatorWorkspace.GetLocatorStyle("US Streets with Zone")

'+++ open the FeatureClass to use as reference data
Set pWorkspaceFactory = New esriDataSourcesGDB.AccessWorkspaceFactory
Set pFeatureWorkspace = pWorkspaceFactory.OpenFromFile("D:\workspace\arcobjects\location\redlands.mdb", 0)
Set pDataset = pFeatureWorkspace.OpenFeatureClass("Streets")

'+++ set the FeatureClass as the primary ReferenceDataTable for the Locator
Set pDataset = pFeatureWorkspace.OpenFeatureClass("Streets")
Set pReferenceDataTables = pLocatorStyle
Set pEnumReferenceDataTable = pReferenceDataTables.Tables
pEnumReferenceDataTable.Reset
Set pReferenceDataTableEdit = pEnumReferenceDataTable.Next
Set pReferenceDataTableEdit.Name = pDataset.FullName

'+++ store the new Locator in the same workspace of the reference data
If pReferenceDataTables.HasEnoughInfo Then
  Set pLocatorWorkspace = pLocatorManager.GetLocatorWorkspaceFromPath("D:\workspace\arcobjects\location\redlands.mdb")
  Set pLocator = pLocatorWorkspace.AddLocator("New Redlands Locator", pLocatorStyle, "", Nothing)
End If

Samples

The following samples illustrate the use of the Locator Reference Data objects.

 

Address Locators

Locator is an abstract class that performs the work of creating geometry for non-spatial descriptions of locations. All types of locators, including address locators and route locators, are subclasses of the Locator abstract class.

AddressLocator objects are a particular type of locator that creates geometry for text descriptions of addresses. This process is commonly called geocoding. Address locators do the work of finding candidates for addresses, geocoding tables of addresses, and finding single addresses.

ESRIAddressLocator objects are address locators that use the ESRI geocoding engine. The ESRIAddressLocator class is also an abstract class, and there are two main types of ESRIAddressLocator:

The IAddressGeocoding interface is the primary interface used to geocode addresses.

Use the MatchAddress method to geocode a single address. The address parameter is a PropertySet containing properties that represent the input address components used by the Locator.

Use the AddressFields property on the IAddressInputs interface to determine the input address components used by the Locator.

The MatchFields property returns a Fields collection in which the names of the Field objects correspond to the names of the properties in the PropertySet returned by the MatchAddress method.

The following example illustrates how to use the IAddressGeocoding interface to geocode a single address:


[Visual Basic 6.0]
Dim pConnectionProperties As esriSystem.IPropertySet
Dim pAGSServerConnectionFactory As esriGISClient.IAGSServerConnectionFactory
Dim pAGSServerConnection As esriGISClient.IAGSServerConnection
Dim pLocatorManager As esriLocation.ILocatorManager2
Dim pLocatorWorkspace As esriGeoDatabase.ILocatorWorkspace
Dim pAddressGeocoding As esriLocation.IAddressGeocoding
Dim pAddressProperties As esriSystem.IPropertySet
Dim pMatchProperties As esriSystem.IPropertySet
Dim pMatchFields As esriGeoDatabase.IFields
Dim lngMatchFieldIndex As Long
Dim pMatchField As esriGeoDatabase.IField
Dim pPoint As esriGeometry.IPoint

'+++ open an AGSServerConnection
Set pConnectionProperties = New esriSystem.PropertySet
pConnectionProperties.SetProperty "machine", "mendota"
Set pAGSServerConnectionFactory = New esriGISClient.AGSServerConnectionFactory
Set pAGSServerConnection = pAGSServerConnectionFactory.Open(pConnectionProperties, 0)

'+++ open the AGSLocatorWorkspace
Set pLocatorManager = New esriLocation.LocatorManager
Set pLocatorWorkspace = pLocatorManager.GetAGSLocatorWorkspace(pAGSServerConnection.FullName)

'+++ get a Locator from the AGSLocatorWorkspace
Set pAddressGeocoding = pLocatorWorkspace.GetLocator("USA Streets")

'+++ geocode an address using the Locator
Set pAddressProperties = New esriSystem.PropertySet
With pAddressProperties
  .SetProperty "Street", "380 New York St."
  .SetProperty "City", "Redlands"
  .SetProperty "State", "CA"
  .SetProperty "ZIP", "92373"
End With
Set pMatchProperties = pAddressGeocoding.MatchAddress(pAddressProperties)

'+++ print the match properties
Set pMatchFields = pAddressGeocoding.MatchFields
For lngMatchFieldIndex = 0 To pMatchFields.FieldCount - 1
  Set pMatchField = pMatchFields.Field(lngMatchFieldIndex)
  If pMatchField.Type = esriFieldTypeGeometry Then
    Set pPoint = pMatchProperties.GetProperty(pMatchField.Name)
    If Not pPoint.IsEmpty Then
      Debug.Print "X: " & pPoint.X
      Debug.Print "Y: " & pPoint.Y
    End If
  Else
    Debug.Print pMatchField.AliasName & ": " & pMatchProperties.GetProperty(pMatchField.Name)
  End If
Next lngMatchFieldIndex

Use the MatchTable method to geocode a table of addresses. The AddressTable parameter is a reference to the Table object that contains the addresses to geocode. The addressFieldNames parameter is a comma-delimited string containing the names of the fields in the address table that contain the address information. The names of the fields in this string must be specified in the same order as the order of the Field objects in the Fields collection returned by the AddressFields property on the IAddressInputs interface. When geocoding a table of addresses, you must first create the feature class that will contain the geocoded features, and pass it to the MatchTable method using the outputFeatureClass parameter. At a minimum, the geocoded feature class must contain an ObjectID field, all of the match fields defined by the MatchFields property, as well as a copy of all of the fields from the address table that contain the address information. The outputFieldNames parameter is a comma-delimited string that contains the names of the match fields in the geocoded feature class. The names of the fields in this string must be specified in the same order as the order of the Field objects in the Field collection returned by the MatchFields property. The fieldsToCopy parameter is a PropertySet defining which fields from the address table to copy to the output feature class. The names of the properties are the names of the fields in the output feature class, and the names of the properties are the names of the corresponding fields in the address table.

Once you have used the MatchTable method to geocode a table of addresses, use the AttachLocator method on the ILocatorAttach2 on the LocatorWorkspace to attach a copy of the locator to the geocoded feature class.

The following example illustrates how to use the IAddressGeocoding interface to geocode a table of addresses in ArcSDE:


[Visual Basic 6.0]
Dim pConnectionProperties As esriSystem.IPropertySet
Dim pWorkspaceFactory As esriGeoDatabase.IWorkspaceFactory
Dim pFeatureWorkspace As esriGeoDatabase.IFeatureWorkspace
Dim pLocatorManager As esriLocation.ILocatorManager
Dim pLocatorWorkspace As esriGeoDatabase.ILocatorWorkspace
Dim pAddressGeocoding As esriLocation.IAddressGeocoding
Dim pAddressTable As esriGeoDatabase.ITable
Dim pFieldsEdit As esriGeoDatabase.IFieldsEdit
Dim pFieldEdit As esriGeoDatabase.IFieldEdit
Dim pMatchFields As esriGeoDatabase.IFields
Dim lngMatchFieldIndex As Long
Dim pAddressFields As esriGeoDatabase.IFields
Dim pFieldsToCopy As esriSystem.IPropertySet
Dim pUID As New esriSystem.UID
Dim pFeatureClass As esriGeoDatabase.IFeatureClass
Dim pLocatorAttach As esriLocation.ILocatorAttach2

'+++ open an ArcSDE Workspace
Set pConnectionProperties = New esriSystem.PropertySet
With pConnectionProperties
  .SetProperty "server", "mendota"
  .SetProperty "instance", "esri_sde"
  .SetProperty "database", "arcobjects"
  .SetProperty "user", "sde"
  .SetProperty "password", "sde"
  .SetProperty "version", "SDE.Default"
End With
Set pWorkspaceFactory = New esriDataSourcesGDB.SdeWorkspaceFactory
Set pFeatureWorkspace = pWorkspaceFactory.Open(pConnectionProperties, 0)

'+++ get a Locator from the DatabaseLocatorWorkspace
Set pLocatorManager = New esriLocation.LocatorManager
Set pLocatorWorkspace = pLocatorManager.GetLocatorWorkspace(pFeatureWorkspace)
Set pAddressGeocoding = pLocatorWorkspace.GetLocator("SDE.Redlands_ZIP")

'+++ open the Table to geocode
Set pAddressTable = pFeatureWorkspace.OpenTable("arcobjects.sde.REDLANDS_ADDRESS")

'+++ create a FeatureClass to contain the geocoding results
'+++ the FeatureClass must contain an ObjectID Field, all of the MatchFields returned by the Locator,
'+++  and Fields that contain the address input values
Set pFieldsEdit = New esriGeoDatabase.Fields
Set pFieldEdit = New esriGeoDatabase.Field
'+++ add an ObjectID Field
pFieldEdit.Name = "OBJECTID"
pFieldEdit.Type = esriFieldTypeOID
pFieldsEdit.AddField pFieldEdit
'+++ add the MatchFields
Set pMatchFields = pAddressGeocoding.MatchFields
For lngMatchFieldIndex = 0 To pMatchFields.FieldCount - 1
  pFieldsEdit.AddField pMatchFields.Field(lngMatchFieldIndex)
Next lngMatchFieldIndex
'+++ add the address fields
Set pAddressFields = pAddressTable.Fields
Set pFieldsToCopy = New esriSystem.PropertySet
Set pFieldEdit = pAddressFields.Field(pAddressFields.FindField("ADDRESS"))
pFieldEdit.Name = "ARC_ADDRESS"
pFieldsEdit.AddField pFieldEdit
pFieldsToCopy.SetProperty "ARC_ADDRESS", "ADDRESS"
Set pFieldEdit = pAddressFields.Field(pAddressFields.FindField("ZIP"))
pFieldEdit.Name = "ARC_ZIP"
pFieldsEdit.AddField pFieldEdit
pFieldsToCopy.SetProperty "ARC_ZIP", "ZIP"
pUID.Value = "esriGeodatabase.Feature"
Set pFeatureClass = pFeatureWorkspace.CreateFeatureClass("REDLANDS_LOCATION", pFieldsEdit, pUID, _
  Nothing, esriFTSimple, "Shape", "")

'+++ geocode the Table into the FeatureClass
pAddressGeocoding.MatchTable pAddressTable, "ADDRESS,ZIP", "", pFeatureClass, _
  "Shape,Status,Score,Side", pFieldsToCopy, Nothing

'+++ attach the Locator to the geocoded FeatureClass
Set pLocatorAttach = pLocatorWorkspace
pLocatorAttach.AttachLocator pAddressGeocoding, pFeatureClass, _
  "ARC_ADDRESS,ARC_ZIP", "Shape,Status,Score,Side"

The IAdvancedGeocoding interface has methods and properties for standardizing addresses and finding candidates and matches for standardized addresses. Most often, you will make use of the IAdvancedGeocoding interface to rematch a geocoded feature class using the RematchTable method. The RematchTable method takes a number of parameters, most of which you can retrieve directly from the AttachedLocator object associated with the geocoded feature class.

The following example illustrates how to use the IAdvancedGeocoding interface to rematch a geocoded feature class:


[Visual Basic 6.0]
Dim pConnectionProperties As esriSystem.IPropertySet
Dim pWorkspaceFactory As esriGeoDatabase.IWorkspaceFactory
Dim pFeatureWorkspace As esriGeoDatabase.IFeatureWorkspace
Dim pFeatureClass As esriGeoDatabase.IFeatureClass
Dim pLocatorManager As esriLocation.ILocatorManager
Dim pAttachedLocator As esriLocation.IAttachedLocator
Dim pAdvancedGeocoding As esriLocation.IAdvancedGeocoding
Dim pGeocodingProperties As esriLocation.IGeocodingProperties

'+++ open an ArcSDE Workspace
Set pConnectionProperties = New esriSystem.PropertySet
With pConnectionProperties
  .SetProperty "server", "mendota"
  .SetProperty "instance", "esri_sde"
  .SetProperty "database", "arcobjects"
  .SetProperty "user", "sde"
  .SetProperty "password", "sde"
  .SetProperty "version", "SDE.Default"
End With
Set pWorkspaceFactory = New esriDataSourcesGDB.SdeWorkspaceFactory
Set pFeatureWorkspace = pWorkspaceFactory.Open(pConnectionProperties, 0)

'+++ open the FeatureClass to rematch
Set pFeatureClass = pFeatureWorkspace.OpenFeatureClass("arcobjects.SDE.REDLANDS_LOCATION")

'+++ get the Locator that is attached to the FeatureClass
Set pLocatorManager = New esriLocation.LocatorManager
Set pAttachedLocator = pLocatorManager.GetLocatorFromDataset(pFeatureClass)
Set pAdvancedGeocoding = pAttachedLocator.Locator

'+++ modify the geocoding properties on the Locator and rematch the FeatureClass
Set pGeocodingProperties = pAdvancedGeocoding
pGeocodingProperties.MinimumMatchScore = 100
With pAttachedLocator
  pAdvancedGeocoding.RematchTable .InputTable, .InputFieldNamesList, .InputJoinFieldName, _
    .OutputTable, .OutputFieldNamesList, .OutputJoinFieldName, ""
End With

The IReverseGeocoding and IReverseGeocodingProperties interfaces provide access to members for finding the address closest to a Point.

Use the SearchDistance property to define the maximum search tolerance, in the units specified by the SearchDistanceUnits property, to use when searching for an address represented by a Point.

The ReverseGeocode method returns a PropertySet representing the address closest to the Point passed as the location parameter. Note that the Point object passed to the location parameter must be projected into the spatial reference used by the locator before it's passed to the ReverseGeocode parameter. Use the bReturnIntersection parameter to indicate whether the ReverseGeocode method should return an intersection address. The names of the properties contained in the PropertySet correspond to the names of the Field objects in the Fields collection returned by the AddressFields property on the IAddressInputs interface on the locator.

The following example illustrates how to use the IReverseGeocoding and IReverseGeocodingProperties interfaces to find the address closest to a point:


[Visual Basic 6.0]
Dim pConnectionProperties As esriSystem.IPropertySet
Dim pAGSServerConnectionFactory As esriGISClient.IAGSServerConnectionFactory
Dim pAGSServerConnection As esriGISClient.IAGSServerConnection
Dim pLocatorManager As esriLocation.ILocatorManager2
Dim pLocatorWorkspace As esriGeoDatabase.ILocatorWorkspace
Dim pReverseGeocoding As esriLocation.IReverseGeocoding
Dim pPoint As esriGeometry.IPoint
Dim pAddressGeocoding As esriLocation.IAddressGeocoding
Dim pMatchFields As esriGeoDatabase.IFields
Dim pShapeField As esriGeoDatabase.IField
Dim pReverseGeocodingProperties As esriLocation.IReverseGeocodingProperties
Dim pAddressProperties As esriSystem.IPropertySet
Dim pAddressInputs As esriLocation.IAddressInputs
Dim pAddressFields As esriGeoDatabase.IFields
Dim lngAddressFieldIndex As Long
Dim pAddressField As esriGeoDatabase.IField

'+++ open an AGSServerConnection
Set pConnectionProperties = New esriSystem.PropertySet
pConnectionProperties.SetProperty "machine", "mendota"
Set pAGSServerConnectionFactory = New esriGISClient.AGSServerConnectionFactory
Set pAGSServerConnection = pAGSServerConnectionFactory.Open(pConnectionProperties, 0)

'+++ get a Locator from the AGSLocatorWorkspace
Set pLocatorManager = New esriLocation.LocatorManager
Set pLocatorWorkspace = pLocatorManager.GetAGSLocatorWorkspace(pAGSServerConnection.FullName)
Set pReverseGeocoding = pLocatorWorkspace.GetLocator("USA Streets")

'+++ create a Point at which to find the address
Set pAddressGeocoding = pReverseGeocoding
Set pMatchFields = pAddressGeocoding.MatchFields
Set pShapeField = pMatchFields.Field(pMatchFields.FindField("Shape"))
Set pPoint = New esriGeometry.Point
Set pPoint.SpatialReference = pShapeField.GeometryDef.SpatialReference
pPoint.X = -117.2
pPoint.Y = 34.06

'+++ set the search tolerance for reverse geocoding
Set pReverseGeocodingProperties = pReverseGeocoding
pReverseGeocodingProperties.SearchDistance = 100
pReverseGeocodingProperties.SearchDistanceUnits = esriMeters

'+++ find the address nearest the Point
Set pAddressProperties = pReverseGeocoding.ReverseGeocode(pPoint, False)

'+++ print the address properties
Set pAddressInputs = pReverseGeocoding
Set pAddressFields = pAddressInputs.AddressFields
For lngAddressFieldIndex = 0 To pAddressFields.FieldCount - 1
  Set pAddressField = pAddressFields.Field(lngAddressFieldIndex)
  Debug.Print pAddressField.AliasName & ": " & pAddressProperties.GetProperty(pAddressField.Name)
Next lngAddressFieldIndex

Samples

The following samples illustrate the use of the Address Locator objects.

 

Geocode Servers

A GeocodeServer is a ServerObject served by an ArcGIS Server that can be used to geocode addresses. Internally, a GeocodeServer uses an address locator to do the work of geocoding, and exposes the high-level functionality of the address locator using the IGeocodeServer interface. Generally, GeocodeServer objects will be used by ArcGIS Server developers to create server applications that include geocoding functionality. ArcGIS Desktop and ArcGIS Engine developers may, however, wish to use GeocodeServer objects to be able to include geocoding functionality in ArcGIS Desktop customizations and custom applications using only the high-level geocoding functionality exposed by a GeocodeServer.

The following example illustrates how to use a GeocodeServer to geocode a single address:


[Visual Basic 6.0]
Dim pGISServerConnection As esriServer.IGISServerConnection
Dim pServerObjectManager As esriServer.IServerObjectManager
Dim pServerContext As esriServer.IServerContext
Dim pGeocodeServer As esriLocation.IGeocodeServer
Dim pAddressProperties As esriSystem.IPropertySet
Dim pLocatorProperties As esriSystem.IPropertySet
Dim pMatchProperties As esriSystem.IPropertySet
Dim pMatchFields As esriGeoDatabase.IFields
Dim lngMatchFieldIndex As Long
Dim pMatchField As esriGeoDatabase.IField
Dim pPoint As esriGeometry.IPoint

'+++ open a GISServerConnection
Set pGISServerConnection = New esriServer.GISServerConnection
pGISServerConnection.Connect "mendota"

'+++ get a GeocodeServer from the GISServerConnection
Set pServerObjectManager = pGISServerConnection.ServerObjectManager
Set pServerContext = pServerObjectManager.CreateServerContext("USA Streets", "GeocodeServer")
Set pGeocodeServer = pServerContext.ServerObject

'+++ construct an address PropertySet to geocode
Set pAddressProperties = pServerContext.CreateObject("esriSystem.PropertySet")
With pAddressProperties
  .SetProperty "Street", "380 New York St."
  .SetProperty "City", "Redlands"
  .SetProperty "State", "CA"
  .SetProperty "ZIP", "92373"
End With

'+++ set the geocoding properties to use to geocode the address
Set pLocatorProperties = pGeocodeServer.GetLocatorProperties
pLocatorProperties.SetProperty "MinimumMatchScore", "100"
pLocatorProperties.SetProperty "SpellingSensitivity", "100"

'+++ geocode the address
Set pMatchProperties = pGeocodeServer.GeocodeAddress(pAddressProperties, pLocatorProperties)

'+++ print the match properties
Set pMatchFields = pGeocodeServer.GetResultFields(Nothing)
For lngMatchFieldIndex = 0 To pMatchFields.FieldCount - 1
  Set pMatchField = pMatchFields.Field(lngMatchFieldIndex)
  If pMatchField.Type = esriFieldTypeGeometry Then
    Set pPoint = pMatchProperties.GetProperty(pMatchField.Name)
    If Not pPoint.IsEmpty Then
      Debug.Print "X: " & pPoint.X
      Debug.Print "Y: " & pPoint.Y
    End If
  Else
    Debug.Print pMatchField.AliasName & ": " & pMatchProperties.GetProperty(pMatchField.Name)
  End If
Next lngMatchFieldIndex



Linear Referencing


The linear referencing objects provide a framework for the creation, management, and display of linearly referenced data. These objects allow you to find and identify route locations, as well as dynamically segment route events so that they can be displayed on a map. Additional objects are provided for both route and event geoprocessing, as well as for the enhanced cartographic display of routes and events.

The linear referencing objects can logically be grouped as follows:

 

Dynamic Segmentation


Locator is an abstract class that specifies the interfaces common to all types of locator objects. Types of locators include addresses, x,y coordinates, routes, and place names. Locators combine reference data and a location method.

The ILocator interface provides access to the properties of a locator.

The ILocatorFullName interface provides access to the name property of a Locator so that it may be persisted.

RouteLocator is an abstract class. A RouteLocator knows how to transform a route location into a shape that can be displayed on a map.

Route locations describe either a precise location along a route or a portion of a route between a from- and to- measure (see the discussion on RouteMeasureLocator).

The IRouteLocator2 interface inherits from IRouteLocator and is useful for retrieving the properties of a RouteLocator object and for determining the shape of route locations and events (see example following the discussion on route locations). Furthermore, the Identify method is used to identify route locations using an envelope. When in ArcMap, a good way to create this envelope is to use the envelope of the map document’s current location expanded by the search tolerance. For example:

[Visual Basic 6.0]
Dim pEnvelope as IEnvelope
Set pEnvelope = pMxDoc.CurrentLocation.Envelope
pEnvelope.Expand pMxDoc.SearchTolerance, pMxDoc.SearchTolerance, False

For route locators, the RouteFeatureClass class can be a coverage route system, a PolyLineM shapefile, or a PolyLine feature class (with m-values) in a Personal, File or ArcSDE geodatabase. This means routes are stored in a feature class where IGeometryDef::GeometryType = esriGeometryPolyLine and IGeometryDef::HasM = True.

A RouteMeasureLocator is one type of RouteLocator. It determines the shape of a route location by matching the route location’s measure values to those stored in a route feature. A RouteMeasureLocator is created via its Name object counterpart, RouteMeasureLocatorName.

The IRouteLocatorName interface is used to retrieve the properties of a RouteLocator object.

LocatorName is an abstract class that can be used to refer to a Locator object.

RouteLocatorName is an abstract class that can be used to refer to a RouteLocator object.

RouteMeasureLocatorName is a class that can be used to refer to a RouteMeasureLocator object. It is a specific implementation of LocatorName and RouteLocatorName.

All route locator name classes implement the IRouteLocatorName interface. This interface is used for setting and retrieving the properties of a RouteLocatorName object. Some things to note about this interface:

The following example shows how to create a RouteMeasureLocator via a RouteMeasureLocatorName.

[Visual Basic 6.0]
Dim pName As IName
Dim pDS As IDataset
Dim pRtLocatorName As IRouteLocatorName
Dim pRtLocator As IRouteLocator2
Set pDS = pRouteFC ' A PolyLineM feature class
Set pName = pDS.FullName
Set pRtLocatorName = New RouteMeasureLocatorName
With pRtLocatorName
  Set .RouteFeatureClassName = pName
  .RouteIDFieldName = "rKey"
  .RouteMeasureUnit = esriMeters
End With
Set pName = pRtLocatorName
Set pRtLocator = pName.Open

A RouteMeasureLocation describes a portion of a route or a single position along a route.

The IRouteLocation interface lets you define the properties of a route location. For example, route locations occur along a single route, so you set that value here. Additionally, you identify the units in which the route location was collected and specify whether you want the route location’s shape offset from its route when it is located.

Offsets are in the spatial reference units of the route feature class (and not necessarily the same units as the route feature class’ measures). Therefore, an offset on route data stored in geographic units might produce inconsistent results. Offsets are used for rendering purposes only.

Setting the IRouteLocation::MeasureUnit property enables you to do on-the-fly measure conversion. This property corresponds to IRouteLocator::RouteMeasureUnit. For example, you may know the position of a route location in miles, but your route feature class has its measures stored in meters. By setting these values accordingly, you can achieve measure conversion.

RouteMeasureLineLocation is a class that describes portions of a route using from and to measure locations.

The IRouteMeasureLineLocation interface is where you set the route location’s from- and to-measure values. For example, say you wanted to find a location from 2,500 meters to 3,500 meters along route 10. Furthermore, you want this location to be offset 25 meters from the route. Your code would look like this:

[Visual Basic 6.0]
Dim pRouteLoc As IRouteLocation
Dim pRMLineLoc As IRouteMeasureLineLocation
Set pRouteLoc = New RouteMeasureLineLocation
With pRouteLoc
  .MeasureUnit = esriMeters
  .RouteID = 10
  .LateralOffset = 25
End With
Set pRMLineLoc = pRouteLoc
pRMLineLoc.FromMeasure = 2500
pRMLineLoc.ToMeasure = 3500

A RouteMeasurePointLocation is a class that uses a single m-value to describe a single position along a route.

The IRouteMeasurePointLocation interface is where you set the route location’s m-value. For example, if you wanted to find a location 565.5 meters along route 10, your code would look like this:

[Visual Basic 6.0]
Dim pRouteLocation As IRouteLocation
Dim pRMPointLoc As IRouteMeasurePointLocation
Set pRouteLocation = New RouteMeasurePointLocation
With pRouteLocation
  .MeasureUnit = esriMeters
  .RouteID = 10
  .LateralOffset = 0
End With
Set pRMPointLoc = pRouteLocation
pRMPointLoc.Measure = 565.5

Once you have created a route location, determine its geometry by calling the IRouteLocator::Locate method (refer to the examples above to see how the RouteLocator object was created).

[Visual Basic 6.0]
Dim pGeom As IGeometry
Dim LocError As esriLocatingError
pRtLocator.Locate pRMPointLoc, pGeom, LocError

An event table is a table that stores route locations and associated attributes. An event, therefore, is a row from an event table. For example, an event may be a speed limit of 110 km/h on route 50 from km 92 to 138. In this case, the route location information of route 50 between km 92 and 138 is used to reference an attribute to a particular portion of a route in a route feature class.

You need to create RouteEventProperties in order to identify certain characteristics of the table so that it can be recognized as an event table. RouteEventProperties are helper objects for a RouteEventSource.

The IRouteEventProperties2 interface inherits from IRouteEventProperties and establishes the route key field, the measure units the events were collected in, and (optionally) the lateral offset field.

The AddErrorField method indicates whether you want an additional field added to your RouteEventSource (see below) for storing event-locating errors.

Note that the route key (EventRouteIDFieldName) defined on this interface is related to the RouteIDFieldName property on both IRouteLocator and IRouteLocatorName. This is how events are located along their respective routes.

The EventRouteIDFieldName does not have to have the same name as the RouteIDFieldName, but it must store similar data.

RouteMeasureLineProperties is a class used to specify the characteristics of a line event table.

The IRouteMeasureLineProperties interface is where you identify the line event table’s from- and to-measure fields. Each line event’s measures reflect the distance from the lowest measure along its route. To set up line event properties where your table has an offset field, your code would look like this:

[Visual Basic 6.0]
Dim pRtProp As IRouteEventProperties2
Dim pRMLineProp As IRouteMeasureLineProperties
Set pRtProp = New RouteMeasureLineProperties
pRtProp.AddErrorField = True
pRtProp.ErrorFieldName = "LOC_ERROR"
With pRtProp
  .EventMeasureUnit = esriMeters
  .EventRouteIDFieldName = "rKey"
  .LateralOffsetFieldName = "Offset"
End With
Set pRMLineProp = pRtProp
pRMLineProp.FromMeasureFieldName = "fmp"
pRMLineProp.ToMeasureFieldName = "tmp"

RouteMeasurePointProperties is a class used to specify the characteristics of a point event table.

The IRouteMeasurePointProperties2 interface inherits from IRouteMeasurePointProperties2 and is where you identify the point event table’s measure field. Each point event’s measure reflects the distance from the lowest measure along its route.

The AddAngleField method indicates whether you want a field added to your RouteEventSource for storing the angle of the route where the point event is placed. This is useful for things like rotating marker symbols. The normal (perpendicular) or tangent angle can be calculated.

By default, when a point event is located along a route, a point feature is created. In some applications, however, route measures are not unique. The AsPointFeature method provides the ability to create Multipoint features.

Code to set up point event properties on a table might look like this:

[Visual Basic 6.0]
Dim pRtProp As IRouteEventProperties2
Dim pRMPointProp As IRouteMeasurePointProperties2
Set pRtProp = New RouteMeasurePointProperties
pRtProp.AddErrorField = True
pRtProp.ErrorFieldName = "LOC_ERROR"
With pRtProp
.EventMeasureUnit = esriMeters
.EventRouteIDFieldName = "rKey"
End With
Set pRMPointProp = pRtProp
With pRMPointProp
   .MeasureFieldName = "mile"
   .AddAngleField = True
   .AngleFieldName = "LOC_ANGLE"
End With

A RouteEventSource serves an event table as a “dynamic” feature class. Every row in the table is served as a feature whose shape is calculated on the fly every time it is asked for. This is dynamic segmentation.

In order to serve an event table as a feature class, a RouteEventSource needs to know things such as the event table, the RouteEventProperties, and the RouteLocator. The IRouteEventSource interface retrieves this information.

Just like the locator objects outlined earlier, a RouteEventSource is created via its name object counterpart, RouteEventSourceName.

A RouteEventSourceName specifies a RouteEventSource object and can be used to instantiate it.

The IRouteEventSourceName interface sets the event table, the RouteEventProperties, and the RouteLocator. The following example shows how to create a RouteEventSource via a RouteEventSourceName. Here, the RouteMeasurePointProperties and the RouteLocatorName are already created. These values are set using IRouteEventSourceName.

[Visual Basic 6.0]
Dim pDS As IDataset
Dim pName As IName
Dim pRESN As IRouteEventSourceName
Dim pRES As IRouteEventSource
Set pDS = pEventTable
Set pName = pDS.FullName
Set pRESN = New RouteEventSourceName
Set pRESN.EventTableName = pName
Set pRESN.EventProperties = pRMPtProp
Set pRESN.RouteLocatorName = pRtLocatorName
Set pName = pRESN
Set pRES = pName.Open

Because a RouteEventSource is a subclass of a feature class, it can be used anywhere a feature class can be. For example, a RouteEventSource can act as the basis of a feature layer in ArcMap, and its attributes can be edited directly with the editing tools in ArcMap.

There may be some limitations imposed by the event table, however. For example, you will not be able to directly edit a feature class created from a delimited text file table since the Editor does not allow text files to be edited directly.

In a RouteEventSource, there is one feature for every row of the original event table. In some cases, however, the features have empty shapes. This is because there was some reason the event could not be properly located. Other times, an event can only be partially located (this happens for line events only).

The IEventSourceErrors interface exposes some methods that allow you to determine the locating errors of events. The following example uses IEventSourceErrors::GetErrors to create an enumeration of the event rows that did not locate properly.

[Visual Basic 6.0]
Sub TestGetErrors(pRES As IRouteEventSource)
  Dim pESErrors As IEventSourceErrors
  Dim pEnum As IEnumEventError
  Dim pRow As IRow
  Dim LocError As esriLocatingError
  Set pESErrors = pRES
  Set pEnum = pESErrors.GetErrors
  pEnum.Next pRow, LocError
  Do While Not pRow Is Nothing
	Select Case LocError
	  Case 0
		Debug.Print pRow.OID & ": No error"
	  Case 1
		Debug.Print pRow.OID & ": Invalid route ID"
	  Case 2
		Debug.Print pRow.OID & ": Invalid measure"
	  Case 3
		Debug.Print pRow.OID & ": Can't find route"
	  Case 4
		Debug.Print pRow.OID & ": Route's shape is empty"
	  Case 5
		Debug.Print pRow.OID & ": Can't find location along route"
	  Case 6
		Debug.Print pRow.OID & ": Can't find extent along route"
	  Case 7
		Debug.Print pRow.OID & ": From-measure partial match"
	  Case 8
		Debug.Print pRow.OID & ": To-measure partial match"
	  Case 9
		Debug.Print pRow.OID & ": Route's measures are not set"
	  Case 10
		Debug.Print pRow.OID & ": Route is not capable of storing measures"
	  Case 11
		Debug.Print pRow.OID & ": From-measure and to-measure partial match"
	  Case Else
		Debug.Print pRow.OID & ": Non-typical locating error - " & LocError
	End Select
	pEnum.Next pRow, LocError
  Loop
End Sub

The RouteLayerExtension class is worth mentioning, as it is a ‘helper’ class for dynamic segmentation in the ArcMap user interface.

Every feature layer has zero or one RouteLayerExtension objects associated with it. Whenever a new feature layer is added in ArcMap, its associated feature class’ geometry definition is inspected to see whether IGeometryDef::GeometryType = esriGeometryPolyLine and IGeometryDef::HasM = True. If both of these criteria are met (and the layer is not based on linear route events), a RouteLayerExtension is attached to the layer. If you are creating feature layers that will not be added to an ArcMap document, however, you are responsible for attaching a RouteLayerExtension if you want to make use of its services later in your application.

The IRouteLayerExtension interface is where you set the route identifier field name for the route feature class. The other methods on this interface are used by the Add Route Events and the Identify Route Locations dialogs to automatically populate certain parameters.

Samples

The following samples illustrate the use of the dynamic segmentation objects.



 

Route and Event Geoprocessing

Before embarking on any linear referencing project, you will need route data. This data may not exist, may exist but without the appropriate measure system defined, or may exist in a format you do not wish to use.

A route is simply any linear feature that has a unique identifier and measurement system stored with it. Routes can be stored in coverages, shapefiles, and Personal, File, and ArcSDE geodatabases.

A RouteMeasureCreator is used to create routes that are stored in a shapefile or in a Personal, File, or ArcSDE geodatabase. A RouteMeasureCreator merges linear features that share a common identifier and sets the measure values.

The IRouteMeasureCreator2 interface inherits from IRouteMeasureCreator. It exposes the methods and properties necessary for creating route feature classes. One important thing to note is that you can specify either an InputFeatureClass or an InputFeatureSelection. The latter gives you the ability to create routes from only a portion of the features in your input feature class. The input line features are merged on InputRouteIDFieldName.

The CreateUsingCoordinatePriority2 method is used when the route measures on the input line features are not known. This method will generate the measures either by accumulating the digitized length or by accumulating a numeric attribute value of the input features. If you choose to use digitized length, the units of the output route measures will be the same as the coordinate system of the output geometry definition’s spatial reference (feet, meters, etc.). To use the digitized length, simply pass an empty string for the lengthFieldName parameter.

With CreateUsingCoordinatePriority2, you control the direction measures are assigned to the routes by specifying the coordinate priority of the starting measure. The coordinate priority can be set using the values in the esriMSeedingCorner enumeration: esriMSeedingUpperLeft, esriMSeedingBottomLeft, esriMSeedingUpperRight or esriMSeedingBottomRight. These options are determined by placing the minimum-bounding rectangle around the input features that are going to be merged to create one route.

Routes with multiple, disjointed parts are supported. A route representing a road, for example, might have the same name on either side of a river. For situations like this, you can choose to ignore spatial gaps between parts when using CreateUsingCoordinatePriority2. If you choose to ignore spatial gaps, route measures will be continuous when a disjointed route is created. If you want the spatial gap incorporated in the measures, the gap distance is the straight-line distance between the endpoints of the parts. The units of the gap will be that of the coordinate system of the output geometry definition’s spatial reference, which may or may not be the same as the measure units.

The CreateUsing2Fields2 method is used when measure values already exist as attributes of the input linear features. That is, two attributes exist that represent from- and to-measure information for the input lines. When using this method, it is important to orient each input linear feature in the direction of increasing measure to prevent routes that have measures that do not always increase.

Samples

The following sample illustrates the use of a RouteMeasureCreator object:


When route measures are inaccurate, events will not be located properly. It is possible to adjust route measures to correspond with known measure locations using a RouteMeasureCalibrator. A RouteMeasureCalibrator adjusts route measures by reading measure information stored as an attribute in a point feature class. Each point falls on the particular route it calibrates or within a given tolerance. Many points may be used to calibrate a single route.

During the calibration process, a new vertex is created where the calibration points intersect the route. The measure value on these new vertices corresponds to the measure value stored as a point attribute. The measure values on other preexisting route vertices can be interpolated and/or extrapolated.

The IRouteMeasureCalibrator2 interface inherits from IRouteMeasureCalibrator. It exposes the methods and properties necessary for calibrating routes. One important thing to note is that you can specify either an InputFeatureClass or an InputFeatureSelection. The latter gives you the ability to limit the number of points used to calibrate. The RouteLocator property should not be used. Specifying a RouteFeatureClass and RouteIDFieldName or RouteFeatureSelection and RouteIDFieldName is the recommended usage of this interface. A RouteFeatureSelection allows you to limit the routes that will be considered for calibration.

In order for the measure value on a vertex to be interpolated or extrapolated, a calibration ratio is needed. There are two ways this ratio can be determined. The CalibrateRoutesByDistance method uses the shortest path distance between the input points.

The CalibrateRoutesByMs method uses the existing measure distance between the input points. This method is useful when the length to measure ratio on the input route is not consistent and you are using the calibration process to fine-tune a route’s measures.

Either whole or partial routes can be calibrated. You can choose to interpolate between the input points, extrapolate before the input points, extrapolate after the input points, or use any combination of these three methods. The updateHow parameter is given as a combination of esriGeometryUpdateMEnum values. When combining multiple values, the bitwise OR operator should always be used. This assures an error-free combination of the values (as long as the attempted combination is valid). Do not use the addition operator (+) to combine the values as unexpected results may occur. For example, to interpolate between the input points and to extrapolate before and after the input points, you would use 7, which equates to: esriGeometryInterpolate OR esriGeometryExtrapolateBefore OR esriGeometryExtrapolateAfter. A value of 0 will only split the input polyline and assign the Ms value to the new created vertex.

When calibrating disjointed routes, you may choose to ignore the spatial gap between the parts. If you choose to ignore spatial gaps, route measures will be continuous. If you want the spatial gap incorporated in the measures, the gap distance is the straight-line distance between the endpoints of the parts. The units of the gap will be that of the coordinate system of the output geometry definition’s spatial reference, which may or may not be the same as the measure units. Ignoring spatial gaps is only a valid choice when using CalibrateRoutesByDistance.

Samples

The following sample illustrates the use of a RouteMeasureCalibrator object:


The types of event processing operations include dissolving events, concatenating events, and event overlay (line on line and point on line). Event geoprocessing is exposed via the RouteMeasureGeoprocessor class.

The IRouteMeasureEventGeoprocessor2 interface inherits from IRouteMeasureEventGeoprocessor and provides access to the event geoprocessing operations.

Event dissolving and event concatenating both involve combining records in line event tables if they are on the same route and have the same value for specified fields. The results are written to a new line event table. The difference between dissolving and concatenating is that concatenating only combines events in situations where the to-measure of one event matches the from-measure of the next event. Dissolving events will combine events when there is measure overlap.

A line-on-line overlay involves the overlay of two line event tables to produce a line event table. For example, you might want to take an event table that describes pavement cracking and overlay it with pavement resurfacing dates. The results of such an overlay could be used to find the characteristics of the oldest paved sections.

When performing a line-on-line overlay, the results may contain events that have no length (for example, the from- and to-measure values are the same). The IRouteMeasureEventGeoprocessor2::KeepZeroLengthLineEvents property can be used to indicate whether you want such events in your result set.

A line-on-point overlay involves the overlay of a point event table with a line event table to produce either a point or line event table. The intersection of a point and a line event table produces a point event table. The union of a point and a line event table produces a line event table.

Samples

The following samples illustrate the use of a RouteMeasureGeoprocessor object


The RouteLocatorOperations class computes the intersection of input features (point, line or polygon) and route features and writes the route and measure information to a new event table. The new table can be dBASE or Personal, File or ArcSDE geodatabase.

The IRouteLocatorOperations2 interface inherits from IRouteLocatorOperations and provides access to the methods that allow features to be located along routes. Note that you can specify either an InputFeatureClass or an InputFeatureSelection. The latter gives you the ability to limit the number of features to be located. The RouteLocator property should not be used. Specifying a RouteFeatureClass and RouteIDFieldName or RouteFeatureSelection and RouteIDFieldName is the recommended usage of this interface. A RouteFeatureSelection allows you to limit the routes that will be considered for locating.

The LocateLineFeatures method determines the route and measure information where the lines intersect with routes. This intersection is based on a specified cluster tolerance that represents the maximum tolerated distance between the input lines and the target routes. This method should not be thought of as a conflation tool and large cluster tolerances should be avoided. Always use the smallest cluster tolerance possible to achieve the best results. When using this method, the outputProperties should be for line events (RouteMeasureLineProperties).

The LocatePointFeatures method determines the route and measure information where the points intersect with routes. This intersection is based on a search radius, which defines how far around each point a search will be done to find a target route. When using this method, the outputProperties should be for point events (RouteMeasurePointProperties).

The LocatePointEvents method represents a variation of the LocatePointFeatures algorithm and is designed specifically to work on point events. When using this method, the outputProperties should be for point events (RouteMeasurePointProperties).

The LocatePolygonFeatures method determines the route and measure information where the polygons intersect with routes. When using this method, the outputProperties should be for line events (RouteMeasureLineProperties).

Samples

The following samples illustrate the use of a RouteLocatorOperations object.



 

Hatching

Hatching is a type of labeling that is designed to post and label hatch marks or symbols at a regular interval along measured linear features. Hatching can be used for both distance-based and non distance-based measures. Distance-based measures include kilometers, miles, feet, and meters. Non distance-based measures include seismic shot point numbers where measure values generally increase in even intervals based on some nominal distance.

Hatching is exposed via the HatchLayerExtension class. Every feature layer has zero or one HatchLayerExtension objects associated with it. Whenever a new feature layer is added in ArcMap, its associated feature class’ geometry definition is inspected to see whether IGeometryDef::GeometryType = esriGeometryPolyLine and IGeometryDef::HasM = True (this includes RouteEventSource objects based on linear event tables). If both of these criteria are met, a HatchLayerExtension is attached to the layer. If you are creating feature layers that will not be added to an ArcMap document, however, you are responsible for attaching a HatchLayerExtension.

The IHatchLayerExtension interface is where you control the properties of the HatchLayerExtension. To display hatches on a layer, there must be at least one HatchClass associated with the HatchLayerExtension. A HatchLayerExtension has one HatchClass associated with it when it is created. You may choose to manipulate the properties of this HatchClass, or you may choose to remove it (RemoveClass or RemoveAll) and add another (AddClass).

The following code demonstrates how to attach a HatchLayerExtension to a new feature layer:


[Visual Basic 6.0]

Dim pWorkspaceFactory As IWorkspaceFactory
Dim pFeatureWorkspace As IFeatureWorkspace
Dim pFeatureLayer As IFeatureLayer
Dim pLayerExt As ILayerExtensions
Dim pHatchExt As IHatchLayerExtension

Set pWorkspaceFactory = New ShapefileWorkspaceFactory
Set pFeatureWorkspace = pWorkspaceFactory.OpenFromFile("d:\data\dyndata", 0)

Set pFeatureLayer = New FeatureLayer
Set pFeatureLayer.FeatureClass = pFeatureWorkspace.OpenFeatureClass("roads_hwy")
pFeatureLayer.Name = pFeatureLayer.FeatureClass.AliasName

Set pLayerExt = pFeatureLayer
Set pHatchExt = New HatchLayerExtension

pHatchExt.AddClass "Class1", pHatchClass   '+++ pHatchClass is created elsewhere
pLayerExt.AddExtension pHatchExt

The reason a HatchLayerExtension can have more than one HatchClass is because it is useful to be able to hatch different features in different ways (IHatchClass::Filter). For example, you might want to hatch only major highways and leave local roads, collector roads un-hatched. It is also useful to be able hatch the same features in different ways, depending on the map's scale (IHatchClass::MaximumScale and IHatchClass::MinimumScale). For example, you might want to leave features un-hatched when zoomed out full extent, and have them hatched when zoomed in to a certain scale threshold.

A HatchClass has a HatchTemplate. Each HatchTemplate is composed of one or more HatchDefinition objects. A HatchDefinition defines the properties of the hatches themselves. There are two kinds of HatchDefinition: HatchMarkerDefinition and HatchLineDefinition.

The easiest way to understand the HatchClass and HatchDefinition classes is to use a ruler analogy. On a ruler, there is a series of vertical lines, or hatches, separated by a regular interval. For example, on a centimeter (cm) ruler, the hatches are typically spaced every millimeter (mm). One millimeter is 1/10 of a centimeter, so the hatch interval is 0.1.

Not all the hatches on a ruler are the same. Some are longer than others. Further, some have text, while others do not. On a centimeter ruler, the hatches placed at every millimeter (0.1 cm) are the shortest. The hatches placed at every 5 millimeters (0.5 cm) are a bit longer. The hatches placed every 10 millimeters (1 cm) are the longest. The longest hatches typically have text to indicate the measure value.

In this example, the ruler is a HatchClass. It is a container for three HatchDefinition objects. Each HatchDefinition is placed at a multiple of the hatch interval (IHatchClass::HatchInterval). The longest hatches are placed at every 0.1 x 10 measure units. The second longest hatches are placed at every 0.1 x 5 measure units. The shortest hatches are placed at every 0.1 x 1 measure units. When placed on a map, hatch definitions within a single hatch class will not draw on top of one another.

Imagine that you have linear features whose measures are in miles. You want to place a hatch every quarter of a mile. This is a hatch interval of 0.25. Further, you want the hatches placed at every 0.25, 0.5, and 1 mile to look different (different length, different color). You want the hatches every mile to have text. Lastly, you want hatches at the ends of the feature. These end hatches are to look different than all other hatches and will have text. The following example demonstrates conceptually how hatching works in this scenario.

There are many ways in which you can control how hatches appear on a map. To do this, you will use the methods on the IHatchClass, IHatchTemplate, IHatchDefinition and IHatchLineDefinition interfaces. The following illustrate some of the ways hatches can be manipulated.

The IHatchClass interface is where you set properties that are specific to the data being hatched. As such, many of the properties on this interface allow data to be derived from a field or can be a specific value (see the discussion on the HatchInputValue class below).

The most important property on IHatchClass is HatchInterval. This specifies, in measure units, where the hatches will appear on the line. Note, however, that hatches can also be placed only at the route ends. In this case, simply do not specify a hatch interval.

All of the hatch definitions in a hatch class can be offset by the same amount using the LateralOffset property. Offsets are specified in the units of line feature class’s coordinate system (e.g. feet or meters), or by the settings IHatchTemplate::DisplayUnits and IHatchTemplate::ConvertUnits. Note, however, that each individual hatch definition can also have its own offset (IHatchDefinition::Offset).

Hatching can start at a measure location other than the low measure (StartRange) of a route. Further, hatching can finish at a location other than the high measure (EndRange) of a route.

Before giving a code example for HatchClass, it is important to talk about the HatchInputValue class. A HatchInputValue is a helper class for many of the methods on the IHatchClass interface. For many hatching properties, it may be desirable to retrieve values from one of the feature’s attributes, or it may be desirable to simply use pre-defined values. The following code shows how to create a new HatchClass and set some of its more important properties.

[Visual Basic 6.0]
Dim pHatchClass As IHatchClass
Dim pHatchInput1 As IHatchInputValue, pHatchInput2 As IHatchInputValue
Dim pHatchInput3 As IHatchInputValue, pHatchInput4 As IHatchInputValue

Set pHatchClass = New HatchClass
Set pHatchInput1 = New HatchInputValue
pHatchInput1.Value = 100#
Set pHatchClass.HatchInterval = pHatchInput1

Set pHatchInput2 = New HatchInputValue
pHatchInput2.Field = "MMIN"
Set pHatchClass.StartRange = pHatchInput2

Set pHatchInput3 = New HatchInputValue
pHatchInput3.Field = "MMAX"
Set pHatchClass.EndRange = pHatchInput3

Set pHatchInput4 = New HatchInputValue
pHatchInput4.Value = 50#
Set pHatchClass.LateralOffset = pHatchInput4

Note that hatching ‘templates’ can be stored in a esriLocationUI.HatchStyleGalleryClass. Because the properties on IHatchClass can be data specific, however, they are not saved when you add items to a HatchStyleGalleryClass.

The IHatchTemplate interface is where you set properties that are generic to all hatches in a HatchClass. These properties are not data specific. As such, these are the properties that do get saved when you store hatches in a HatchStyleGalleryClass.

In the case where a feature’s geometry has multiple parts, it is possible to apply hatches to the feature as a whole or to each part individually by setting HatchByPart to TRUE.

By default, the placement of hatches is adjusted to the hatch interval. This means that in cases where a line’s low measure is not divisible by the interval, the first hatch will be placed at the first measure value that is divisible by the hatch interval. For example, a line whose measures range from 1.1 to 5.2 will have its first hatch placed at 1.25 when the hatch interval is 0.25. This behavior can be turned off, however, by setting StartAtIntervalMultiple to FALSE. Note that end hatch definitions are not affected by this property and are not shown in the following example.

In cases in where a feature’s high measure is not divisible by the hatch interval and an end hatch definition has been defined, it is possible to get two hatches that are very close to or on top of one another. To avoid this, it is possible to specify an EndHatchDrawingTolerance, which informs the hatching algorithm to not place hatches when they fall within the tolerance of the end hatch. The end hatch tolerance is specified in route measure units, and its value is typically set to a value that is less than the hatch interval.


As noted previously, a HatchDefinition defines the properties of the hatches themselves. There are two kinds of HatchDefinition: HatchMarkerDefinition and HatchLineDefinition.

The IHatchDefinition interface is where you specify the properties that are common to both marker and line hatches.

Each hatch definition can be displayed to the left, centered on, or to the right of a feature by setting the Alignment property. When set to center, hatches will be labeled to the left of the feature.

Hatch text is flipped as the direction of the feature changes. This is to make the text more readable. This can be turned off using AdjustTextOrientation, so the text is always oriented in the direction of increasing measure.

A hatch definition will be labeled with the measure value when the TextSymbol property has been set. The number of decimal places is controlled by the DisplayPrecision property. It is possible, however to add a prefix and/or a suffix to the measure value. The following code adds the suffix ‘km’ to every hatch in the HatchDefinition. In the following code example, pay particular attention to the TextDisplay and Suffix properties.

[Visual Basic 6.0]
Dim pHatchDef As IHatchDefinition
Set pHatchDef = New HatchLineDefinition
With pHatchDef
Set .HatchSymbol = pLineSymbol
.TextDisplay = esriHatchTDPrefixSuffix
Set .TextSymbol = pTextSymbol
.Suffix = "km"
.DisplayPrecision = 0
End With

For certain applications, however, the ability to add a prefix and/or suffix is not enough. For these applications, it is possible to use VBScript or JScript to specify a function that will be evaluated. This function must be called FindLabel and, at the very least, the esri__measure value must be passed in (note that there are two underscore characters in esri__measure). Fields from the layer being hatched can also be passed to the FindLabel function, and are enclosed in square brackets [], regardless of the data type. In the following code example, the FindLabel function sets a hatch’s label to be an empty string when the measure value passed in (esri__measure) is within 25 measure units of the value stored in the MMax field. Otherwise, it appends the ‘km’ suffix to the measure value. Pay particular attention to the TextDisplay, ExpressionParserEngine, ExpressionSimple and Expression properties.

[Visual Basic 6.0]
Dim pHatchDef As IHatchDefinition
Dim pHatchLineDef As IHatchLineDefinition
Set pHatchDef = New HatchLineDefinition
With pHatchDef
Set .HatchSymbol = pLineSymbol
Set .TextSymbol = pTextSymbol
.TextDisplay = esriHatchTDExpression
.ExpressionParserEngine = esriHatchVBScriptEngine
.ExpressionSimple = False
.Expression = "Function FindLabel (esri__measure, [MMax])" & vbCrLf & _
	"mmax = [MMax]" & vbCrLf & _
	"m = esri__measure" & vbCrLf & _
	"If (mmax - m) <= 25 Then " & vbCrLf & _
	  "FindLabel =   """"" & vbCrLf & _
	"Else" & vbCrLf & _
	  "FindLabel = CStr(Round(m, 1)) & "" km""" & vbCrLf & _
	  "End If" & vbCrLf & _
	"End Function"
End With

Note that the FindLabel function in the previous code example looks like the following without the VBScript formatting.

[VBScript ]
Function FindLabel (esri__measure, [MMax])
  mmax = [MMax]
  m = esri__measure
  If (mmax - m)  <= 25 Then
	FindLabel =   ""
  Else
	FindLabel = CStr(Round(m, 1)) & " km"
  End If
End Function

Each HatchTemplate can have an EndHatchDefinition. An end hatch definition pays no attention to the specified hatch interval. Rather, it simply draws hatch marks at the low and high measure of a linear feature. For cases in which hatches get placed too close together near the end of a feature, it is possible to specify an EndHatchDrawingTolerance, which prevents certain hatches from drawing if they are within the tolerance (specified in measure units) of an end hatch. A HatchTemplate can only have one end hatch definition.

The IHatchLineDefinition interface is where you specify the properties that are specific to line hatches. At the very least, you should always set the Length property when dealing with line hatches. Note that the Length is specified in the units of the coordinate system of the route feature class's spatial reference, or by the settings IHatchTemplate::DisplayUnits and IHatchTemplate::ConvertUnits.

Note that by default, line hatches are drawn perpendicular to the feature. It is possible to specify a SupplementalAngle that gets added to the calculated angle.

Samples

The following samples illustrate the use of the Hatching objects.