The Family Historian API
Special Issues with Place and Address Fields
How To Keep Life Simple
This page describes special rules which apply to place and address fields. And at first sight they may appear dauntingly complicated. However, these rules are only relevant to you if you are working directly with Place or Address records, or if you wish to use fhSetValueAsLink or fhSetValue_Copy to set the value of place and address fields in other records. If instead of using those functions, you use fhSetValueAsText to set the value of place and address fields in other records (such as when you set the place and/or address for an event in an Individual record, say), you can avoid the complexity described below.
Ordinary Place and Address Fields
There are some special issues that apply to place fields and address fields, which plugin authors should be aware of. Place and address fields are common throughout the program. All facts (events and attributes) have associated place and address fields, for example. For most purposes, place and address fields look and behave like simple text fields, but internally they are in fact implemented as links. When a user enters a value (e.g. "London, UK") in a place field, Family Historian looks to see if there is already a Place record with this name. If there is, internally, it stores a link to that Place record in the place field. If there isn't, it creates a new Place record with the name required, and stores a link to that Place record instead. It also takes care of updates to place names, and deletion of place names in a similar way. If at any point, a Place record is left with no links to it, as a result of an update, Family Historian will automatically delete that place record - but only if there is no information stored in the Place record. Address fields work in a similar way.
Most of the time, there is no need for ordinary users to be aware of the special nature of place and address fields, and the extra work regarding Place and Address records that Family Historian does with respect to them. However, if users wish to store extra information about places or addresses (e.g. notes, pictures, longitude and latitude, etc), they will find that this information is stored in Place or Address records. Moreover, this data can be accessed using data references. For data reference purposes, all place fields can be treated as a link to a Place record, and all address fields can be treated as a link to an Address record. So, for example, this expression is valid and will return the latitude and longitude of a person's date-of-birth, if known:
%INDI.BIRT.PLAC>LATLONG%
All of the above applies also to plugins. Although, as we have seen, internally place and address fields are really links, they can be treated as text fields by plugin authors. So, for example, if you want to set the value for a place field for a given event, you can use fhSetValueAsText. In fact, until 6.0.2 this was the only option. From 6.0.3 onwards, you can alternatively use fhSetValueAsLink to link a place field to a Place record (although, as we will see below, this can fail if used incorrectly); and from 8.0 onwards, you can use fhSetValueAsLink to link an address field to an Address record (again, as we will see below, this can fail if used incorrectly). If you want to get the value of a place or address field you will ordinarily use fhGetValueAsText. But you can also use the function fhGetValueAsLink to get the associated Place or Address record. Plugin authors can, of course, also use data references which treat place fields as links, to access Place record data, and can use address fields as links, to access Address record data.The Text Field in Place Records
So far when talking about "place fields" we have been talking about ordinary place fields. But there is one special kind of place field which behaves differently. This is the place field in a Place record which stores the actual text of the Place record. This latter field has the tag "TEXT" unlike all ordinary place fields which have the tag "PLAC". The TEXT place field is a level one field within a Place record. It differs from ordinary place fields in the following respects:
- Internally it is not implemented as a link to anything. So using fhGetValueAsLink or fhSetValueAsLink will fail for this field.
- Although you can update the value of this field (using fhSetValueAsText) be aware that the update will fail if you try to set the field to an empty value, or if you try to set the value to a place name that is already in use in another Place record. No two Place records can share exactly the same place name.
- Also, if you do update the value of this field (by providing it with a valid value), you will in doing so effectively update the value of all ordinary place fields that link to this Place record.
- Unlike ordinary place fields, the TEXT place field cannot be separately deleted. You can delete a Place record as a whole, but you cannot separately delete the TEXT place field within it.
Creating Place Records
When you first create a place record, a TEXT field will be automatically be created for it, with no text in it. You should set a text value (subject to the above constraints about uniqueness) straight away. If the user saves and reloads a project that contains a place record with an empty TEXT field in it, Family Historian will automatically generate a unique place name value for it. This will be "(Unidentified place)" followed by a suffix to make it unique, if necessary.
Addresses, Address Records and the Address-Place Consistency Rule
Addresses in Family Historian can be linked to places, and usually are, and are unique within their associated place. If they not linked to a place, they are unique amongst all address that also are not linked to a place. Every Address record can have an optional link to a single Place record. An Address record can be linked to at most one Place record. If an Individual or Family fact is associated with an address, the following rule applies:
The
Address-Place Consistency Rule
If a fact is linked to an Address record, it must also be linked to the
same Place record that the Address record is linked to, if any. If
the Address record is not linked to a Place record, the fact must not be
linked to a Place record.
To enforce this rule, the following policies are used:
- If you set the value of a fact's address field (new or existing) using fhSetValueAsText, a new Address record will be automatically created for that address, if necessary, linked to whatever Place record the fact is linked to, or to no Place record if the fact had no link to a Place record. If there is already a suitable Address record, the address field will be set to link to that Address record.
- If you set the value of a fact's place field (new or existing) using fhSetValueAsText, a new Place record will be automatically created for that place, if necessary. If there is already a suitable Place record (the text matches exactly), the place field will be set to link to that Place record. If the fact in question also has an address field, the address field value will be changed to become an address for that Place record. This will cause the internal link for the address field to be changed, and may result in a new Address record being created.
- If you try to set the value of a fact's address field (new or existing) using fhSetValueAsLink or fhSetValue_Copy, to specify a link to an Address record, the call will fail if the link would break the Address-Place Consistency Rule - that is, if the Address record's Place record link is different from and inconsistent with the Place record linked to by the fact's place field.
- If you try to set the value of a fact's place field (new or existing) using fhSetValueAsLink or fhSetValue_Copy, the call will again fail if setting the link would break the Address-Place Consistency Rule. Note that a call to set the link value of a place field will always succeed if the fact has no address field. But setting the link value of an address field to an Address record, will not necessarily succeed if the fact has no place field. In fact it will only succeed in that case, if the Address record being linked to also has no associated Place record.
- If you delete the place linked to a fact using fhDeleteItem, if the fact has an address field, the address field value will be removed - that is, the address field item will be left with a NULL value. The address field item will not actually be deleted however.
- Within an Address record, the link to a Place record is stored in the _PLAC field. This is an ordinary link, except in this respect: you cannot set it using fhSetValueAsLink or fhSetValue_Copy, or delete it using fhDeleteItem, if the Address record has any inbound links (e.g. from an event in an Individual record). You can however delete the entire Address record, even if it has inbound links. These will be handled automatically in that case.
The Text Field in Address Records
So far when talking about "address fields" we have been talking about ordinary address fields. But there is one special kind of address field which behaves differently. This is the address field in an Address record which stores the actual text of the Address record. This latter field has the tag "TEXT" unlike all ordinary address fields which have the tag "ADDR". The TEXT place field is a level one field within an Address record. It differs from ordinary address fields in the following respects:
- Internally it is not implemented as a link to anything. So using fhGetValueAsLink or fhSetValueAsLink will fail for this field.
- Although you can update the value of this field (using fhSetValueAsText) be aware that the update will fail if you try to set the field to an empty value, or if you try to set the value to an address name that is already in use in another Address record linked to the same Place record. No two Address records linked to the same Place record can share exactly the same address text. And no two Address records which at not linked to a Place record can share exactly the same address text either.
- Also, if you do update the value of this field (by providing it with a valid value), you will in doing so effectively update the value of all ordinary address fields that link to this Address record.
- Unlike ordinary address fields, the TEXT address field cannot be separately deleted. You can delete an Address record as a whole, but you cannot separately delete the TEXT address field within it.
Creating Address Records
When you first create an address record, a TEXT field will be automatically be created for it, with no text in it. You should first link the Address record to a Place record (if it is to be linked to a Place record), and then set a text value straight away (subject to the above constraints about uniqueness). If the user saves and reloads a project that contains an Address record with an empty TEXT field in it, Family Historian will automatically generate a suitably unique address name value for it. This will be "(Unidentified address)" followed by a suffix to make it unique, if necessary.