/** * @copyright Sister Software * @license AGPL-3.0 * @author Teffen Ellis, et al. * * Reads the parts of an INSPIRE Addresses feature that every publisher spells the same way. * * INSPIRE harmonizes the schema and leaves the rest to the publisher. Seven publishers this * repository reads all write `ad:Address` with the same element paths, and they disagree on four * things that each decide a value: * * 1. The wrapper. Czechia writes `base:SpatialDataSet` with `base:member`. The Netherlands, * Wallonia and Brussels write `gml:FeatureCollection` with `gml:featureMember`. * 2. The reference form. Czechia's `ad:component` href is an absolute WFS stored-query URL * whose `Id=` parameter is the key. The Netherlands, Wallonia and Brussels write a local `#` * fragment. Flanders writes an absolute data URI that a caller rewrites into a `resourceId`. * 3. Where the postcode lives. Czechia and Wallonia reference an `ad:PostalDescriptor`; the * Netherlands puts it inline as a `LocatorDesignatorTypeValue/postalDeliveryIdentifier` locator and publishes no * `ad:PostalDescriptor` at all. * 4. The locator vocabulary. Czechia types its number `buildingIdentifier`, the Netherlands * `addressNumber`, Wallonia `LocatorDesignatorTypeValue/addressIdentifierGeneral`, Brussels * `buildingIdentifier`. * 5. The prefix's case. Seven publishers write `ad:` and `gn:`. The Dirección General del Catastro * and the Gobierno de Navarra bind the same namespaces to `AD:` and `GN:`. The Catastro also * states a designator type and an administrative level as element text, `1` and `4`, where * everyone else writes a codelist URI. The readers below therefore match an element name * without regard to case, and accept either form of a coded value. * * So this module exposes the primitives and leaves composition to each adapter. A configuration * object describing those four axes would have to be right about publishers whose files nobody has * read yet. A handful of small functions carries no such claim. * * The reference form is the exception, because its shapes are enumerable and measured: * {@linkcode componentJoinKey} reads all four. */ import type { MarkupElement } from "@mailwoman/core/html/elements"; /** * Whether an element's name is `wanted`, ignoring the case of both. * * The prefix a document binds a namespace to is the document's own choice. * Seven publishers write `ad:Address` and `gn:text`. * * The Dirección General del Catastro and the Gobierno de Navarra bind the same * two namespaces to `AD:` and `GN:`. * A reader comparing the name exactly finds neither a locator nor a street * nor a postcode in either Spanish file. * * That reads as an address carrying none rather than as a prefix this repository had not met. * * The prefix is still compared, because it carries the namespace and the namespace carries the meaning. * The Service public de Wallonie writes three `gml:name` elements inside each * `ad:ThoroughfareName`, ahead of the `ad:name` that holds the street. * * A reader that dropped the prefix and matched on `name` alone read the first of those three * and found no street on any of Wallonia's 58,591 thoroughfare features. */ export declare function inspireNameIs(name: string, wanted: string): boolean; /** * The first child of `element` named `name`, ignoring case. * * `name` is written with the prefix the INSPIRE guideline uses, which is the * prefix eight of the nine publishers write. * The case-insensitive sibling of `childElement` from `@mailwoman/core/html/elements`, * which compares the name exactly as a general markup reader must. */ export declare function inspireChild(element: MarkupElement, name: string): MarkupElement | undefined; /** * Every child of `element` named `name`, in document order, ignoring case. * * The case-insensitive sibling of `childElements` from `@mailwoman/core/html/elements`, * for the same reason {@linkcode inspireChild} is. */ export declare function inspireChildren(element: MarkupElement, name: string): readonly MarkupElement[]; /** * The element reached by walking `path` from `element`, taking the first match at each step. * * The case-insensitive sibling of `elementAtPath` from `@mailwoman/core/html/elements`. * An INSPIRE value sits five or six elements down, so the path form reads better than * a chain of {@linkcode inspireChild} calls and reports the same absence. */ export declare function inspireElementAt(element: MarkupElement, ...path: readonly string[]): MarkupElement | undefined; /** * The final segment of an INSPIRE codelist URI, which is the value's name. * * `http://inspire.ec.europa.eu/codelist/LocatorDesignatorTypeValue/buildingIdentifier` * reads `buildingIdentifier`. * A `#` fragment is dropped first, because Flanders appends one to a `vocab.belgif.be` * reference and Czechia folds it into `base:localId`. */ export declare function codelistValue(uri: string | undefined): string | undefined; /** * Whether a publisher marked this element void. * * INSPIRE writes `xsi:nil="true"` and usually a `nilReason`. * Brussels writes the nil marker and no reason on all 232,003 of its void `ad:validFrom` * elements, and Czechia writes four `gn:pronunciation` elements nil with no reason, * so a reader keyed on `nilReason` alone mistakes a void value for a populated one. * * An absent element answers false, so a caller distinguishes a void value from a missing one. */ export declare function isVoid(element: MarkupElement | undefined): boolean; /** * The reason a publisher gave for a void element, as a codelist value such as `Unpopulated`. * * Returns undefined when the element is void and states no reason, which the * schema permits and which Brussels does throughout. * A caller that needs to separate a void carrying a reason from a void carrying * none reads this together with {@linkcode isVoid}. */ export declare function voidReason(element: MarkupElement | undefined): string | undefined; /** * Every locator designator on an address, keyed by its INSPIRE type name. * * One `ad:AddressLocator` carries a designator per part of the number, each in its * own `ad:LocatorDesignator` beside an `ad:type` naming what it is. * Czechia writes two, `č.ev.` typed `buildingIdentifierPrefix` and `502` typed `buildingIdentifier`. * * The Netherlands writes four, including an empty `LocatorDesignatorTypeValue/addressNumberExtension` * and the postcode as `LocatorDesignatorTypeValue/postalDeliveryIdentifier`. * * A type may repeat, so each key holds a list in document order. * A designator the publisher wrote empty contributes an empty string, which is a value the publisher * stated rather than one it omitted: the Netherlands writes `` 198,118 times * over 108,708 features to mean "no extension", and that is a different condition from void. * * A designator whose `ad:type` is absent or void is skipped, because its value cannot be placed. */ export declare function designatorsByType(address: MarkupElement): ReadonlyMap; /** * The first non-empty designator among `types`, in the order given. * * A caller states its publisher's vocabulary and its own precedence: * Czechia asks for `buildingIdentifier`, the Netherlands for `addressNumber`, * Wallonia for `LocatorDesignatorTypeValue/addressIdentifierGeneral`. */ /** * The locator-designator types this address marks void, by their INSPIRE type name. * * {@linkcode designatorsByType} leaves a void designator out, so on its own it cannot * separate a value the publisher marked unknown from one the publisher never wrote. * The repository's partial-read rule needs that separation: an unreadable requested * value has to be reported rather than turned into an absence. * * A caller reads this when the difference changes what it does. * An adapter that refuses a row carrying no house number should report a void `buildingIdentifier` as * a value it could not read, and an absent one as an address the publisher states has no number. */ export declare function voidDesignatorTypes(address: MarkupElement): ReadonlySet; export declare function designator(byType: ReadonlyMap, ...types: readonly string[]): string | undefined; /** * Every `ad:component` reference on an address, as written. * * The href is returned verbatim, and {@linkcode componentJoinKey} turns it into a join key. * A component whose href is absent or empty is skipped. * * Brussels writes `` on 9 addresses, and those 9 therefore * carry no postal zone, which a caller must report rather than read as a resolved component. */ export declare function componentHrefs(address: MarkupElement): readonly string[]; /** * One `ad:component` reference, with the title the publisher wrote beside it. */ export interface ComponentLink { /** * The `xlink:href`, trimmed and otherwise as written. */ readonly href: string; /** * The `xlink:title`, or undefined where the reference carries none. */ readonly title?: string; } /** * Every `ad:component` reference on an address, with its title. * * Most publishers repeat the referenced feature's own value in `xlink:title`, and their adapters * read the resolved feature instead, because a title is a copy and the feature is the record. * * The Gobierno de Navarra is the case that needs the title. * Its references leave the file: a thoroughfare reference is the bare string `ThoroughfareName` * and an administrative-unit reference addresses a CartoCiudad stored query. * * The title is the only statement of the street name, the postcode and the place names * that its own file carries, so its adapter reads titles and resolves no reference. * * A component whose href is absent or empty is skipped, as in {@linkcode componentHrefs}. */ export declare function componentLinks(address: MarkupElement): readonly ComponentLink[]; /** * The key a component reference joins on. * * Four shapes appear across the publishers measured, and they differ in * where the key sits rather than in whether one exists: * * | publisher | href | key | * | --- | --- | --- | * | Netherlands, Wallonia, Brussels | `#nl-imbag-ad-thoroughfarename.0003300000117203` | the fragment | * | Czechia | `…inspire-ad-wfs.asp?…&Id=TF.48674` | `TF.48674` | * | Slovakia | `…ad/ows?…&id=AdminUnitName.15345` | `AdminUnitName.15345` | * | Flanders | `https://data.vlaanderen.be/id/straatnaam/6301` | the URI itself | * * A URI with no id parameter is its own key, which is what Flanders publishes on both sides of the join. * Its fragment is dropped, because a reference may carry one where the identifier does not: * `http://vocab.belgif.be/auth/refnis1995/1000#id` addresses the same term as that URI without it. * * Whether a key joins is not a property of its spelling, so this reads a key * and the caller decides joinability against the features the publisher actually served. * Deciding it here from the URL's shape once reported 15 of Flanders' 20 references as * belonging to another register when every one of them addressed a feature of the same service. * * @returns The key, or undefined when the href is neither a fragment nor a URL. */ export declare function componentJoinKey(href: string): string | undefined; /** * The spelling a `gn:GeographicalName` carries, reached from a feature that holds one. * * Every name-bearing INSPIRE feature nests the text at * `…/gn:GeographicalName/gn:spelling/gn:SpellingOfName/gn:text`, under a per-feature * prefix: an `ad:ThoroughfareName` adds `ad:name/ad:ThoroughfareNameValue/ad:name`, * while an `ad:AdminUnitName` and an `ad:AddressAreaName` add only `ad:name`. * The caller gives the prefix. * * @returns The text, or undefined when any step is absent or the name is void. */ export declare function geographicalNameText(feature: MarkupElement, ...prefix: readonly string[]): string | undefined; /** * The street name an `ad:ThoroughfareName` feature states. */ export declare function thoroughfareName(feature: MarkupElement): string | undefined; /** * The place name an `ad:AdminUnitName` or `ad:AddressAreaName` feature states. */ export declare function placeName(feature: MarkupElement): string | undefined; /** * The postcode an `ad:PostalDescriptor` feature states. * * The Spanish cadastre writes this element as an integer, so `02250` arrives as `2250`. * Left-padding belongs to the caller that knows the jurisdiction's width, * because this reader returns what the publisher wrote. */ export declare function postalDescriptorCode(feature: MarkupElement): string | undefined; /** * The administrative level an `ad:AdminUnitName` states, as a codelist value such as `4thOrder`. * * A publisher references several admin units per address: Czechia references the * country at `1stOrder` and the municipality at `4thOrder`, and the Netherlands * publishes exactly one `ad:AdminUnitName` feature, the country. * A caller picks the finest level it wants by this value rather than by the order the references appear. */ export declare function adminUnitLevel(feature: MarkupElement): string | undefined; //# sourceMappingURL=address.d.ts.map