I’m happy to announce the release of DataValues Geo 0.1.1.
DataValues Geo is a library containing value objects to represent geographical information, parsers to turn user input into such value objects, and formatters to turn them back into user consumable representations. It is part of the DataValues set of libraries. For background on this set of libraries, see my recent blog post.
The functionality provided by the library can be subdivided into 3 groups: value objects, parsers and formatters.
These are simple value objects. They all implement the
LatLongValue– Object representing a geographic point specified by latitude and longitude.
GlobeCoordinateValue– Geographical coordinate with precision and globe.
These turn value objects into string representations. They all implement the
GeoCoordinateFormatter– Formats a LatLongValue into float, decimal minute, decimal degree or degree minute second notation. Both directional and non-directional notation are supported. Directional labels, latitude-longitude separator and precision can be specified.
GlobeCoordinateFormatter– Formats a GlobeCoordinateValue.
These turn string representations into value objects. They all implement the
DdCoordinateParser– Parses decimal degree coordinates into LatLongValue objects.
DmCoordinateParser– Parses decimal minute coordinates into LatLongValue objects.
DmsCoordinateParser– Parses degree minute second coordinates into LatLongValue objects.
FloatCoordinateParser– Parses float coordinates into LatLongValue objects.
GeoCoordinateParser– Facade for DdCoordinateParser, DmCoordinateParser, DmsCoordinateParser and FloatCoordinateParser. Parses a coordinate in any of the notations supported by these parsers into a LatLongValue object. Both directional and non-directional notation are supported. Directional labels and the latitude-longitude separator can be specified.
GlobeCoordinateParser– Parses coordinates into GlobeCoordinateValue objects.
In 2009 I wrote the Maps extension. It was initially in part based on the Semantic Layers extension, from which I stole the coordinate parsing code. Or perhaps I stole it from Semantic Google Maps, I can’t remember. The important part is that I stole it from somewhere. I ended up rewriting big parts of the extension rather frequently, as Yaron Koren can attest to. This was to try out various things and solve certain design issues. (Of course, since I did not really have an idea of software design back then, I ended up trading one set of issues for another, without consistently moving in the good direction.) The parsing and formatting of coordinates was the one part that remained untouched for a long time, as I found it rather scary.
At some point I did end up rewriting it all, since some modifications needed to be made. And so MapsCoordinateParser was born. This lovely “class” was fully static, responsible for everything related to coordinate parsing, which I figured included formatting, validation and even geocoding *shiver*.
The first tests I ever wrote where for this class. I had read about this testing thing somewhere and decided to give it a try on this code. Unsurprisingly I got the impression that writing tests is rather hard, and not worth the effort to do for all code. It took quite some time before I tried the testing thing again and learned about how to do it right.
About a year ago, I started working on the concept of creating dedicated value objects, parsers and formatters, that could then be reused by different extensions. One of the initial use cases for this was the coordinate parsing code of Maps, which I wanted to share with the Validator extension. This would then allow for having parameters of a “geographical coordinate” type.
The result of this work was a fresh set of code somewhat based on the code from Maps. Unlike that old code, this was created via Test Driven Development, so has lots of tests. By doing this I found a few bugs in the old Maps code that have been there for years. The new code also correctly separates concerns, avoids tight coupling, enables inversion of control and does not lead to global state. One big step forward.
Current status and future
The Maps and Validator extensions now both make use of this new library. Wikibase, the Wikidata software, also makes use of it, though right now it is still using an older version of DataValues in which the Geo library does not stand on its own. Semantic MediaWiki is a potential user of it as well. Making use of DataValues Geo would fall under the general item of utilizing the DataValues set of libraries.
Of course usage is not restricted to MediaWiki related code, as the library is not dependent, on or even knows about, MediaWiki. I thus hope it is of use to many other people as well!