1. Introduction
  2. Layers
      2.1 VectorialData
  3. ViewPort
  4. Events
      4.1 AtomicEvents
  5 Drivers
      5.1 VectorialFileDriver
  6. User interface
      6.1 MapControl
      6.2 MapBehavior
          6.2.1 Creation of a tool from an existing behavior
        6.2.2 Creation of a tool with a nonimplemented behaviour
      6.3 Composition of tools

1. Introduction

    In the FMap package, a map consists of:

In order to obtain an image of a map you have to:

	LayerFactory.setDriversPath("C:\\drivers");
	ViewPort vp = new ViewPort(ProjectionPool.get("ed50utm30"));
vp.setImageSize(new Dimension(100, 100));
FMap mapa = new FMap(vp);
	l = LayerFactory.createLayer("Vias", "DemoSHPDriver", new File("c:\\vias.shp"), ProjectionPool.get("ed50utm30"));
mapa.getLayers().addLayer(l);
	BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
mapa.draw(img, img.createGraphics());

The specific example above corresponds to the ImageFrame of the example "com.iver.cit.gvsig.fmap.DrawImage". To see an example of use of FMap from a complex element of user interface see User interface User interface

2. Layers

    Each map visualizes in an image cartography whose origin can be very different: files, WMS servers, ... In order to add an source of map data to a map we have the concept of Layer. Layers represent an source of map datas regardless of their location and nature. Fmap has a getLayers() method which returns a special layer, consisting of an initially empty number of layers that are used to conduct the operations of drawing, printing, ...
In FMap, a layer is defined by the FLayer interface so that any class that implements the FLayer interface is a layer. In addition to this interface, there is an assembly of interfaces that define the characteristics of a layer. These are in the package "com.iver.cit.gvsig.fmap.layer.layerOperations" and allow to create layers with different capabilities in accordance with the need of the programmer, user, standard, ...
On the other hand, the creation of the layers that initially come with gvSIG is centralized in FLayers having this one static methods to create any of these layers easily.
Once a reference to FLayer is obtained, if you want to conduct a specific operation, you have to verify if this layer implements the interface of the package "com.iver.cit.gvsig.fmap.layer.layerOperations" that gives support to this operation, having to carry out a casting to perform the operation. For example, the following code would delete the selection of all the active layers with support of selection of an Array layers:

		for (Iterator iter = layers.iterator(); iter.hasNext();) {
FLayer layer = (FLayer) iter.next();

if (layer.isActive()) {
if (layer instanceof Selectable) {
((Selectable) layer).clearSelection();
}
}
}

In order to understand completely the operations you can do with layers, read the documentation at the level of the API document of the interfaces of the mentioned package.
(TODO: Put the description of the interfaces here)

2.1 VectorialData

    It should be mentioned the VectorialData interface due to its sophistication. The vectorial layers in FMap may have a sequential source of data or random, depending on the driver used, therefore a selection by rectangle would have to be implemented twice, one for each type of driver. In order to avoid this we have used a mechanism by means of which, the programmer should implement classes that derive from com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor. In this interface there are 3 methods: start, visit and stop. These methods are documented in the API. Let us see a simple example: in order to make a selection by rectangle you will have to:

	public void setRect(Rectangle2D r) {
rect = r;
}
	public boolean start(FLayer layer) {
return layer instanceof Selectable;
}
	public void visit(IGeometry g, int index) {
if (g.intersects(rect)) {
bitset.set(index, true);
} else {
bitset.set(index, false);
}
}
		((Selectable) layer).setSelection(bitset);
		((VectorialData) layer).process(new SelectionByRectVisitor(r));

As you can see, we have not needed to know if the source of the layer is sequential or random. In the package "com.iver.cit.gvsig.fmap.operations.strategies" there are many more examples of FeatureVisitors.

3. ViewPort

    The ViewPort class saves the information relative to transformations from coordinates and data of the current projection. To do this, it stores the size of the image on which it is drawn, the rectangle of visualization, the rectangle adjusted to the visualization frame, etc. It is also responsible for managing "listeners" which listen to the events of change of "extent", and make the calculations of area, perimeter and distance.

4. Events

    FMap provides the programmer with a complete mechanism to know "what it is happening within the map". Each element of FMap has a method of the form addXXXListener, through which the programmer can be registered as observer of the events that happen in the object at hand. For example, the ViewPort has an addViewPortListener that receives a ViewPortListener interface. The class that implements this interface and is registered by means of the method addViewPortListener will be notified of the events of change of extent and change of background color in the ViewPort by means of invocations to the methods of the interface that implements. This presents a problem and to show it we are going to suppose that we have a control of user interface that listens to events of the ViewPort and the collection of layers, so that when a layer it added or the extent modified it draws again the image that it shows. When th efirst layer is added it also modifies the extent therefore in the case of the control of the example the image will unnecessarily be refreshed twice. The solution is the AtomicEvents.

    4.1 AtomicEvents

   In order to solve the previous problem FMap includes two beginAtomicEvent and endAtomicEvent methods. These methods do not affect the management of events of the individual elements of FMap, it affects the management of events from FMap. As with other elements of the package, FMap contains an addAtomicEventListener method with the analogous functionality of the addXXXListener mentioned above. Once registered, the listener will be notified of any event that happens inside that instance of FMap (in the layers, viewport, legend…) with the only difference that it could at the same time be notified of several events. If a piece of code is between the beginAtomicEvent and endAtomicEvent instructions, the individual objects (ViewPort, Layers…) will trigger events in the same way, but the FMap instance will accumulate the events since beginAtomicEvent is executed until endAtomicEvent is executed, and then an AtomicEvent with the embedded accumulated events in the previous will go off. In case that beginAtomicEvent and endAtomicEvent are not used, FMap will not accumulate events, but it will continue triggering them as they are arriving. As an example of listener of AtomicEvent we have the NewMapControl class, which listens to atomic events in the internal class MapContextListener. As example of code that uses beginAtomicEvent and endAtomicEvent we have the method execute of the extension to com.iver.cit.gvsig.Abrir in gvSIG

