The core of each GIS is of course built around the spatial data (duh). So how we access that data (on a programming level) should be of prime importance when designing Ilwis-Objects. Some people would argue that the organization of data is of prime importance but I don’t agree with that. Organization should be a technical derivative of how I want to access my data. I don’t care if there is a database behind my interfaces or a file based system or a service or…. I just want to do things with my data. Organization is important, but only insofar it serves the interfaces.
So what do I require of my interfaces?
- They must be simple! ( remember KISS). This is probably the hardest point. Paradoxical as it may seem but it is far easier to develop a complex set of interfaces than to develop a simple one. Complexity breeds complexity and thus grows at a very fast pace.
- Things that are the same should be the same. This is a cryptic point as it states something obvious. Still, I seldom see a very rigorous implementation of this in the software I am familiar with. E.g. is a (Ilwis3) maplist the same as a rastermap were only the nature of the pixel value is different ( a array instead of a single value)? Arguably yes, so why are there different classes? It gets more interesting with vector maps. Is a point different from a polygon or are two spatial different points always different things? I will investigate this one further down below
- Natural integration within the C++ STL style of programming. The STL is a core library of C++ that (among other things) abstracts algorithms from data types. The reason why this is important is that it generalizes and simplifies the way how we can write algorithms tremendously. For example I rewrote the resample algorithm from over 150 lines of code to 8 lines of code.
So what does this mean in practice? Lets first look at the rasters. One could visualize a maplist like the picture below.
As long as there is the constraint that raster maps in the stack must have the same geometry it is clear that a maplist is nothing else than a rastermap with a different value type. If we accept this than we have met the second criterium for my interfaces and made a first step for the first criterium. The third we haven’t touched yet. We can view a raster ( and thus a maplist) as a container for pixels with a certain organization(the grid). In the STL the primary way of traversing through containers is the iterator.
Basically an iterator accesses each element of a container in a order that is particular for that type of container. The iterator is an abstraction of the ordering of the container and through this abstraction the STL is not aware anymore of the actual nature of the container. If we lift this mechanism to Ilwis-Objects we need to define an iterator for a rasters and thus satisfy criterium 3. As iterators are fairly simple in use, criterium 1 would also be met.
To facilitate this I linearized the whole rastermap (including multiple layers) and made sure that x,y,z are translated into some linear offsets within this system. Most (not all) algorithms follow some fixed order of accessing pixels and through the iterator this can done in an elegant, compact way. The whole mechanism and implications of the pixeliterator, as the class is called, is probably sufficient stuff for a separate blog.
Vectors have undergone an even more radical reorganization. In Ilwis3 vectors had a very simple but also a somewhat naive implementation. A simple linear array of points/lines/polygons. we didn’t support for example multi points (like simple features defines) . Multi-scale or temporal data could only be arranged through multiple vector maps, a bit awkward. Now I did find simple features of OGC also severely lacking. The whole notion of multi features is quite silly in my opinion, at least at the level OGC did it. It mixes semantics and geometry in a totally unnecessary way. Besides that, simple features (and GML/WFS for that matter) let the nature of the preferred container, the relational database, shimmer through its interfaces and organization.
I started by going back to basics what a feature, a word i will now use for vector elements, really is. Is an ice berg moving over the sea observed at different moments really a different thing? Is a bird with a GPS sensor moving around a different thing at the locations it visits? Is a city, modeled as a polygon on regional scale and the same city modeled as a point at world level really a different feature? Nah, don’t think so. In Ilwis-Objects a feature is something with a number of attributes of any domain and one or more geometries that are organized in an array. The index in the array has meaning; time for example, or scale. This means that the feature may show itself differently for different indexes. Indexes are mapped onto a domain and thus can have attributes.
Now the question is, does this conform to the criteria above? The first one yes I would say. In its base form ( one geometry per feature) it is virtually identical to the current simple organization. The whole organization of temporal data (probably the most used one) becomes much more logical as each feature knows its temporal behavior. No need for queries on attributes and such.
The second criterium is certainly met. The same object remains the same object in a data set irrespective of the place or time. No need for vague identifiers to be able query which objects are the same.
The third criterium is met by introducing an iterator that can move both over the features as over the geometries and still present a common return interface so that everything looks identical.
It is important to realize that this organization is independent of the actual data source. The connectors I wrote about earlier take care of that abstraction. I have written scripts in Ilwis-Objects that create and use raster maps that never appear on disk and disappear without leaving a trace ( as intermediate products) because they only exist in the internal representation.
Much more can be said about how these changes interact and simplify the way how algorithms work in Ilwis-Objects but I will leave that for later. Next time I will write a bit about MapCalc 2.0