特征链¶
范围¶
本页描述了“功能链接”的使用,它从简单的组件中组合复杂的功能,特别是处理一些在实践中被证明具有重要意义的需求。
处理单个特征类型中多值属性的多个事例
处理多值属性在其他多值属性中的嵌套
链接相关(通过关联)特征类型,尤其是允许重新使用相关特征类型(例如,O&M模式从采样特征进行了相关观察,但观察本身可能有用)。
当同一引用的属性对象出现在多个包含功能中时,将其编码为链接
消除了对顶级特性及其相关特性的大型非规范化数据存储视图的需求。对于特殊情况,如多对多关系,仍然需要非规范化的视图,但不会太大。
有关非应用程序架构配置,请参阅 数据访问集成 .
映射步骤¶
为每个复杂类型创建映射文件¶
对于要嵌套的复杂类型,我们需要一个映射文件,包括非特性,例如gsml:compositionpart。
不能单独访问的非功能类型(例如,作为数据类型的compositionpart)仍然可以单独映射以实现其可重用性。对于这种情况,包含特征类型必须在其映射文件中包含这些类型。include标记应包含与包含类型映射文件的位置相关的嵌套映射文件路径。在 GeologicUnit_MappingFile.xml
::
<includedTypes>
<Include>CGITermValue_MappingFile.xml</Include>
<Include>CompositionPart_MappingFile.xml</Include>
</includedTypes>
可以单独访问的功能类型不需要显式地包含在映射文件中,因为它们将被配置为供地理服务器查找。这些类型的映射文件将与相应的data store.xml文件相关联,这意味着可以从数据存储注册表中找到它。换句话说,如果该类型与datastore.xml文件相关联,那么如果从另一个映射文件引用,则不需要显式包含该类型。
例子 :
对于此输出: MappedFeature_Output.xml
,以下是映射文件:
地质类型
您可以在geologicUnit特性中看到,gml:composition(组成部分类型)和gsml:geologichistory(geologicevent类型)都是多值属性。它显示了如何在单个特征类型中配置多个多值属性案例。这也证明您可以“链接”非特征类型,因为compositionpart是一种数据类型。
地质通风口类型
gsml:eventEnvironment(cgi-termValue类型)和gsml:eventprocess(也属于cgi-termValue类型)都是多值属性。这也表明“链接”可以在多个层次上完成,因为地质学家Vent嵌套在地质学家内部。请注意,gsml:event age属性被配置为内联属性,因为每个地质事件只能有一个事件期限,因此不需要特征链接。
在嵌套功能类型上配置嵌套¶
在嵌套特征类型中,确保有一个可以被父特征引用的字段。如果没有可以引用的现有字段,则系统字段 FEATURE_LINK 可以映射以保存外键值。这是一个多值字段,因此对于可以由不同父类型嵌套的功能,可以在同一功能类型中映射多个实例。因为这个字段在模式中不存在,所以它不会出现在输出文档中。
在源表达式标记中:
ocql:这个值应该对应于父特性的ocql部分。
示例1 :使用 FEATURE_LINK 在cgi termValue类型中,地质学家vent将其称为gsml:eventprocess和gsml:eventenvironment。
在Geologicevent(容器功能)映射中:
<AttributeMapping>
<targetAttribute>gsml:eventEnvironment</targetAttribute>
<sourceExpression>
<OCQL>id</OCQL>
<linkElement>gsml:CGI_TermValue</linkElement>
<linkField>FEATURE_LINK[1]</linkField>
</sourceExpression>
<isMultiple>true</isMultiple>
</AttributeMapping>
<AttributeMapping>
<targetAttribute>gsml:eventProcess</targetAttribute>
<sourceExpression>
<OCQL>id</OCQL>
<linkElement>gsml:CGI_TermValue</linkElement>
<linkField>FEATURE_LINK[2]</linkField>
</sourceExpression>
<isMultiple>true</isMultiple>
</AttributeMapping>
在cgi-termValue(嵌套功能)映射中:
<AttributeMapping>
<!-- FEATURE_LINK[1] is referred by geologic event as environment -->
<targetAttribute>FEATURE_LINK[1]</targetAttribute>
<sourceExpression>
<OCQL>ENVIRONMENT_OWNER</OCQL>
</sourceExpression>
</AttributeMapping>
<AttributeMapping>
<!-- FEATURE_LINK[2] is referred by geologic event as process -->
<targetAttribute>FEATURE_LINK[2]</targetAttribute>
<sourceExpression><
<OCQL>PROCESS_OWNER</OCQL>
</sourceExpression>
</AttributeMapping>
cgi-termValue视图中的environment_owner列对应于geologicevent视图中的id列。
地质事件属性文件:
id |
GEOLOGIC_UNIT_ID:String |
G名称:字符串 |
ghmaxage:字符串 |
ghage_cdspace:String |
ge.26931120 |
gu.25699 |
渐新世 |
古新世 |
urn:cgi:分类器方案:ics:战略图:2008 |
ge.26930473 |
gu.25678 |
全新世 |
更新世 |
urn:cgi:分类器方案:ics:战略图:2008 |
ge.26930960 |
gu.25678 |
上新世 |
中新世 |
urn:cgi:分类器方案:ics:战略图:2008 |
ge.26932959 |
gu.25678 |
LowerOrdovician |
LowerOrdovician |
urn:cgi:分类器方案:ics:战略图:2008 |
CGI术语值属性文件:
id |
值:字符串 |
PROCESS_OWNER:String |
ENVIRONMENT_OWNER:String |
3 |
河流 |
NULL |
ge.26931120 |
4 |
沼泽/沼泽/沼泽 |
NULL |
ge.26930473 |
5 |
海的 |
NULL |
ge.26930960 |
6 |
海底风扇 |
NULL |
ge.26932959 |
7 |
半远洋的 |
NULL |
ge.26932959 |
8 |
碎屑沉积静水 |
ge.26930473 |
NULL |
9 |
水 [过程] |
ge.26932959 |
NULL |
10 |
渠化水流 |
ge.26931120 |
NULL |
11 |
混浊电流 |
ge.26932959 |
NULL |
系统字段 FEATURE_LINK 不在输出中编码::
<gsml:GeologicEvent>
<gml:name codeSpace="urn:cgi:classifierScheme:GSV:GeologicalUnitId">gu.25699</gml:name>
<gsml:eventAge>
<gsml:CGI_TermRange>
<gsml:lower>
<gsml:CGI_TermValue>
<gsml:value codeSpace="urn:cgi:classifierScheme:ICS:StratChart:2008">Oligocene</gsml:value>
</gsml:CGI_TermValue>
</gsml:lower>
<gsml:upper>
<gsml:CGI_TermValue>
<gsml:value codeSpace="urn:cgi:classifierScheme:ICS:StratChart:2008">Paleocene</gsml:value>
</gsml:CGI_TermValue>
</gsml:upper>
</gsml:CGI_TermRange>
</gsml:eventAge>
<gsml:eventEnvironment>
<gsml:CGI_TermValue>
<gsml:value>fluvial</gsml:value>
</gsml:CGI_TermValue>
</gsml:eventEnvironment>
<gsml:eventProcess>
<gsml:CGI_TermValue>
<gsml:value>channelled stream flow</gsml:value>
</gsml:CGI_TermValue>
</gsml:eventProcess>
例二 :使用现有字段(gml:name)保存外键,请参见 MappedFeature_MappingFile.xml
:
GSML:规范链接到GML:地质名称::
<AttributeMapping>
<targetAttribute>gsml:specification</targetAttribute>
<sourceExpression>
<OCQL>GEOLOGIC_UNIT_ID</OCQL>
<linkElement>gsml:GeologicUnit</linkElement>
<linkField>gml:name[3]</linkField>
</sourceExpression>
</AttributeMapping>
在 GeologicUnit_MappingFile.xml
:
地质学家在映射文件中有3个gml:name属性,因此每个属性都有一个代码空间来澄清它们:
<AttributeMapping>
<targetAttribute>gml:name[1]</targetAttribute>
<sourceExpression>
<OCQL>ABBREVIATION</OCQL>
</sourceExpression>
<ClientProperty>
<name>codeSpace</name>
<value>'urn:cgi:classifierScheme:GSV:GeologicalUnitCode'</value>
</ClientProperty>
</AttributeMapping>
<AttributeMapping>
<targetAttribute>gml:name[2]</targetAttribute>
<sourceExpression>
<OCQL>NAME</OCQL>
</sourceExpression>
<ClientProperty>
<name>codeSpace</name>
<value>'urn:cgi:classifierScheme:GSV:GeologicalUnitName'</value>
</ClientProperty>
</AttributeMapping>
<AttributeMapping>
<targetAttribute>gml:name[3]</targetAttribute>
<sourceExpression>
<OCQL>id</OCQL>
</sourceExpression>
<ClientProperty>
<name>codeSpace</name>
<value>'urn:cgi:classifierScheme:GSV:MappedFeatureReference'</value>
</ClientProperty>
</AttributeMapping>
具有多个gml:name属性及其代码空间的输出:
<gsml:specification>
<gsml:GeologicUnit gml:id="gu.25678">
<gml:description>Olivine basalt, tuff, microgabbro, minor sedimentary rocks</gml:description>
<gml:name codeSpace="urn:cgi:classifierScheme:GSV:GeologicalUnitCode">-Py</gml:name>
<gml:name codeSpace="urn:cgi:classifierScheme:GSV:GeologicalUnitName">Yaugher Volcanic Group</gml:name>
<gml:name codeSpace="urn:cgi:classifierScheme:GSV:MappedFeatureReference">gu.25678</gml:name>
如果这是一对多或多对一数据库关系的“一”方面,我们可以使用功能ID作为源表达式字段,正如您在上面的示例中看到的那样。参见 one_to_many_relationship.JPG
作为一个例子。
如果我们有一个多对多的关系,我们必须对嵌套的每一侧使用一个非规范化视图。这意味着我们可以使用功能ID作为引用字段,或者分配一个列来实现这一目的。参见 many_to_many_relationship.JPG
作为一个例子。
备注
对于多对多关系,不能对嵌套的两侧使用相同的非规范化视图。
通过单独运行嵌套功能类型的GetFeature请求来测试此配置。
在“包含”功能类型上配置嵌套¶
嵌套另一个复杂类型时,需要在源表达式中指定:
OCQL :ogc的数据存储列的公共查询语言表达式
- 链接元素 :
嵌套的元素名称,通常是对应类型的TargetElement或MappingName。
在某些情况下,它必须是OCQL函数(请参见 多态性 )
链接字段 :ocql对应的嵌套元素的索引xpath属性
例子: 地质单元特征中的套料组成部分。
在地质单元绘图文件中:
<AttributeMapping>
<targetAttribute>gsml:composition</targetAttribute>
<sourceExpression>
<OCQL>id</OCQL>
<linkElement>gsml:CompositionPart</linkElement>
<linkField>FEATURE_LINK</linkField>
</sourceExpression>
<isMultiple>true</isMultiple>
</AttributeMapping>
OCQL :id是地质单元id
链接元素 :链接到gsml:compositionpart类型
链接字段 :feature_link,在gsml:compositionpart类型中映射的链接字段,也存储地质单元ID。如果嵌套要素类型中有多个属性,请确保包含索引,例如feature_link [2] .
地质单元属性文件:
id |
缩写:字符串 |
名称:字符串 |
文本描述:字符串 |
gu.25699 |
-上一年 |
火山群 |
橄榄玄武岩、凝灰岩、微辉长岩、小沉积岩 |
gu.25678 |
-上一年 |
火山群 |
橄榄玄武岩、凝灰岩、微辉长岩、小沉积岩 |
组合部件属性文件:
id |
COMPONENT_ROLE:String |
比例:字符串 |
GEOLOGIC_UNIT_ID:String |
cp.167775491936278812 |
夹层组分 |
重要的 |
gu.25699 |
cp.167775491936278856 |
夹层组分 |
少数的 |
gu.25678 |
cp.167775491936278844 |
唯一成分 |
专业 |
gu.25678 |
运行GetFeature请求以测试此配置。检查步骤2中返回的嵌套特性是否在包含特性的内部适当地排列。如果它们不存在,或者抛出异常,请向下滚动并阅读“故障排除”部分。
同一类型的多个映射¶
有时,您可能会发现需要为同一类型使用不同的FeatureTypeMapping实例。您可能有两个需要嵌套的同一类型的不同属性。例如,在gsml:geologicUnit中,有gsml:exposureColor和gsml:outlopcharacter,它们都是gsml:cgi-termValue类型。
这是在 映射文件 进来。不要在包含类型的LinkElement中传入嵌套功能类型的TargetElement,而是指定相应的MappingName。
备注
MappingName具有命名空间意识,并且区分大小写。
当引用的MappingName包含特殊字符(如“—”)时,必须在LinkElement中用单引号将其括起来。例如,<linkelement>'observation-method'<linkelement>。
对于应用程序中的其他MappingName和TargetElement标记,每个MappingName必须是唯一的。
mappingname仅用于标识嵌套类型中的链接类型。对于多个FeatureTypeMapping实例来说,它不是一个解决方案,其中>1个实例可以作为顶级功能进行查询。
当作为顶级功能进行查询时,将使用普通的targetElement。涉及嵌套类型的筛选器仍应在查询的PropertyName部分使用TargetElement。
如果同一映射文件中有一个功能是顶级功能,则在同一映射文件中不能有超过1个相同类型的FeatureTypeMapping。这是因为featureType.xml将查找targetElement,不知道要获取哪个。
上面最后一点的解决方案是将它们分成单独的文件和位置,在预期的顶级功能位置中只有1 featureType.xml。例如。
对于gsml:cgi_TermValue类型,您可以在同一个文件中有两个FeatureTypeMapping实例,因为它不是一个功能类型。
GSML:MappedFeature可以有两个FeatureTypeMapping实例,但它们必须分解为单独的文件。可以作为顶级功能类型进行查询的功能在其位置上将有featureType.xml。
嵌套简单属性¶
您不需要链接多值的简单属性并分别映射它们。原始配置仍然可以工作。
过滤链接特征上的嵌套属性¶
过滤器会像往常一样工作。您可以提供属性的完整xpath,代码将处理这个问题。例如,可以在gsml:mappedFeatureUseCase2a上运行以下筛选器:
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:Function name="contains_text">
<ogc:PropertyName>gsml:specification/gsml:GeologicUnit/gml:description</ogc:PropertyName>
<ogc:Literal>Olivine basalt, tuff, microgabbro, minor sedimentary rocks</ogc:Literal>
</ogc:Function>
<ogc:Literal>1</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
引用的多值属性( XLink:链接 )¶
您可能希望使用功能链接来通过引用设置多值属性。这对于避免循环关系中的无休止循环特别方便。例如,GSML:MappedFeature和GSML:GeologicUnit之间可能存在循环关系。例如。
gsml:mappedFeature具有gsml:geologicUnit作为gsml:specification
gsml:geologicUnit将gsml:mappedFeature作为gsml:occurrence
显然,你只能对关系的一方进行编码,否则你将以一个无休止的循环结束。您需要选择“链”的一端,并使用 xlink:href 作为关系的另一端。
对于这个例子,我们将gsml:geologicUnit嵌套在gsml:mappedFeature中,作为gsml:specification。
像往常一样在容器功能类型映射上设置嵌套::
<AttributeMapping> <targetAttribute>gsml:specification</targetAttribute> <sourceExpression> <OCQL>GEOLOGIC_UNIT_ID</OCQL> <linkElement>gsml:GeologicUnit</linkElement> <linkField>gml:name[2]</linkField> </sourceExpression> </AttributeMapping>在其他映射文件上设置xlink:href作为客户端属性::
<AttributeMapping> <targetAttribute>gsml:occurrence</targetAttribute> <sourceExpression> <OCQL>id</OCQL> <linkElement>gsml:MappedFeature</linkElement> <linkField>gsml:specification</linkField> </sourceExpression> <isMultiple>true</isMultiple> <ClientProperty> <name>xlink:href</name> <value>strConcat('urn:cgi:feature:MappedFeature:', ID)</value> </ClientProperty> </AttributeMapping>
当我们从嵌套特性中获取客户机属性值时,我们必须将其设置为像链接特性一样;但是我们还添加包含 XLink:链接 在属性映射中。代码将检测 XLink:链接 设置,并且不会继续构建嵌套功能的属性,我们将以空属性结束 XLink:链接 客户端属性。
这将是gsml:geologicUnit:的编码结果:
<gsml:GeologicUnit gml:id="gu.25678">
<gsml:occurrence xlink:href="urn:cgi:feature:MappedFeature:mf2"/>
<gsml:occurrence xlink:href="urn:cgi:feature:MappedFeature:mf3"/>
备注
别忘了添加 XLink 在映射文件名称空间部分中,或者可以以stackOverflowException作为 XLink:链接 无法识别客户端属性,映射将无限链。
解析 即使指定了XLink引用,也可以用于强制应用程序模式执行到某个级别的完整功能链接。