Sorry I do not have more time for this, there are a couple spots which seem
really odd to me in your example.

(Collection<Property>) nextFeature.getProperty("kommunenavn").getValue()

I was trying to sort out why this was a collection - it does not match any
of the examples in the javadocs here (
https://docs.geotools.org/latest/javadocs/org/opengis/feature/ComplexAttribute.html
).

Do you have the feature model information (descriptors and types if you are
building by hand, or the XSD if you are building from an XML Schema). I
find I am making too many guesses without a guide :D

It also looks like you are working very hard to query information out of
your data structure; a property accessor should be able to help.

PropertyName xpath = factory.property( "foo/bar" );
   Property bar = xpath.evaluate( attribute );

It is known that GML is very verbose, with many of the examples repeating
information. It took me a while to see the naming convention identifikasjon
vs Identifikasjon. I do not know why there is not a single identifikasjon
with multiplicity 1..N ? Is that a decision the application schema author
made?


--
Jody Garnett


On Tue, 31 Aug 2021 at 13:46, Roar Brænden <roar.brenden...@gmail.com>
wrote:

> Hi,
>
> Thanks for the response Jody.
>
> In my original example there was only one kommunenavn, but here I've found
> one with two kommunenavn's:
>
> <app:kommunenavn>
>    <app:AdministrativEnhetNavn>
>       <app:navn>Hattfjelldal</app:navn>
>       <app:språk>nor</app:språk>
>    </app:AdministrativEnhetNavn>
>    <app:AdministrativEnhetNavn>
>       <app:navn>Aarborte</app:navn>
>       <app:språk>sma</app:språk>
>    </app:AdministrativEnhetNavn>
> </app:kommunenavn>
>
>
> The main goal of my query, is to extract the <app:navn>-element of the
> <app:AdministrativEnhetNavn> where there is an <app:språk>nor</app:språk>.
>
>
> I've prepared an example at Github
> <https://github.com/roarbra/geotools/blob/d2aea334b6e26d252386db0b594dd1034ee33970/modules/unsupported/wfs-ng/src/test/java/org/geotools/data/wfs/KartverketKommuneReader.java>.
> Here I've taken out the main parts, and written it as I would like it to be:
>
> /* Ordinary feature iterator using getProperty to extract
> <app:kommunenummer> and <app:kommunenavn>. */
> /* The content of <app:kommunenavn> must go through findNorskNavn() */
> *try* (FeatureIterator<Feature> features = 
> kommuneSource.getFeatures().features())
> {
> *while* (features.hasNext()) {
> Feature nextFeature = features.next();
> String kommunenr = (String)nextFeature.getProperty("kommunenummer"
> ).getValue();
> String kommunenavn = findNorskNavn((Collection<Property>)nextFeature
> .getProperty("kommunenavn")
> .getValue());
>
>
> System.*out*.printf("%s : %s\n", kommunenr, kommunenavn);
> }
> }
>
> /* Loop through all <app:AdministrativEnhetNavn>, return navn with
> språk=nor. */
> String findNorskNavn(Collection<Property> alleNavn) {
> *for* (Property inner : alleNavn) {
> *if* (matchNorskSprak(inner)) {
> *return* extractNavn(inner);
> }
> }
> *return* "Without norwegian name.";
> }
>
> /* Return true if <app:AdministrativEnhetNavn> contains a
> <app:språk>nor</app:språk> */
> *boolean* matchNorskSprak(Property prop) {
> *for* (Property inner : (Collection<Property>)prop.getValue()) {
> *if* ("språk".equals(inner.getName().getLocalPart())
> && "nor".equals(inner.getValue())) {
> *return* *true*;
> }
> }
> *return* *false*;
> }
>
> /* Return content of <app:navn> within the <app:AdministrativEnhetNavn> */
>      String extractNavn(Property prop) {
> *for* (Property inner : (Collection<Property>)prop.getValue()) {
> *if* ("navn".equals(inner.getName().getLocalPart())) {
> *return* (String) inner.getValue();
> }
> }
> *throw* *new* RuntimeException("There should've been a \"navn\" element."
> );
> }
>
> Any feedback would be welcome.
>
> Regards,
> Roar Brænden
>
>
>
> 31. aug. 2021 kl. 17:35 skrev Jody Garnett <jody.garn...@gmail.com>:
>
> The use of complex features is mostly confined to the app-schema module,
> and that is a good source of test cases and examples.
>
> I helped setup the feature model to enable the app-schema team but did not
> get a chance to work on it beyond that.  The toString representations are
> just to aid with debugging, the important asspect is the relationship
> between the classes to ensure they form a complete descriptive type system.
>
> Some additional comments inline:
>
> On Tue, Aug 31, 2021 at 1:21 AM Roar Brænden <roar.brenden...@gmail.com>
> wrote:
>
>> I have a WFS source that I try to fetch features from. The response is
>> quite complex, and I've been
>> using org.geotools.data.wfs.impl.WFSDataAccessFactory within gt-wfs-ng.
>>
>
> I have not tried gt-wfs-ng with complex features myself I am curious how
> this will go.
>
> I feel there is something wrong about how this xml are represented as a
>> object graph of Property, but there are so many JUnit tests confirming this
>> structure, so I'm not sure how to make it better. There is also a lack of
>> documentation / examples on how the structure should be.
>>
>
> The data structure forms a graph of properties; just the same way you
> could form a data structure using maps and key/value pairs; or layout a
> java object in memory.  They properties do support some use of user data if
> you need to hang additional information on the data structuring during
> processing or parsing etc…
>
> The type system describes how the layout should be in order to be valid.
> It is also responsible for defining the meaning of the values with
> associated description and other “metadata” details.  As a side effect the
> metadata can also describe default values (useful when setting up a new
> data), or additional filters (that can be used to validate that the data
> makes sense).
>
> The last aspect of the data model is the ability to query values out. In
> addition to traversing the data structures this was designed for access via
> xpath (to support WFS xpath property access).
>
> I key test of this as a dynamic type system is if the feature type system
> describes the data structure well enough that you can construct a xpath
> expression to retrieve the content you wish.
>
> Here is an example of what the xml looks like:
>>
>> <wfs:member>
>>     <app:Kommune xmlns:app="
>> http://skjema.geonorge.no/SOSI/produktspesifikasjon/AdmEnheter/4.1";
>> gml:id="kommune_view.357">
>>       <app:identifikasjon>
>>         <app:Identifikasjon>
>>           <app:lokalId>173103</app:lokalId>
>>           <app:navnerom>
>> https://data.geonorge.no/sosi/administrativeenheter/fylker_kommuner</app:navnerom>
>>           <app:versjonId>4.1</app:versjonId>
>>         </app:Identifikasjon>
>>       </app:identifikasjon>
>>       <app:oppdateringsdato>2020-02-07T00:00:00</app:oppdateringsdato>
>>       <app:datauttaksdato>2021-01-04T10:07:10</app:datauttaksdato>
>>       <app:område>
>>         <!--Inlined geometry 'kommune_view.357_APP_OMRÅDE'-->
>>         <gml:Polygon gml:id="kommune_view.357_APP_OMRÅDE"
>> srsName="urn:ogc:def:crs:EPSG::4258">
>>           <gml:exterior>
>>             <gml:LinearRing>
>>               <gml:posList>58.426581 6.605405 .....</gml:posList>
>>             </gml:LinearRing>
>>           </gml:exterior>
>>         </gml:Polygon>
>>       </app:område>
>>       <app:kommunenummer>4207</app:kommunenummer>
>>       <app:kommunenavn>
>>         <app:AdministrativEnhetNavn>
>>           <app:navn>Flekkefjord</app:navn>
>>           <app:språk>nor</app:språk>
>>         </app:AdministrativEnhetNavn>
>>       </app:kommunenavn>
>>       <app:samiskForvaltningsområde>false</app:samiskForvaltningsområde>
>>     </app:Kommune>
>>   </wfs:member>
>>
>>
>> The <wfs:member><app:Kommune> is the root for a singe Feature. When
>> calling getProperties you will get all the child elements of Kommune
>> represented as a subclass of Property. That contains a name, value and
>> binding. This works great for ordinary values as string, dates, boolean
>> and geometry. The problem is when there's a child element, like for
>> instance <app:kommunenavn>.
>>
>
>
> This is represented as a ComplexAttribute and has a Collection as a value.
>> The Collection is actually a Collection of Property's.
>>
>
> I am confused here, do you mean that more than one kommunenavn is
> allowed? Like min occurs 0, max occurs N? If so you should get repeated
> individual properties rather than a single one with a collection value.
>
> Underneath I've tried to represent this. Ordinary Attribute's are written
>> as: "name [type] : value", while ComplexAttribute's are written "name {"
>> with new indentation for their nested properties:
>>
>> samiskForvaltningsområde  [java.lang.Boolean]: false
>> IdentifikasjonPropertyType {
>>   Identifikasjon {
>>     IdentifikasjonType {
>>       lokalId  [java.lang.String]: 173103
>>       navnerom  [java.lang.String]: https://data.geonorge.no/sosi/
>>       versjonId  [java.lang.String]: 4.1
>>     }
>>   }
>> }
>> kommunenummer  [java.lang.String]: 4207
>> AdministrativEnhetNavnPropertyType {
>>   AdministrativEnhetNavn {
>>     AdministrativEnhetNavnType {
>>       navn  [java.lang.String]: Flekkefjord
>>       språk  [java.lang.String]: nor
>>     }
>>   }
>> }
>> oppdateringsdato  [java.sql.Timestamp]: 2020-02-07 01:00:00.0
>> område  [org.locationtech.jts.geom.Polygon]: POLYGON ((58.426581
>> 6.605405,
>> datauttaksdato  [java.sql.Timestamp]: 2021-01-04 11:07:10.0
>>
>
> If you have suggestions for the toStirng representations we welcome pull
> requests; they are mostly used to aid in debugging. With GML and JSON used
> between systems.
>
> I would like "IdentifikasjonPropertyType" to have the name
>> "identifikasjon", and the property IdentifikasjonType is superfluous.
>>
>
> I do not understand, the property is the only real thing (ie data
> structure). The property type describes how it operates.
>
> Do anyone have an idea why it's done like it is today, or do anyone have
>> an opinion about my changes? It would be nice to hear about them.
>>
>
> Thanks for this discussion I hope we can sort out how to accomplish what
> you wish.
>
> Jody
> --
> --
> Jody Garnett
>
>
>
_______________________________________________
GeoTools-Devel mailing list
GeoTools-Devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geotools-devel

Reply via email to