Please read “Address Locator Style: Introduction” before reading this post.
Editing the Locator Style files:
I am going through this guide by ESRI.
What am I changing?
For me it’s to create an address locator without state (here in Israel we don’t have a state).
Also an optional change is adding common spelling mistakes in Hebrew to the mix.
Basic Change: Name and Description
1. Copied: USAddress.lot.xml, LocatorStyle.xsd, and LocatorStyle.xslt to my projects folder.
2. Rename USAddress.lot.xml
3. Change the name and description for the address locator:
- <?xml version="1.0" encoding="utf-8"?>
- <?xml-stylesheet type="text/xsl" href="LocatorStyle.xslt"?>
- <locators xsi:noNamespaceSchemaLocation="LocatorStyle.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <locator>
- <name>Dll Shepherd Address</name>
- <desc>Locator style for Dll Shepherd addresses</desc>
- <version>10</version>
Change: create an address locator without state
1. Create ref_data_style with the name City Street House Number
- <ref_data_style>
- <name>City Street House Number</name>
- <desc>City,Street and House Number</desc>
- <table_roles>
- <table_role name="Primary">
- <display_name>Primary Table</display_name>
- <desc>streets feature class</desc>
- <field_roles>
- <field_role name="Primary.Shape" is_geometry="true">
- <display_name>Geometry</display_name>
- <preferred_name>Shape</preferred_name>
- </field_role>
- <field_role name="Primary.ID">
- <display_name>Feature ID</display_name>
- <preferred_name>ID</preferred_name>
- <preferred_name>POINTID</preferred_name>
- <preferred_name>FEATUREID</preferred_name>
- <preferred_name>FEATURE_ID</preferred_name>
- <preferred_name>FEAT_ID</preferred_name>
- <preferred_name>FEATUREID_1</preferred_name>
- <preferred_name>FEATUREID_2</preferred_name>
- <preferred_name>DYNAMAPID</preferred_name>
- <preferred_name>DYNAMAP_ID</preferred_name>
- <preferred_name>DYNAMAPID_1</preferred_name>
- <preferred_name>DYNAMAPID_2</preferred_name>
- <preferred_name>OBJECTID</preferred_name>
- <preferred_name>OBJECT_ID</preferred_name>
- <preferred_name>OBJECTID_1</preferred_name>
- <preferred_name>OBJECTID_2</preferred_name>
- <preferred_name>FID</preferred_name>
- <preferred_name>FID_1</preferred_name>
- <preferred_name>FID_2</preferred_name>
- <preferred_name>AREAID</preferred_name>
- <preferred_name>LINK_ID</preferred_name>
- <preferred_name>AREA_ID</preferred_name>
- <preferred_name>LINKID</preferred_name>
- <preferred_name>TLID</preferred_name>
- </field_role>
- <field_role name="Primary.CityName">
- <display_name>CityName</display_name>
- <preferred_name>CityName</preferred_name>
- <preferred_name>CityNameEng</preferred_name>
- <preferred_name>CITY_NAME</preferred_name>
- <preferred_name>CITY</preferred_name>
- <preferred_name>City</preferred_name>
- <preferred_name>CityCode</preferred_name>
- <preferred_name>CITY_CODE</preferred_name>
- </field_role>
- <field_role name="Primary.StreetName">
- <display_name>StreetName</display_name>
- <preferred_name>StreetName</preferred_name>
- <preferred_name>StreetNameEng</preferred_name>
- <preferred_name>STREET_NAME</preferred_name>
- <preferred_name>STREET</preferred_name>
- <preferred_name>Street</preferred_name>
- <preferred_name>StreetCode</preferred_name>
- <preferred_name>STREET_CODE</preferred_name>
- </field_role>
- <field_role name="Primary.HouseNumber">
- <display_name>HouseNumber</display_name>
- <preferred_name>HouseNumber</preferred_name>
- <preferred_name>HOUSE_NUMBER</preferred_name>
- <preferred_name>House</preferred_name>
- <preferred_name>HouseNum</preferred_name>
- <preferred_name>HOUSE</preferred_name>
- </field_role>
- <field_role name="Primary.User_fld">
- <display_name>Additional Field</display_name>
- </field_role>
- </field_roles>
- </table_role>
- </table_roles>
- <data_source type="indexed">
- <mapping_schema ref="REG_COUNTRY" />
- <queries>
- <query>
- <tables>
- <table role_ref="Primary" />
- </tables>
- <fields>
- <field ref="Shape" field_role_ref="Primary.Shape" />
- <field ref="ID" field_role_ref="Primary.ID" />
- <field ref="CityName" field_role_ref="Primary.CityName" />
- <field ref="StreetName" field_role_ref="Primary.StreetName" />
- <field ref="HouseNumber" field_role_ref="Primary.HouseNumber" />
- <field ref="User_fld" field_role_ref="Primary.User_fld" />
- </fields>
- </query>
- </queries>
- </data_source>
I haven’t touched <inputs> and <multiline_grammar> since I don’t know how they work. Testing this now will throw an exception…
2. Since in the previous step we did:
- <data_source type="indexed">
- <mapping_schema ref="REG_COUNTRY" />
- <queries>
- <query>
- <tables>
- <table role_ref="Primary" />
- </tables>
- <fields>
- <field ref="Shape" field_role_ref="Primary.Shape" />
- <field ref="ID" field_role_ref="Primary.ID" />
- <field ref="CityName" field_role_ref="Primary.CityName" />
- <field ref="StreetName" field_role_ref="Primary.StreetName" />
- <field ref="HouseNumber" field_role_ref="Primary.HouseNumber" />
- <field ref="User_fld" field_role_ref="Primary.User_fld" />
- </fields>
- </query>
- </queries>
- </data_source>
Then we need to create the REG_COUNTRY mapping_schema with those fields. Like ZIP:
- <field name="ZIP" grammar_ref="ZIP5">
- <desc>ZIP code</desc>
- <preferred_name>ZIP</preferred_name>
- <preferred_name>ZIPCODE</preferred_name>
- </field>
But what is the grammar for CityName? Well inside grammar->Zones->ZIP5:
- <def name="ZIP5">
- <alt>`[0-9][0-9][0-9][0-9][0-9]`</alt>
- </def>
(It defines ZIP5 as a string of 5 numeric characters)
Looking above it I found:
- <def name="City">
- <alias_list_ref ref="CityAliases"/>
- <alt ref="wordlist"/>
- </def>
(This defines City as a string of words (wordlist is word+wordlist (who loves recursive?)))
The good news is that House is defined but the bad news Street is not. But that is easily fixable we will just add below City:
- <def name="Street">
- <alt ref="wordlist"/>
- </def>
(You can use City for that as well but I prefer creating this definition that later can be customized (for example street must start with “St.” can be defined here)
Later I found this definition for street:
- <def name="StName">
- <alias_list_ref ref="StreetNameAliases"/>
- <alt ref="name"/>
- </def>
Back to our mapping schema, well I started with a copy of USZIP and changed the name and descriptions:
- <mapping_schema name="REG_COUNTRY" geom_type="point">
- <desc>Inner Country schema - city,street,house</desc>
- <desc>Point features containing Inner Country schema - city,street,house.</desc>
- <fields>
(Shape and Id I kept the same)
- <field name="CityName" grammar_ref="City">
- <desc>City Name</desc>
- <preferred_name>CityName</preferred_name>
- <preferred_name>CITY_NAME</preferred_name>
- </field>
- <field name="StreetName" grammar_ref="Street">
- <desc>Street Name</desc>
- <preferred_name>StreetName</preferred_name>
- <preferred_name>STREET_NAME</preferred_name>
- </field>
- <field name="HouseNumber" grammar_ref="House">
- <desc>House Number</desc>
- <preferred_name>HouseNumber</preferred_name>
- <preferred_name>HOUSE_NUMBER</preferred_name>
- </field>
(I kept User_fld since it’s not required and I just don’t know what it does)
Next <index> this I decided to copy+change from SingleAddress, this defines how the index of the data is going to be built:
- <index>
- <dictionary ref="House"/>
- <dictionary ref="StreetName" search="true"/>
- <dictionary ref="City" search="true"/>
- <dictionary ref="ID" type="ids"/>
- <relationship>
- <field_ref ref="ZIP"/>
- </relationship>
- <reverse_relationship>
- <field_ref ref="House"/>
- <field_ref ref="StreetName"/>
- <field_ref ref="City"/>
- <field_ref ref="ID"/>
- <field_ref ref="User_fld"/>
- </reverse_relationship>
- </index>
Outputs, hope it works:
- <outputs>
- <output ref="Shape" type="geometry"/>
- <output component="Status" candidate_mode="false" length="1"/>
- <output component="Score" type="float" decimal_digits="2"/>
- <output name="Match_addr" length="100">
- <format>
- <field_value ref="House"/>
- <field_value ref="StreetName"/>
- <field_value ref="City"/>
- </format>
- </output>
- <output name="Ref_ID" ref="ID" type="fromdata" selector="WriteReferenceIDField"/>
- <output ref="User_fld" type="string" length="120" selector="WriteAdditionalOutputFields" />
- <output component="Match_time" type="float" selector="ShowElapsedTime"/>
- </outputs>
Reverse GeoCoding, I just copy changed this to my needs:
- <reverse_geocoding>
- <reverse_geocoding_method name="Address">
- <outputs>
- <output ref="Shape" type="geometry" />
- <output ref="ZIP" length="5" />
- <output component="Match_time" type="float" selector="ShowElapsedTime"/>
- </outputs>
- </reverse_geocoding_method>
- </reverse_geocoding>
Result (cross my fingers and hope it works):
- <reverse_geocoding>
- <reverse_geocoding_method name="Address">
- <outputs>
- <output ref="Shape" type="geometry" />
- <output ref="House" length="15" />
- <output ref="StreetName" length="100" />
- <output ref="City" length="100" />
- <output component="Match_time" type="float" selector="ShowElapsedTime"/>
- </outputs>
- </reverse_geocoding_method>
- </reverse_geocoding>
I just commented standardization (hope it’s not needed)
Testing got me this Exception:
System.InvalidCastException was unhandled by user code
Message=Unable to cast COM object of type 'System.__ComObject' to interface type 'ESRI.ArcGIS.Location.IReferenceDataTables'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{600A5898-DDC1-11D3-9F74-00C04F8ED1C4}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
Testing
Testing the changes: with ArcCatalog
TODO: I don’t really have ArcCatalog…
Testing the changes: with ArcObjects
I wrote a post about it and it can be found here.
TODO: add a link to the introduction
TODO: add a link to the arcObjects testing
TODO: Fix introduction post
Resources:
Customizing ArcGIS 10 locators (An Esri Geocoding Technical Paper)
Keywords: ESRI, ArcGis Server, geocode, geocoding, address locator