Verwacht het onverwachte – Altova MissionKit lost een mysterie rondom getalformaten op

Elke keer dat u gegevens ontvangt van een externe bron, bestaat de kans dat deze niet in de vorm aankomen die u verwacht. Dit kan speciale aanpassingen vereisen, en het is zeldzaam en onwaarschijnlijk, maar het is belangrijk om een robuuste en betrouwbare oplossing voor data-integratie en -transformatie te creëren.

We hebben letterlijk tientallen .gpx-bestanden verwerkt, elk met honderden coördinaten, met behulp van de mapping-functionaliteit van MapForce, waar we in de blogpost "Webservice als naslagtabel om GPS-gegevens te verfijnen" over schreven. Vervolgens, op een dag, verwerkten we een nieuw bestand en kregen we de onderstaande fout, waardoor de verwerking mislukte:

Door gebruik te maken van de Altova MissionKit om de functies van MapForce en XMLSpy te combineren, konden we het probleem snel identificeren en een oplossing ontwikkelen die we ook in toekomstige mappingprojecten kunnen hergebruiken.

We vermoedden in eerste instantie een probleem met de invoergegevens, dus we openden het bestand in XMLSpy, waar het de tests voor correcte structuur en XML-validatie succesvol doorheen kwam. Gelukkig heeft elk datapunt een unieke tijdstempel, dus we zochten naar 23:06:22, het tijdstip van de laatste set GPS-coördinaten die correct verwerkt werden. Die tijdstempel kwam één keer voor op regel 1772 van het invoerbestand.

Er viel in de brongegevens die direct volgden niets opvallends verkeerd. We hebben simpelweg de volgende datapunkt uitgeschakeld en het bestand opgeslagen om de mapping opnieuw te verwerken:

Deze keer is de mapping succesvol uitgevoerd:

Nu waren we argwanend over de gegevens die door de webservice werden geretourneerd. Zelfs al wordt de webservice beheerd door het National Geospatial Program van de U.S. Geological Survey, het kan zijn dat de onderliggende database ongeldige gegevens bevatte.

We hebben een eenvoudig .csv-bestand in de mapping opgenomen als een alternatieve uitvoer en de resultaten van de hoogteberekeningen voor elke set broncoördinaten toegewezen, om de output van de webservice te onderzoeken.

In een van de regels in het uitvoerbestand "diagnostic.csv" stond dezelfde waarde als in de vorige foutmelding, maar dan tussen aanhalingstekens:

Het is wetenschappelijke notatie! De webservice heeft een getal geretourneerd in wetenschappelijke notatie! De functie voor afronding in onze datamapping, die het resultaat van de webservice verwerkt, vereist decimale invoer.

Conversie van gegevenstypen

Een mogelijke strategie is om een functie te schrijven die het resultaat van de webservice herkent als wetenschappelijke notatie en de numerieke waarde expliciet berekent. De MapForce-foutmelding "Conversie naar decimaal mislukt voor '-1.24202767892712E-06'" suggereert echter een eenvoudigere oplossing.

Dit is een goed moment om na te denken over datatypes. Het web service component in onze mapping geeft duidelijk aan dat het een tekststring retourneert. MapForce voert automatisch typeconversies uit van een string naar een decimale waarde wanneer een mapping een string als invoer koppelt aan een wiskundige formule. In de meeste gevallen hoeven ontwikkelaars hierdoor niet meer expliciet na te denken over typeconversies, omdat de data tussen verschillende formaten wordt verplaatst. In onze mapping heeft MapForce succesvol 178 keer een typeconversie uitgevoerd van een string naar een decimale waarde, voordat het een waarde in wetenschappelijke notatie tegenkwam.

Wetenschappelijke notatie wordt doorgaans gebruikt voor getallen die te groot of te klein zijn om handig in decimale vorm weer te geven. In MapForce specificeert het decimale datatype niet de grootte of waarde van het getal. In plaats daarvan identificeert het het XML-decimale type, een reeks cijfers met een punt als decimale scheidingsteken.

In XML, en in MapForce, ondersteunt het datatype "double" wetenschappelijke notatie. We kunnen gegevens in wetenschappelijke notatie expliciet omzetten naar het datatype "double" en vervolgens het resultaat afronden.

Deze oplossing is eenvoudig te testen met een eenvoudige mapping, waarbij tekstbestanden worden gebruikt voor zowel de invoer als de uitvoer. We hebben een eenvoudige variabele toegevoegd vóór de functie voor afronding van decimale getallen en het datatype van deze variabele is ingesteld op "double". Voor onze eerste test hebben we de gegevens die zijn opgehaald van de USGS-webservice als invoer gebruikt, om dezelfde gegevens te verwerken zonder de webservice-aanroepen onnodig te herhalen. Deze mapping maakt het ook eenvoudig om meer testgevallen te maken met nieuwe invoergegevens.

De mapping is succesvol uitgevoerd en heeft het volgende resultaat opgeleverd:

Maak een gebruikersfunctie

Gebruikersfuncties in MapForce worden gedefinieerd in één mappingbestand en kunnen worden toegevoegd aan de Functiebibliotheek voor gebruik in andere mappingbestanden, zelfs door meerdere gebruikers. Gebruikersfuncties omvatten ook complexe bewerkingen en helpen om de algehele gegevensstroom van een uitgebreid mappingproject veel beter te volgen.

We hadden de eenvoudige web service aanroep al aangepast door de database te kiezen voor het oostelijke of westelijke deel van de Verenigde Staten, afhankelijk van de lengtegraad. Het toevoegen van expliciete datatypes aan het resultaat maakt het aanroepen van getElevation nu nog complexer. We hebben ervoor gekozen om alles te definiëren in een gebruikersfunctie.

Het toepassen van de gebruikersfunctie

In de onderstaande code hebben we de nieuwe functie getElevationUS toegevoegd.

Op dit moment is het goed om te herinneren waarom we in de eerste plaats de hoogte die door de webservice wordt geretourneerd, hebben afgerond. De webservice geeft een waarde in meters, en twee decimalen – of elk centimeter – is minder dan een halve inch.

We hadden de afrondingsbewerking wel in de functie getElevationUS kunnen opnemen, maar de functie zal in de toekomst nuttiger zijn voor het verwerken van data als deze de ruwe hoogtedata niet afrondt.

De resultaten van de herziene mapping worden hieronder weergegeven, met behulp van hetzelfde .gpx-bestand dat aanvankelijk het probleem veroorzaakte. We hebben het uitvoerbestand doorzocht naar "23:06:22", de tijdstempel die we gebruikten om de laatste correcte coördinaten te vinden voordat de fout optrad. Het volgende punt, beginnend bij regel 902, is het punt dat de fout veroorzaakte.

In eerste instantie waren we teleurgesteld, want al die inspanning leek te resulteren in een hoogteverschil dat afgerond 0 was. Vervolgens hebben we de verdachte coördinaten op een Google Maps kaart ingevoerd:

Een deel van de route volgde een brug over een getijdengeul. Zelfs als we de functie getElevationUS in de toekomst niet meer gebruiken voor het verwerken van data, is het zeer waarschijnlijk dat andere .gpx-bestanden voor andere tochten ons over andere getijdengeulen zullen leiden, waar ze mogelijk nog meer zeer kleine hoogtemetingen opleveren.

Als u de tools in wilt gebruiken Altova MissionKit om gebruikersgedefinieerde functies te maken voor uw eigen datamappingen Klik hier om een gratis proefversie te downloaden.