Personal tools
You are here: Home Development Developers guide gvSIG Internal Libraries Examples of FMAP Usage Spatial Query
Document Actions

Spatial Query

by Grupo gvSIG last modified 2010-06-01 22:52

Spatial queries are very common. For example, we search for features within a determined polygon (the same as searching for something using certain tolerance).

There are several ways to do it and they can be consulted by looking at the codes for the information and selection tools in gvSIG. Here we will show a simple one, especially to demonstrate the FBitMap usage.

The FBitMap class represents a selection of records. It is based on the Bitmap Java class, which contains 0 and 1, a “1” when the record is selected and a “0” when it is not selected. The advantage of this binary storage is the very low memory space taken by the selection and easiness to iterate, count, change the selection, etc.

The disadvantage is that we start from the assumption we always have a random access available to our driver. In other words, the operation to get the umpteenth record is available and fast. That allows us, if there are 10 records selected to obtain their record numbers, get their Feature and do something with them. The problem arises when the data sources do not allow for this type of random access and return their Features in a sequential manner, without knowing how many records will be returned before hand.

That is why we cover BitMap with FBitMap, so in the future we can deliver a selection adapted to databases with random or sequential access.

Then, upon a selection the driver is run from beginning to end while the condition is evaluated (spatial and/or alphanumeric) and the selected records are marked with bitmaps. If any driver were only sequential, we would have to storage the selected records in an array or something similar to avoid searching through the database to position the records, which would be a slow operation.

Nowadays, the drivers in gvSIG are sufficiently fast to allow for random access. Therefore, we can make a query such as:

Point2D p = event.getPoint();
Point2D mapPoint = mapCtrl.getViewPort().toMapPoint((int) p.getX(), (int) p.getY());

// 3 pixels tolerance
double tol = mapCtrl.getViewPort().toMapDistance(3);
FLayer[] actives = mapCtrl.getMapContext()
.getLayers().getActives();
for (int i=0; i < actives.length; i++)
{
    if (actives[i] instanceof FLyrVect) {
        FLyrVect lyrVect = (FLyrVect) actives[i];
        FBitSet oldBitSet = lyrVect.getSource().getRecordset().getSelection();
        FBitSet newBitSet = lyrVect.queryByPoint(mapPoint, tol);
        if (event.getEvent().isControlDown())
            newBitSet.xor(oldBitSet);
        lyrVect.getRecordset().setSelection(newBitSet);
    }
}

This code has been extracted from the com.iver.cit.gvsig.fmap.tools.PointSelectionListener.java class. What is does is to receive a point in pixels, transform it to map coordinates and search through all the active layers. If they are of vector type, it uses the queryByPoint query to obtain the FBitSet (the selection).

Then we can use this selection for anything we want. The search through the selected records is done this way:

SelectableDataSource ds =lyrVect.getRecordset(); 
int idField = ds.getFieldIndexByName("NOM_PROVIN");
FBitSet bs = lyrVect.queryByPoint(mapPoint, tol);
for (int i=bs.nextSetBit(0); i >=0; i=bs.nextSetBit(i+1))
{
    long idRec = i;
    String nom = ds.getFieldValue(idRec, idField).toString();
    dlg.setProvinName(nom);
}

Here we have selected the province that contains the point “mapPoint” and we have search through the selected records, recovering the field value “NOM_PROVIN”.

We will see more examples in chapter 6.


Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: