{"id":1659,"date":"2018-02-12T15:37:05","date_gmt":"2018-02-12T15:37:05","guid":{"rendered":"https:\/\/wetransform.eu\/?post_type=news-and-events&#038;p=1659"},"modified":"2022-07-28T08:11:06","modified_gmt":"2022-07-28T08:11:06","slug":"inspireid-best-practices","status":"publish","type":"news-and-events","link":"https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/","title":{"rendered":"gml:id, gml:identifier and the InspireID \u2013 Clarifications and Best Practices"},"content":{"rendered":"<p>Many people who create GML, and in particular INSPIRE GML, hit some common challenges around identifying features. In part, these come from technical requirements of XML\/GML, and in part they come from INSPIRE requirements. <\/p>\n<p>An INSPIRE feature will generally have three properties that identify objects, each with a different purpose:<\/p>\n<p><code>gml:id<\/code>: This is the <strong>mandatory<\/strong> XML element ID, and it is encoded as an attribute of the element. It is used to uniquely identify that element in the current document, and serves to identify the target object of an Xlink. It has to match a defined pattern, e.g. it must start with a letter or underscore. It is first and foremost a technical identifier, though it should be stable over time (e.g. over multiple transformation runs) and should thus be grounded in a property of the source feature. Only if it is stable over time, Xlink references across documents can actually work. The <code>gml:id<\/code> is used by the WFS standard query <code>GetFeatureByID<\/code>.<\/p>\n<p><code>inspireId<\/code>: This is a specific, often <strong>mandatory<\/strong>, complex property of INSPIRE objects, which consists of three sub-properties - <code>localId<\/code>, <code>namespace<\/code>, and <code>version<\/code>. The INSPIRE ID should be stable, and is usually used to clearly identify the object in its specific domain. Often, existing keys are re-used 1:1 as the <code>localId<\/code>.<\/p>\n<p><code>gml:identifier<\/code>: This is the <strong>optional<\/strong> external element ID, i.e. it should include a namespace to make it globally unique, not just in the current document. It is a standard property of all GML objects, it is encoded as an element, and is of the type <code>gml:CodeWithAuthorityType<\/code>. This is also a technical identifier which should be stable over time. INSPIRE recommends to use the <code>namespace<\/code> and <code>localId<\/code> from the <code>inspireId<\/code> to build the <code>identifier<\/code>, and INSPIRE <code>identifiers<\/code> use this codespace: <code>http:\/\/inspire.ec.europa.eu\/ids<\/code><\/p>\n<p>Here is a complete example for a feature with all three properties:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/JBoudewijn\/13afec1189078e916669a6dc31444ac6.js\"><\/script><\/p>\n<p><a href=\"https:\/\/github.com\/wetransform-os\/website-examples\/blob\/af7108ee8f5a838327c3e4b871850212c399e37c\/news\/resources\/idexample.xml\" title=\"Download\">Download<\/a><\/p>\n<p>The following guidelines on how to form these different types of IDs are partially based on the guidelines that the German AdV (Arbeitsgemeinschaft der Vermessungsverwaltungen der L\u00e4nder Deutschlands) has developed. We\u2019ve used those successfully in hundreds of transformation projects.<\/p>\n<h2>Namespaces<\/h2>\n<p>Both for <code>gml:Identifier<\/code> and for the INSPIRE ID, you will need to define a dataset namespace. The dataset namespace needs to be unique within all of the INSPIRE infrastructure, and will be used for one data set only. There are generally two common patterns for these namespaces:<\/p>\n<ol>\n<li><strong>Technical namespace<\/strong>: There is one central namespace for all resources in your local spatial data infrastructure. All resources get a technical identifier, such as a UUID, which together with the registry URL, forms the dataset namespace, such as in this (fictitious) example:<br \/>\n<a href=\"https:\/\/www.nationaalgeoregister.nl\/c4b137b8-2317-42c2-aced-204c4216d68d\">https:\/\/www.nationaalgeoregister.nl\/c4b137b8-2317-42c2-aced-204c4216d68d<\/a><br \/>\nSuch namespaces are easy to generate, and collisions are very unlikely.<\/li>\n<li><strong>Semantic namespace<\/strong>: A semantic namespace identifies the data owner, as well as some properties of the dataset, such as the INSPIRE theme it belongs to, and what data it was derived from. This is a real example: <a href=\"http:\/\/www.swisstopo.ch\/inspire\/au\/4.0\/swissboundaries3d\/\">http:\/\/www.swisstopo.ch\/inspire\/au\/4.0\/swissboundaries3d\/<\/a><\/li>\n<\/ol>\n<p>Both approaches have some advantages and disadvantages, so it comes down to what you want to achieve by using the namespaces. For all kinds of namespaces, there is often a national or regional registry (such as the <a href=\"https:\/\/registry.gdi-de.org\/\">GDI-DE Registry<\/a>) where INSPIRE implementers have to register their organisation and dataset namespaces.<\/p>\n<h2>General Rules for IDs<\/h2>\n<p>In most situations, we recommend to have the values for <code>gml:id, localId<\/code> and the local part of the <code>gml:identifier<\/code> to be identical. Since we often generate multiple INSPIRE objects of different INSPIRE Feature types from one source object, we need to differentiate these objects and thus prefix the domain key with the INSPIRE type name, e.g. like this:<\/p>\n<p><code>AdministrativeBoundary_932817<\/code><\/p>\n<p>We used both underscores and points to separate the INSPIRE type name from the domain key, there is no inherent difference. The domain key has to be a unique property in all source objects, or it has to be generated. Using a unique source property is highly preferred, as only that guarantees a stable ID over multiple transformation or generation runs.<\/p>\n<p>In some cases, the source objects have a unique domain key that uses a problematic format (e.g. containing spaces or backslashes). If uniqueness can still be guaranteed by removing the special characters you can just strip them, otherwise, we recommend to use the source domain key as input to either generate a UUID, or to generate a Hash value. To generate a Hash value, we recommend the SHA-256 algorithm.<\/p>\n<p>This approach has several advantages: <\/p>\n<ul>\n<li>It guarantees a valid ID, which needs to start with a non-numerical character<\/li>\n<li>It differentiates multiple objects created from one source object<\/li>\n<li>It immediately tells a viewer what kind of object this is, which is especially useful in references<\/li>\n<\/ul>\n<p>The question how you can build references is often the key to determine which source domain key is used best. This requires a stable, reproducible generation method that we can also employ in places where the original source object was referenced. So, when in doubt, your domain key should always be the value that is used in the existing data to create references (e.g. a Foreign Key in a data base table).<\/p>\n<h2>Merging objects<\/h2>\n<p>There are many cases where we create an INSPIRE object from multiple source objects. As an example, we merge a set of <code>WaterwayLinks<\/code> to create <code>InlandWaterways<\/code>. In this case, we still want to create a stable ID for the merged object. We do this by concatenating the domain keys of all the merged objects and then calculating the SHA-256 Hash value of the resulting string. This gives us a long, but still manageable ID:<\/p>\n<p><code>InlandWaterway_e3b0c44298fc1c149afbf4c8...4649b934ca495991b7852b855<\/code><\/p>\n<p>Another approach would be to use the value that was used to group objects as the domain key part. This creates a semantically meaningful identifier, like in this example with a stripped name:<\/p>\n<p><code>InlandWaterway_DiepwaterrouteDuitslandWestFrieslandNoordHinder<\/code><\/p>\n<h2>Splitting Objects<\/h2>\n<p>In some cases, we need to disassemble a source object and create many INSPIRE objects of the same type from it. The most common use case for this is when the INSPIRE schema only allows simple geometries, and we have to split up a <code>MultiGeometry<\/code>. In this case, we apply the same rules as for the simple 1:1 creation, but add a postfix to the ID that uses the index of the property on which we split the object. In this example, we look at the 22nd object created from splitting out a source object(we start with 1, not with 0):<\/p>\n<p><code>WaterwayLink_e3b0c44298fc1c149afbf4c8...4649b934ca495991b7852b855_22<\/code><\/p>\n<h2>Joining Objects<\/h2>\n<p>In a join, we use multiple objects of different source types to form an INSPIRE object. As an example, we might join a <code>Municipality<\/code> and a <code>District<\/code> object together to create an <code>AdministrativeUnit<\/code> with references to <code>lowerLevelUnits<\/code>. If there is a reason why we can\u2019t just use the domain key of the <code>District<\/code>, our recommendation is to also use multi-component IDs for this case. In a Join, there is always a \u201cfocus\u201d or \u201croot\u201d object, to which matching objects of other types are added. In this example, we try to find all <code>Municipalities<\/code> belonging to the <code>District<\/code>, so the <code>District<\/code> is the focus object. We use the domain key of this root object as we would for a simple 1:1 creation. However, we then add another key created by concatenating the domain keys of the joined objects (the Municipalities), like we do it in the Merge case. This means we take the concatenated IDs of the Municipalities and then create a SHA-256 Hash value, which is then added to the other parts of the ID:<\/p>\n<p><code>District_241_e3b0c44298fc1c149afbf4c8...4649b934ca495991b7852b855<\/code><\/p>\n<h2>Summary<\/h2>\n<p>Creating stable IDs that can be referenced is somewhat complex. However, we\u2019ve used the rules above as well as some variants over a few hundred projects by now and they work very well. Do you have ideas on who to improve or complement them? Let us know!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many people who create GML, and in particular INSPIRE GML, hit some common challenges around identifying features. In part, these come from technical requirements of XML\/GML, and in part they come from INSPIRE requirements. An INSPIRE feature will generally have three properties that identify objects, each with a different purpose: gml:id: This is the mandatory [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[48],"tags":[65,75,37,76,18],"class_list":["post-1659","news-and-events","type-news-and-events","status-publish","hentry","category-tutorials","tag-best-practices","tag-data-specifications","tag-gml","tag-identifiers","tag-inspire"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.5 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>gml:id, gml:identifier and the InspireID \u2013 Clarifications and Best Practices - wetransform<\/title>\n<meta name=\"description\" content=\"People who create GML often hit challenges around identifying features. Learn best practices for gml:id, gml:identifier, and the InspireID.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"gml:id, gml:identifier and the InspireID \u2013 Clarifications and Best Practices\" \/>\n<meta property=\"og:description\" content=\"People who create GML often hit challenges around identifying features. Learn best practices for gml:id, gml:identifier, and the InspireID.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/\" \/>\n<meta property=\"og:site_name\" content=\"wetransform\" \/>\n<meta property=\"article:modified_time\" content=\"2022-07-28T08:11:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wetransform.to\/wp-content\/uploads\/2022\/04\/logo-large-e1657284415170.png\" \/>\n\t<meta property=\"og:image:width\" content=\"254\" \/>\n\t<meta property=\"og:image:height\" content=\"200\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@wetransformto\" \/>\n<meta name=\"twitter:label1\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data1\" content=\"6\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wetransform.to\\\/de\\\/news-and-events\\\/inspireid-best-practices\\\/\",\"url\":\"https:\\\/\\\/wetransform.to\\\/de\\\/news-and-events\\\/inspireid-best-practices\\\/\",\"name\":\"gml:id, gml:identifier and the InspireID \u2013 Clarifications and Best Practices - wetransform\",\"isPartOf\":{\"@id\":\"http:\\\/\\\/wetransform.to\\\/de\\\/#website\"},\"datePublished\":\"2018-02-12T15:37:05+00:00\",\"dateModified\":\"2022-07-28T08:11:06+00:00\",\"description\":\"People who create GML often hit challenges around identifying features. Learn best practices for gml:id, gml:identifier, and the InspireID.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wetransform.to\\\/de\\\/news-and-events\\\/inspireid-best-practices\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wetransform.to\\\/de\\\/news-and-events\\\/inspireid-best-practices\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wetransform.to\\\/de\\\/news-and-events\\\/inspireid-best-practices\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wetransform.to\\\/de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"News & Events\",\"item\":\"https:\\\/\\\/wetransform.to\\\/de\\\/news-and-events\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"gml:id, gml:identifier and the InspireID \u2013 Clarifications and Best Practices\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\\\/\\\/wetransform.to\\\/de\\\/#website\",\"url\":\"http:\\\/\\\/wetransform.to\\\/de\\\/\",\"name\":\"wetransform\",\"description\":\"Making environmental data useful and accessible\",\"publisher\":{\"@id\":\"http:\\\/\\\/wetransform.to\\\/de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\\\/\\\/wetransform.to\\\/de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"http:\\\/\\\/wetransform.to\\\/de\\\/#organization\",\"name\":\"wetransform\",\"url\":\"http:\\\/\\\/wetransform.to\\\/de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"http:\\\/\\\/wetransform.to\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/wetransform.to\\\/wp-content\\\/uploads\\\/2022\\\/07\\\/large-logo-whitebg.png\",\"contentUrl\":\"https:\\\/\\\/wetransform.to\\\/wp-content\\\/uploads\\\/2022\\\/07\\\/large-logo-whitebg.png\",\"width\":1024,\"height\":1024,\"caption\":\"wetransform\"},\"image\":{\"@id\":\"http:\\\/\\\/wetransform.to\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/wetransformto\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/wetransform-gmbh\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"gml:id, gml:identifier and the InspireID \u2013 Clarifications and Best Practices - wetransform","description":"People who create GML often hit challenges around identifying features. Learn best practices for gml:id, gml:identifier, and the InspireID.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/","og_locale":"de_DE","og_type":"article","og_title":"gml:id, gml:identifier and the InspireID \u2013 Clarifications and Best Practices","og_description":"People who create GML often hit challenges around identifying features. Learn best practices for gml:id, gml:identifier, and the InspireID.","og_url":"https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/","og_site_name":"wetransform","article_modified_time":"2022-07-28T08:11:06+00:00","og_image":[{"width":254,"height":200,"url":"https:\/\/wetransform.to\/wp-content\/uploads\/2022\/04\/logo-large-e1657284415170.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_site":"@wetransformto","twitter_misc":{"Gesch\u00e4tzte Lesezeit":"6\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/","url":"https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/","name":"gml:id, gml:identifier and the InspireID \u2013 Clarifications and Best Practices - wetransform","isPartOf":{"@id":"http:\/\/wetransform.to\/de\/#website"},"datePublished":"2018-02-12T15:37:05+00:00","dateModified":"2022-07-28T08:11:06+00:00","description":"People who create GML often hit challenges around identifying features. Learn best practices for gml:id, gml:identifier, and the InspireID.","breadcrumb":{"@id":"https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/wetransform.to\/de\/news-and-events\/inspireid-best-practices\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wetransform.to\/de\/"},{"@type":"ListItem","position":2,"name":"News & Events","item":"https:\/\/wetransform.to\/de\/news-and-events\/"},{"@type":"ListItem","position":3,"name":"gml:id, gml:identifier and the InspireID \u2013 Clarifications and Best Practices"}]},{"@type":"WebSite","@id":"http:\/\/wetransform.to\/de\/#website","url":"http:\/\/wetransform.to\/de\/","name":"wetransform","description":"Making environmental data useful and accessible","publisher":{"@id":"http:\/\/wetransform.to\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/wetransform.to\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"http:\/\/wetransform.to\/de\/#organization","name":"wetransform","url":"http:\/\/wetransform.to\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"http:\/\/wetransform.to\/de\/#\/schema\/logo\/image\/","url":"https:\/\/wetransform.to\/wp-content\/uploads\/2022\/07\/large-logo-whitebg.png","contentUrl":"https:\/\/wetransform.to\/wp-content\/uploads\/2022\/07\/large-logo-whitebg.png","width":1024,"height":1024,"caption":"wetransform"},"image":{"@id":"http:\/\/wetransform.to\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/wetransformto","https:\/\/www.linkedin.com\/company\/wetransform-gmbh\/"]}]}},"_links":{"self":[{"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/news-and-events\/1659","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/news-and-events"}],"about":[{"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/types\/news-and-events"}],"author":[{"embeddable":true,"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/comments?post=1659"}],"version-history":[{"count":11,"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/news-and-events\/1659\/revisions"}],"predecessor-version":[{"id":3755,"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/news-and-events\/1659\/revisions\/3755"}],"wp:attachment":[{"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/media?parent=1659"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/categories?post=1659"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wetransform.to\/de\/wp-json\/wp\/v2\/tags?post=1659"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}