5 Drivers

    FMap reads the sources of data by means of drivers, which allows anyone to implement a given driver for any existing format. To do this, it is necessary to configure a directory in which the drivers are placed, each one within its directory in the following way:



Each type of driver (vectorial, raster…) has to be implemented by means of a different interface (VectorialFileDriver, WMSDriver…) and besides implementing this interface, other interfaces can be implemented that add an added value to the driver.

5.1 VectorialFileDriver

    In order to create a driver of a vectorial file it is necessary to implement the VectorialFileDriver interface whose methods are documented in the JavaDoc. By means of this interface the driver gains access to the geographic data of the vectorial files. In addition to this interface it is necessary to implement an interface for the access to the alphanumeric data. Depending on how these data are organized, it is possible to implement com.iver.cit.gvsig.fmap.drivers.ExternalData, which is a useful interface for when the alphanumeric data are in a file different from the file of geographic data (case of shapefile), or it is possible to implement com.hardcode.gdbms.engine.data.FileDriver that is adapted for the cases in which the table of alphanumeric data is in the same medium of the geographic data (case of the DGN).

Once implemented these two interfaces, others can be implemented to give an added value to the drivers:


6 User interface

    With the FMap package a series of tools designed for this control is provided along with a control of user interface. MapControl is the user interface on FMap that is provided with gvSIG and automates a great deal of the programming of the graphical interface of a map, sending the drawn one in background, redrawing automatically when the FMap below is invalidated, ... In addition it provides a series of tools prepared for their use and extensible so that the addition of new tools by the user is a trivial process as long as the behavior of the tool is already programmed. In the later sections this will be seen in more detail.

6.1 MapControl

    MapControl is a user control that has as model an instance of FMap which can be accessed by means of the getMapContext() method. Next we present the basic steps to show a Frame with a MapControl without tools. In the following section tools with already existing behaviors will be added and how to add tools with a behavior not programmed yet.

            LayerFactory.setDriversPath(
            "C:\\eclipse3\\workspace\\Andami\\gvSIG\\extensiones\\com.iver.cit.gvsig\\drivers");
                FLayer l = LayerFactory.createLayer("Vias", "gvSIG shp driver",
                    new File("C:/Documents and Settings/fernando/Mis documentos/vias.shp"),
                    ProjectionPool.get("EPSG:23030"));
                newMapControl.getMapContext().getLayers().addLayer(l);
		newMapControl.addMapTool("zoom", new RectangleBehavior(new ZoomInListenerImpl(newMapControl)));
newMapControl.setTool("zoom");

6.2 MapBehaviors

    The tools that are provided in FMap are in fact behaviors. A behavior of the mouse is defined as for example creating a rectangle (RectangleBehavior class), drawing a polyline (PolylineBehavior), etc. and these behaviors trigger events related to their own behavior, for example, the tool to make rectangles -when the user finishes drawing the rectangle -sends an event rectangle defined in the interface to com.iver.cit.gvsig.fmap.tools.RectangleListener. Thus, to implement the tools that have the rectangle drawn behavior (zoom in, selection by rectangle…) only the listeners of the events have to be implemented. In the previous example we have seen how a tool is added to the MapControl by means of the behavior RectangleMapBehavior which takes in its constructor the action that is carried out with the rectangle (approaching the image).

6.2.1 Creation of a tool from an existing behavior

    In order to create a tool with a behavior already implemented, it is necessary to implement the interface that this behavior expects. In order to find out what interface is this, it is necessary to read the documentation of each behavior. In the package "com.iver.cit.gvsig.fmap.tools" there are many examples on how to implement the different interfaces of behaviors.
  
6.2.2 Creation of a tool with a nonimplemented behavior

    In order to make a tool for which there is not a defined behavior there are two approaches:


6.3 Composition of tools

    The model of tools follows a composite pattern. This means that there is a special tool that really consists of a set of tools. Theory apart, this means that we can have several tools selected simultaneously like only one. For example, we can simultaneously have a tool that zoom in, we can simultaneously have the tool which does zoom out with the right button of the mouse and we have one maptool that shows the coordinate of the current position of the mouse. We have an example of this in the View class of gvSIG:

        m_MapControl.addMapTool("zoomIn", new CompoundBehavior(new RectangleBehavior(zil),
new PointBehavior(zoil), new MouseMovementBehavior(sbl)));

That adds the tool composed by the 3 wished simple tools. There is also a convenience method that accepts an Array of Behaviours and creates the CompoundBehavior internally.