Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/AbstractLayer.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/AbstractLayer.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/AbstractLayer.java	(revision 29513)
@@ -0,0 +1,87 @@
+package org.openstreetmap.gui.jmapviewer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AbstractLayer {
+    private LayerGroup parent;
+    private String name;
+    private String description;
+    private Style style;
+    private Boolean visible;
+    private Boolean visibleTexts=true;
+    
+    public AbstractLayer(String name){
+        this(name, (String)null);
+    }
+    public AbstractLayer(String name, String description){
+        this(name, description, MapMarkerCircle.getDefaultStyle());
+    }
+    public AbstractLayer(String name, Style style){
+        this(name, null, style);
+    }
+    public AbstractLayer(String name, String description, Style style){
+        this(null, name, description, style);
+    }
+    public AbstractLayer(LayerGroup parent, String name){
+        this(parent, name, MapMarkerCircle.getDefaultStyle());
+    }
+    public AbstractLayer(LayerGroup parent, String name, Style style){
+        this(parent, name, null, style);
+    }
+    public AbstractLayer(LayerGroup parent, String name, String description, Style style){
+        setParent(parent);
+        setName(name);
+        setDescription(description);
+        setStyle(style);
+        setVisible(true);
+
+        if(parent!=null) parent.add(this);
+    }
+    public LayerGroup getParent() {
+        return parent;
+    }
+    public void setParent(LayerGroup parent) {
+        this.parent = parent;
+    }
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+    public String getDescription() {
+        return description;
+    }
+    public void setDescription(String description) {
+        this.description = description;
+    }
+    public Style getStyle() {
+        return style;
+    }
+    public void setStyle(Style style) {
+        this.style = style;
+    }
+    public Boolean isVisible() {
+        return visible;
+    }
+    public void setVisible(Boolean visible) {
+        this.visible = visible;
+    }
+    public static <E> List<E> add(List<E> list, E element) {
+        if(element!=null){
+            if(list==null) list = new ArrayList<E>();
+            if(!list.contains(element)) list.add(element);
+        }
+        return list;
+    }
+    public Boolean isVisibleTexts() {
+        return visibleTexts;
+    }
+    public void setVisibleTexts(Boolean visibleTexts) {
+        this.visibleTexts = visibleTexts;
+    }
+    public String toString(){
+        return name;
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Coordinate.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Coordinate.java	(revision 29512)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Coordinate.java	(revision 29513)
@@ -9,4 +9,6 @@
 import java.io.Serializable;
 
+import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
+
 /**
  * This class encapsulates a Point2D.Double and provide access
@@ -16,5 +18,5 @@
  *
  */
-public class Coordinate implements Serializable {
+public class Coordinate implements Serializable, ICoordinate {
     private transient Point2D.Double data;
 
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Demo.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Demo.java	(revision 29512)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Demo.java	(revision 29513)
@@ -5,4 +5,5 @@
 import java.awt.BorderLayout;
 import java.awt.Cursor;
+import java.awt.Point;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -22,4 +23,5 @@
 import org.openstreetmap.gui.jmapviewer.events.JMVCommandEvent;
 import org.openstreetmap.gui.jmapviewer.interfaces.JMapViewerEventListener;
+import org.openstreetmap.gui.jmapviewer.interfaces.MapPolygon;
 import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
@@ -40,5 +42,5 @@
     private static final long serialVersionUID = 1L;
 
-    private JMapViewer map = null;
+    private JMapViewerTree treeMap = null;
 
     private JLabel zoomLabel=null;
@@ -52,9 +54,9 @@
         setSize(400, 400);
 
-        map = new JMapViewer();
+        treeMap = new JMapViewerTree("Zones");
 
         // Listen to the map viewer for user operations so components will
         // recieve events and update
-        map.addJMVListener(this);
+        map().addJMVListener(this);
 
         // final JMapViewer map = new JMapViewer(new MemoryTileCache(),4);
@@ -71,8 +73,8 @@
 
         mperpLabelName=new JLabel("Meters/Pixels: ");
-        mperpLabelValue=new JLabel(String.format("%s",map.getMeterPerPixel()));
+        mperpLabelValue=new JLabel(String.format("%s",map().getMeterPerPixel()));
 
         zoomLabel=new JLabel("Zoom: ");
-        zoomValue=new JLabel(String.format("%s", map.getZoom()));
+        zoomValue=new JLabel(String.format("%s", map().getZoom()));
 
         add(panel, BorderLayout.NORTH);
@@ -88,53 +90,67 @@
 
             public void actionPerformed(ActionEvent e) {
-                map.setDisplayToFitMapMarkers();
-            }
-        });
-        JComboBox tileSourceSelector = new JComboBox(new TileSource[] { new OsmTileSource.Mapnik(),
+                map().setDisplayToFitMapMarkers();
+            }
+        });
+        JComboBox<TileSource> tileSourceSelector = new JComboBox(new TileSource[] { new OsmTileSource.Mapnik(),
                 new OsmTileSource.CycleMap(), new BingAerialTileSource(), new MapQuestOsmTileSource(), new MapQuestOpenAerialTileSource() });
         tileSourceSelector.addItemListener(new ItemListener() {
             public void itemStateChanged(ItemEvent e) {
-                map.setTileSource((TileSource) e.getItem());
-            }
-        });
-        JComboBox tileLoaderSelector;
+                map().setTileSource((TileSource) e.getItem());
+            }
+        });
+        JComboBox<TileLoader> tileLoaderSelector;
         try {
-            tileLoaderSelector = new JComboBox(new TileLoader[] { new OsmFileCacheTileLoader(map),
-                    new OsmTileLoader(map) });
+            tileLoaderSelector = new JComboBox(new TileLoader[] { new OsmFileCacheTileLoader(map()),
+                    new OsmTileLoader(map()) });
         } catch (IOException e) {
-            tileLoaderSelector = new JComboBox(new TileLoader[] { new OsmTileLoader(map) });
+            tileLoaderSelector = new JComboBox(new TileLoader[] { new OsmTileLoader(map()) });
         }
         tileLoaderSelector.addItemListener(new ItemListener() {
             public void itemStateChanged(ItemEvent e) {
-                map.setTileLoader((TileLoader) e.getItem());
-            }
-        });
-        map.setTileLoader((TileLoader) tileLoaderSelector.getSelectedItem());
+                map().setTileLoader((TileLoader) e.getItem());
+            }
+        });
+        map().setTileLoader((TileLoader) tileLoaderSelector.getSelectedItem());
         panelTop.add(tileSourceSelector);
         panelTop.add(tileLoaderSelector);
         final JCheckBox showMapMarker = new JCheckBox("Map markers visible");
-        showMapMarker.setSelected(map.getMapMarkersVisible());
+        showMapMarker.setSelected(map().getMapMarkersVisible());
         showMapMarker.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                map.setMapMarkerVisible(showMapMarker.isSelected());
+            public void actionPerformed(ActionEvent e) {
+                map().setMapMarkerVisible(showMapMarker.isSelected());
             }
         });
         panelBottom.add(showMapMarker);
+        ///
+        final JCheckBox showTreeLayers = new JCheckBox("Tree Layers visible");
+        showTreeLayers.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                treeMap.setTreeVisible(showTreeLayers.isSelected());
+            }
+        });
+        panelBottom.add(showTreeLayers);
+        ///
+        final JCheckBox showToolTip = new JCheckBox("ToolTip visible");
+        showToolTip.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                map().setToolTipText(null);
+            }
+        });
+        panelBottom.add(showToolTip);
+        ///
         final JCheckBox showTileGrid = new JCheckBox("Tile grid visible");
-        showTileGrid.setSelected(map.isTileGridVisible());
+        showTileGrid.setSelected(map().isTileGridVisible());
         showTileGrid.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                map.setTileGridVisible(showTileGrid.isSelected());
+            public void actionPerformed(ActionEvent e) {
+                map().setTileGridVisible(showTileGrid.isSelected());
             }
         });
         panelBottom.add(showTileGrid);
         final JCheckBox showZoomControls = new JCheckBox("Show zoom controls");
-        showZoomControls.setSelected(map.getZoomContolsVisible());
+        showZoomControls.setSelected(map().getZoomContolsVisible());
         showZoomControls.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                map.setZoomContolsVisible(showZoomControls.isSelected());
+            public void actionPerformed(ActionEvent e) {
+                map().setZoomContolsVisible(showZoomControls.isSelected());
             }
         });
@@ -143,5 +159,5 @@
         scrollWrapEnabled.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
-                map.setScrollWrapEnabled(scrollWrapEnabled.isSelected());
+                map().setScrollWrapEnabled(scrollWrapEnabled.isSelected());
             }
         });
@@ -154,36 +170,66 @@
         panelTop.add(mperpLabelValue);
 
-        add(map, BorderLayout.CENTER);
+        add(treeMap, BorderLayout.CENTER);
 
         //
-        map.addMapMarker(new MapMarkerDot(49.814284999, 8.642065999));
-        map.addMapMarker(new MapMarkerDot(49.91, 8.24));
-        map.addMapMarker(new MapMarkerDot(49.71, 8.64));
-        map.addMapMarker(new MapMarkerDot(48.71, -1));
-        map.addMapMarker(new MapMarkerDot(49.8588, 8.643));
+        LayerGroup germanyGroup = new LayerGroup("Germany");
+        Layer germanyWestLayer = germanyGroup.addLayer("Germany West");
+        Layer germanyEastLayer = germanyGroup.addLayer("Germany East");
+        MapMarkerDot eberstadt = new MapMarkerDot(germanyEastLayer, "Eberstadt", 49.814284999, 8.642065999);
+        MapMarkerDot ebersheim = new MapMarkerDot(germanyWestLayer, "Ebersheim", 49.91, 8.24);
+        MapMarkerDot empty = new MapMarkerDot(germanyEastLayer, 49.71, 8.64);
+        MapMarkerDot darmstadt = new MapMarkerDot(germanyEastLayer, "Darmstadt", 49.8588, 8.643);
+        map().addMapMarker(eberstadt);
+        map().addMapMarker(ebersheim);
+        map().addMapMarker(empty);
+        Layer franceLayer = treeMap.addLayer("France");
+        map().addMapMarker(new MapMarkerDot(franceLayer, "La Gallerie", 48.71, -1));
+        map().addMapMarker(darmstadt);
+        treeMap.addLayer(germanyWestLayer);
+        treeMap.addLayer(germanyEastLayer);
+
+        MapPolygon bermudas = new MapPolygonImpl(c(49,1), c(45,10), c(40,5));
+        map().addMapPolygon( bermudas );
+        map().addMapPolygon( new MapPolygonImpl(germanyEastLayer, "Riedstadt", ebersheim, darmstadt, eberstadt, empty));
+        
+        map().addMapMarker(new MapMarkerCircle(germanyWestLayer, "North of Suisse", new Coordinate(48, 7), .5));
+        Layer spain = treeMap.addLayer("Spain");
+        map().addMapMarker(new MapMarkerCircle(spain, "La Garena", new Coordinate(40.4838, -3.39), .002));
+        spain.setVisible(false);
+        
+        Layer wales = treeMap.addLayer("UK");
+        map().addMapRectangle(new MapRectangleImpl(wales, "Wales", c(53.35,-4.57), c(51.64,-2.63)));
 
         // map.setDisplayPositionByLatLon(49.807, 8.6, 11);
         // map.setTileGridVisible(true);
         
-        map.addMouseListener(new MouseAdapter() {
+        map().addMouseListener(new MouseAdapter() {
             @Override
             public void mouseClicked(MouseEvent e) {
                 if (e.getButton() == MouseEvent.BUTTON1) {
-                    map.getAttribution().handleAttribution(e.getPoint(), true);
+                    map().getAttribution().handleAttribution(e.getPoint(), true);
                 }
             }
         });
         
-        map.addMouseMotionListener(new MouseAdapter() {
+        map().addMouseMotionListener(new MouseAdapter() {
             @Override
             public void mouseMoved(MouseEvent e) {
-                boolean cursorHand = map.getAttribution().handleAttributionCursor(e.getPoint());
+                Point p = e.getPoint();
+                boolean cursorHand = map().getAttribution().handleAttributionCursor(p);
                 if (cursorHand) {
-                    map.setCursor(new Cursor(Cursor.HAND_CURSOR));
+                    map().setCursor(new Cursor(Cursor.HAND_CURSOR));
                 } else {
-                    map.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+                    map().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                 }
-            }
-        });
+                if(showToolTip.isSelected()) map().setToolTipText(map().getPosition(p).toString());
+            }
+        });
+    }
+    private JMapViewer map(){
+        return treeMap.getViewer();
+    }
+    private static Coordinate c(double lat, double lon){
+        return new Coordinate(lat, lon);
     }
 
@@ -200,7 +246,7 @@
     private void updateZoomParameters() {
         if (mperpLabelValue!=null)
-            mperpLabelValue.setText(String.format("%s",map.getMeterPerPixel()));
+            mperpLabelValue.setText(String.format("%s",map().getMeterPerPixel()));
         if (zoomValue!=null)
-            zoomValue.setText(String.format("%s", map.getZoom()));
+            zoomValue.setText(String.format("%s", map().getZoom()));
     }
 
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java	(revision 29512)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java	(revision 29513)
@@ -24,4 +24,5 @@
 import org.openstreetmap.gui.jmapviewer.events.JMVCommandEvent;
 import org.openstreetmap.gui.jmapviewer.events.JMVCommandEvent.COMMAND;
+import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
 import org.openstreetmap.gui.jmapviewer.interfaces.JMapViewerEventListener;
 import org.openstreetmap.gui.jmapviewer.interfaces.MapMarker;
@@ -269,31 +270,37 @@
         if (markers) {
             for (MapMarker marker : mapMarkerList) {
-                int x = OsmMercator.LonToX(marker.getLon(), mapZoomMax);
-                int y = OsmMercator.LatToY(marker.getLat(), mapZoomMax);
-                x_max = Math.max(x_max, x);
-                y_max = Math.max(y_max, y);
-                x_min = Math.min(x_min, x);
-                y_min = Math.min(y_min, y);
-            }
-        }
-
-        if (rectangles) {
-            for (MapRectangle rectangle : mapRectangleList) {
-                x_max = Math.max(x_max, OsmMercator.LonToX(rectangle.getBottomRight().getLon(), mapZoomMax));
-                y_max = Math.max(y_max, OsmMercator.LatToY(rectangle.getTopLeft().getLat(), mapZoomMax));
-                x_min = Math.min(x_min, OsmMercator.LonToX(rectangle.getTopLeft().getLon(), mapZoomMax));
-                y_min = Math.min(y_min, OsmMercator.LatToY(rectangle.getBottomRight().getLat(), mapZoomMax));
-            }
-        }
-
-        if (polygons) {
-            for (MapPolygon polygon : mapPolygonList) {
-                for (Coordinate c : polygon.getPoints()) {
-                    int x = OsmMercator.LonToX(c.getLon(), mapZoomMax);
-                    int y = OsmMercator.LatToY(c.getLat(), mapZoomMax);
+                if(marker.isVisible()){
+                    int x = OsmMercator.LonToX(marker.getLon(), mapZoomMax);
+                    int y = OsmMercator.LatToY(marker.getLat(), mapZoomMax);
                     x_max = Math.max(x_max, x);
                     y_max = Math.max(y_max, y);
                     x_min = Math.min(x_min, x);
                     y_min = Math.min(y_min, y);
+                }
+            }
+        }
+
+        if (rectangles) {
+            for (MapRectangle rectangle : mapRectangleList) {
+                if(rectangle.isVisible()){
+                    x_max = Math.max(x_max, OsmMercator.LonToX(rectangle.getBottomRight().getLon(), mapZoomMax));
+                    y_max = Math.max(y_max, OsmMercator.LatToY(rectangle.getTopLeft().getLat(), mapZoomMax));
+                    x_min = Math.min(x_min, OsmMercator.LonToX(rectangle.getTopLeft().getLon(), mapZoomMax));
+                    y_min = Math.min(y_min, OsmMercator.LatToY(rectangle.getBottomRight().getLat(), mapZoomMax));
+                }
+            }
+        }
+
+        if (polygons) {
+            for (MapPolygon polygon : mapPolygonList) {
+                if(polygon.isVisible()){
+                    for (ICoordinate c : polygon.getPoints()) {
+                        int x = OsmMercator.LonToX(c.getLon(), mapZoomMax);
+                        int y = OsmMercator.LatToY(c.getLat(), mapZoomMax);
+                        x_max = Math.max(x_max, x);
+                        y_max = Math.max(y_max, y);
+                        x_min = Math.min(x_min, x);
+                        y_min = Math.min(y_min, y);
+                    }
                 }
             }
@@ -418,4 +425,22 @@
         return new Point(x, y);
     }
+    
+    /**
+     * Calculates the position on the map of a given coordinate
+     *
+     * @param lat Latitude
+     * @param offset Offset respect Latitude
+     * @param checkOutside
+     * @return Integer the radius in pixels
+     */
+    public Integer getLatOffset(double lat, double offset, boolean checkOutside) {
+        int y = OsmMercator.LatToY(lat+offset, zoom);
+        y -= center.y - getHeight() / 2;
+        if (checkOutside) {
+            if (y < 0 || y > getHeight())
+                return null;
+        }
+        return y;
+    }
 
     /**
@@ -428,4 +453,20 @@
     public Point getMapPosition(double lat, double lon) {
         return getMapPosition(lat, lon, true);
+    }
+    
+    /**
+     * Calculates the position on the map of a given coordinate
+     *
+     * @param marker MapMarker object that define the x,y coordinate
+     * @return Integer the radius in pixels
+     */
+    public Integer getRadius(MapMarker marker, Point p) {
+        if(marker.getMarkerStyle() == MapMarker.STYLE.FIXED)
+            return (int)marker.getRadius();
+        else if(p!=null){
+            Integer radius = getLatOffset(marker.getLat(), marker.getRadius(), false);
+            radius = radius==null?null:p.y-radius.intValue();
+            return radius;
+        }else return null;
     }
 
@@ -450,5 +491,5 @@
      *         and checkOutside set to <code>true</code>
      */
-    public Point getMapPosition(Coordinate coord, boolean checkOutside) {
+    public Point getMapPosition(ICoordinate coord, boolean checkOutside) {
         if (coord != null)
             return getMapPosition(coord.getLat(), coord.getLon(), checkOutside);
@@ -579,5 +620,5 @@
         if (mapPolygonsVisible && mapPolygonList != null) {
             for (MapPolygon polygon : mapPolygonList) {
-                paintPolygon(g, polygon);
+                if(polygon.isVisible()) paintPolygon(g, polygon);
             }
         }
@@ -585,5 +626,5 @@
         if (mapRectanglesVisible && mapRectangleList != null) {
             for (MapRectangle rectangle : mapRectangleList) {
-                paintRectangle(g, rectangle);
+                if(rectangle.isVisible()) paintRectangle(g, rectangle);
             }
         }
@@ -591,5 +632,5 @@
         if (mapMarkersVisible && mapMarkerList != null) {
             for (MapMarker marker : mapMarkerList) {
-                paintMarker(g, marker);
+                if(marker.isVisible())paintMarker(g, marker);
             }
         }
@@ -602,5 +643,6 @@
      */
     protected void paintMarker(Graphics g, MapMarker marker) {
-        Point p = getMapPosition(marker.getLat(), marker.getLon());
+        Point p = getMapPosition(marker.getLat(), marker.getLon(), marker.getMarkerStyle()==MapMarker.STYLE.FIXED);
+        Integer radius = getRadius(marker, p);
         if (scrollWrapEnabled) {
             int tilesize = tileSource.getTileSize();
@@ -608,6 +650,7 @@
             if (p == null) {
                 p = getMapPosition(marker.getLat(), marker.getLon(), false);
-            }
-            marker.paint(g, p);
+                radius = getRadius(marker, p);
+            }
+            marker.paint(g, p, radius);
             int xSave = p.x;
             int xWrap = xSave;
@@ -615,14 +658,14 @@
             while ((xWrap -= mapSize) >= -15) {
                 p.x = xWrap;
-                marker.paint(g, p);
+                marker.paint(g, p, radius);
             }
             xWrap = xSave;
             while ((xWrap += mapSize) <= getWidth() + 15) {
                 p.x = xWrap;
-                marker.paint(g, p);
+                marker.paint(g, p, radius);
             }
         } else {
             if (p != null) {
-                marker.paint(g, p);
+                marker.paint(g, p, radius);
             }
         }
@@ -671,8 +714,8 @@
      */
     protected void paintPolygon(Graphics g, MapPolygon polygon) {
-        List<Coordinate> coords = polygon.getPoints();
+        List<ICoordinate> coords = polygon.getPoints();
         if (coords != null && coords.size() >= 3) {
             List<Point> points = new LinkedList<Point>();
-            for (Coordinate c : coords) {
+            for (ICoordinate c : coords) {
                 Point p = getMapPosition(c, false);
                 if (p == null) {
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewerTree.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewerTree.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewerTree.java	(revision 29513)
@@ -0,0 +1,176 @@
+package org.openstreetmap.gui.jmapviewer;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.List;
+
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JSplitPane;
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+
+import org.openstreetmap.gui.jmapviewer.checkBoxTree.CheckBoxNodePanel;
+import org.openstreetmap.gui.jmapviewer.checkBoxTree.CheckBoxTree;
+import org.openstreetmap.gui.jmapviewer.interfaces.MapObject;
+
+/**
+ * Tree of layers for JMapViewer component
+ * @author galo
+ */
+public class JMapViewerTree extends JPanel{
+    /** Serial Version UID */
+    private static final long serialVersionUID = 3050203054402323972L;
+
+    private JMapViewer map;
+    private CheckBoxTree tree;
+    private JPanel treePanel;
+    private JSplitPane splitPane;
+
+    public JMapViewerTree(String name){
+        this(name, false);
+    }
+    public JMapViewerTree(String name, boolean treeVisible){
+        super();
+        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+        
+        tree = new CheckBoxTree(name);
+        treePanel = new JPanel();
+        treePanel.setLayout(new BorderLayout());
+        treePanel.add(tree, BorderLayout.CENTER);
+        treePanel.add(new JLabel("<html><center>Use right mouse button to<br />show/hide texts</center></html>"), BorderLayout.SOUTH);
+        map = new JMapViewer();
+
+        splitPane.setOneTouchExpandable(true);
+        splitPane.setDividerLocation(150);
+        
+        //Provide minimum sizes for the two components in the split pane
+        Dimension minimumSize = new Dimension(100, 50);
+        //tree.setMinimumSize(minimumSize);
+        map.setMinimumSize(minimumSize);
+        createRefresh();
+        setLayout(new BorderLayout());
+        setTreeVisible(treeVisible);
+        tree.addNodeListener(new MouseAdapter() {
+            public void mousePressed(MouseEvent e) {
+                maybeShowPopup(e);
+            }
+            public void mouseReleased(MouseEvent e) {
+                maybeShowPopup(e);
+            }
+            private void maybeShowPopup(MouseEvent e) {
+                if (e.isPopupTrigger()) {
+                    e.getSource();
+                    AbstractLayer layer = ((CheckBoxNodePanel)e.getComponent()).getData().getAbstractLayer();
+                    if(layer!=null)
+                        JMapViewerTree.this.createPopupMenu(layer).show(e.getComponent(), e.getX(), e.getY());
+                }
+            }
+        });
+    }
+    private JPopupMenu createPopupMenu(final AbstractLayer layer) {
+        JMenuItem menuItemShow = new JMenuItem("show texts");
+        JMenuItem menuItemHide = new JMenuItem("hide texts");
+ 
+        //Create the popup menu.
+        JPopupMenu popup = new JPopupMenu();
+        
+        // Create items
+        if(layer.isVisibleTexts()==null){
+            popup.add(menuItemShow);
+            popup.add(menuItemHide);
+        }else if(layer.isVisibleTexts()) popup.add(menuItemHide);
+        else popup.add(menuItemShow);
+        
+        menuItemShow.addActionListener(new ActionListener(){
+            @Override
+            public void actionPerformed(ActionEvent arg0) {
+                setVisibleTexts(layer, true);
+                if(layer.getParent()!=null) layer.getParent().calculateVisibleTexts();
+                map.repaint();
+            }
+        });
+        menuItemHide.addActionListener(new ActionListener(){
+            @Override
+            public void actionPerformed(ActionEvent arg0) {
+                setVisibleTexts(layer, false);
+                if(layer.getParent()!=null) layer.getParent().calculateVisibleTexts();
+                map.repaint();
+            }
+        });
+ 
+        return popup;
+    }
+    private void setVisibleTexts(AbstractLayer layer, boolean visible){
+        layer.setVisibleTexts(visible);
+        if(layer instanceof LayerGroup){
+            LayerGroup group = (LayerGroup)layer;
+            if(group.getLayers()!=null) for(AbstractLayer al: group.getLayers()) setVisibleTexts(al, visible);
+        }
+    }
+    public Layer addLayer(String name){
+        Layer layer = new Layer(name);
+        this.addLayer(layer);
+        return layer;
+    }
+    public JMapViewerTree addLayer(Layer layer){
+        tree.addLayer(layer);
+        return this;
+    }
+    public JMapViewerTree addLayer(MapObject element){
+        //element.getLayer().add(element);
+        return addLayer(element.getLayer());
+    }
+    public Layer removeFromLayer(MapObject element){
+        element.getLayer().getElements().remove(element);
+        return element.getLayer();
+    }
+    public static int size(List<?> list){
+        return list==null?0:list.size();
+    }
+    public JMapViewer getViewer(){
+        return map;
+    }
+    public CheckBoxTree getTree(){
+        return tree;
+    }
+    public void addMapObject(MapObject o){
+        
+    }
+    public void setTreeVisible(boolean visible){
+        removeAll();
+        revalidate();
+        if(visible){
+            splitPane.setLeftComponent(treePanel);
+            splitPane.setRightComponent(map);
+            add(splitPane, BorderLayout.CENTER);
+        }else add(map, BorderLayout.CENTER);
+        repaint();
+    }
+    private void createRefresh(){
+        tree.getModel().addTreeModelListener(new TreeModelListener() {
+            @Override
+            public void treeNodesChanged(final TreeModelEvent e) {
+                repaint();
+            }
+            @Override
+            public void treeNodesInserted(TreeModelEvent arg0) {
+                // TODO Auto-generated method stub
+            }
+            @Override
+            public void treeNodesRemoved(TreeModelEvent arg0) {
+                // TODO Auto-generated method stub
+            }
+            @Override
+            public void treeStructureChanged(TreeModelEvent arg0) {
+                // TODO Auto-generated method stub
+            }
+        });
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Layer.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Layer.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Layer.java	(revision 29513)
@@ -0,0 +1,42 @@
+package org.openstreetmap.gui.jmapviewer;
+
+import java.util.List;
+
+import org.openstreetmap.gui.jmapviewer.interfaces.MapObject;
+
+public class Layer extends AbstractLayer{
+    private List<MapObject> elements;
+    
+    public Layer(String name){
+        super(name);
+    }
+    public Layer(String name, String description){
+        super(name, description);
+    }
+    public Layer(String name, Style style){
+        super(name, style);
+    }
+    public Layer(String name, String description, Style style){
+        super(name, description, style);
+    }
+    public Layer(LayerGroup parent, String name){
+        super(parent, name);
+    }
+    public Layer(LayerGroup parent, String name, Style style){
+        super(parent, name, style);
+    }
+    public Layer(LayerGroup parent, String name, String description, Style style){
+        super(parent, name, description, style);
+    }
+    public List<MapObject> getElements() {
+        return elements;
+    }
+    public void setElements(List<MapObject> elements) {
+        this.elements = elements;
+    }
+    public Layer add(MapObject element) {
+        element.setLayer(this);
+        elements = add(elements, element);
+        return this;
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/LayerGroup.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/LayerGroup.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/LayerGroup.java	(revision 29513)
@@ -0,0 +1,58 @@
+package org.openstreetmap.gui.jmapviewer;
+
+import java.util.List;
+
+public class LayerGroup extends AbstractLayer{
+    private List<AbstractLayer> layers;
+    
+    public LayerGroup(String name){
+        super(name);
+    }
+    public LayerGroup(String name, String description){
+        super(name, description);
+    }
+    public LayerGroup(String name, Style style){
+        super(name, style);
+    }
+    public LayerGroup(String name, String description, Style style){
+        super(name, description, style);
+    }
+    public LayerGroup(LayerGroup parent, String name){
+        super(parent, name);
+    }
+    public LayerGroup(LayerGroup parent, String name, String description, Style style){
+        super(name, description, style);
+    }
+    public List<AbstractLayer> getLayers() {
+        return layers;
+    }
+    public void setElements(List<AbstractLayer> layers) {
+        this.layers = layers;
+    }
+    public Layer addLayer(String name) {
+        Layer layer = new Layer(this, name);
+        layers = add(layers, layer);
+        return layer;
+    }
+    public LayerGroup add(AbstractLayer layer) {
+        layer.setParent(this);
+        layers = add(layers, layer);
+        return this;
+    }
+    public void calculateVisibleTexts(){
+        Boolean calculate=null;
+        if(layers!=null&&layers.size()>0){
+            calculate=layers.get(0).isVisibleTexts();
+            for(int i=1;i<layers.size(); i++){
+                calculate = resultOf(calculate, layers.get(i).isVisibleTexts());
+            }
+        }
+        setVisibleTexts(calculate);
+        if(getParent()!=null) getParent().calculateVisibleTexts();
+    }
+    public Boolean resultOf(Boolean b1, Boolean b2){
+        if(b1==null||b2==null) return null;
+        else if(b1.booleanValue() == b2.booleanValue()) return b1.booleanValue();
+        else return null;
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapMarkerCircle.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapMarkerCircle.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapMarkerCircle.java	(revision 29513)
@@ -0,0 +1,102 @@
+package org.openstreetmap.gui.jmapviewer;
+
+//License: GPL. Copyright 2008 by Jan Peter Stotz
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+
+import org.openstreetmap.gui.jmapviewer.interfaces.MapMarker;
+
+/**
+ * A simple implementation of the {@link MapMarker} interface. Each map marker
+ * is painted as a circle with a black border line and filled with a specified
+ * color.
+ *
+ * @author Jan Peter Stotz
+ *
+ */
+public class MapMarkerCircle extends MapObjectImpl implements MapMarker {
+
+    Coordinate coord;
+    double radius;
+    STYLE markerStyle;
+
+    public MapMarkerCircle(String name, Coordinate coord, double radius) {
+        this(null, name, coord, radius);
+    }
+    public MapMarkerCircle(Layer layer, Coordinate coord, double radius) {
+        this(layer, null, coord, radius);
+    }
+    public MapMarkerCircle(Layer layer, double lat, double lon, double radius) {
+        this(layer, null, new Coordinate(lat,lon), radius);
+    }
+    public MapMarkerCircle(Layer layer, String name, Coordinate coord, double radius) {
+        this(layer, name, coord, radius, STYLE.VARIABLE, getDefaultStyle());
+    }
+    public MapMarkerCircle(Layer layer, String name, Coordinate coord, double radius, STYLE markerStyle, Style style) {
+        super(layer, name, style);
+        this.markerStyle = markerStyle;
+        this.coord = coord;
+        this.radius = radius;
+    }
+
+    public Coordinate getCoordinate(){
+        return coord;
+    }
+    public double getLat() {
+        return coord.getLat();
+    }
+
+    public double getLon() {
+        return coord.getLon();
+    }
+    
+    public double getRadius() {
+        return radius;
+    }
+    
+    public STYLE getMarkerStyle() {
+        return markerStyle;
+    }
+
+    public void paint(Graphics g, Point position, int radio) {
+        int size_h = radio;
+        int size = size_h * 2;
+        
+        if (g instanceof Graphics2D && getBackColor()!=null) {
+            Graphics2D g2 = (Graphics2D) g;
+            Composite oldComposite = g2.getComposite();
+            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
+            g2.setPaint(getBackColor());
+            g.fillOval(position.x - size_h, position.y - size_h, size, size);
+            g2.setComposite(oldComposite);
+        }
+        g.setColor(getColor());
+        g.drawOval(position.x - size_h, position.y - size_h, size, size);
+        
+        if(getLayer()==null||getLayer().isVisibleTexts()) paintText(g, position);
+    }
+
+    public static Style getDefaultStyle(){
+        return new Style(Color.ORANGE, new Color(200,200,200,200), null, getDefaultFont());
+    }
+    @Override
+    public String toString() {
+        return "MapMarker at " + getLat() + " " + getLon();
+    }
+    @Override
+    public void setLat(double lat) {
+        if(coord==null) coord = new Coordinate(lat,0);
+        else coord.setLat(lat);
+    }
+    @Override
+    public void setLon(double lon) {
+        if(coord==null) coord = new Coordinate(0,lon);
+        else coord.setLon(lon);
+    }
+
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapMarkerDot.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapMarkerDot.java	(revision 29512)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapMarkerDot.java	(revision 29513)
@@ -4,6 +4,4 @@
 
 import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Point;
 
 import org.openstreetmap.gui.jmapviewer.interfaces.MapMarker;
@@ -17,42 +15,29 @@
  *
  */
-public class MapMarkerDot implements MapMarker {
+public class MapMarkerDot extends MapMarkerCircle {
 
-    double lat;
-    double lon;
-    Color color;
+    public static final int DOT_RADIUS = 5;
 
-    public MapMarkerDot(double lat, double lon) {
-        this(Color.YELLOW, lat, lon);
+    public MapMarkerDot(String name, Coordinate coord) {
+        this(null, name, coord);
     }
-
-    public MapMarkerDot(Color color, double lat, double lon) {
-        super();
-        this.color = color;
-        this.lat = lat;
-        this.lon = lon;
+    public MapMarkerDot(Layer layer, Coordinate coord) {
+        this(layer, null, coord);
     }
-
-    public double getLat() {
-        return lat;
+    public MapMarkerDot(Layer layer, String name, Coordinate coord) {
+        this(layer, name, coord, getDefaultStyle());
     }
-
-    public double getLon() {
-        return lon;
+    public MapMarkerDot(Layer layer, double lat, double lon) {
+        this(layer, null, lat, lon);
     }
-
-    public void paint(Graphics g, Point position) {
-        int size_h = 5;
-        int size = size_h * 2;
-        g.setColor(color);
-        g.fillOval(position.x - size_h, position.y - size_h, size, size);
-        g.setColor(Color.BLACK);
-        g.drawOval(position.x - size_h, position.y - size_h, size, size);
+    public MapMarkerDot(Layer layer, String name, double lat, double lon) {
+        this(layer, name, new Coordinate(lat, lon), getDefaultStyle());
     }
-
-    @Override
-    public String toString() {
-        return "MapMarker at " + lat + " " + lon;
+    public MapMarkerDot(Layer layer, String name, Coordinate coord, Style style) {
+        super(layer, name, coord, DOT_RADIUS, STYLE.FIXED, style);
     }
-
+    
+    public static Style getDefaultStyle(){
+        return new Style(Color.BLACK, Color.YELLOW, null, getDefaultFont());
+    }
 }
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapObjectImpl.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapObjectImpl.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapObjectImpl.java	(revision 29513)
@@ -0,0 +1,105 @@
+package org.openstreetmap.gui.jmapviewer;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Stroke;
+
+import javax.swing.UIManager;
+
+public abstract class MapObjectImpl {
+    private Layer layer;
+    private String name;
+    private Style style;
+    private Boolean visible;
+
+    public MapObjectImpl(String name) {
+        this(null, name, null);
+    }
+    public MapObjectImpl(Layer layer) {
+        this(layer, null, null);
+    }
+    public MapObjectImpl(Layer layer, String name, Style style) {
+        super();
+        this.layer = layer;
+        this.name = name;
+        this.style = style;
+    }
+    public Layer getLayer() {
+        return layer;
+    }
+    public void setLayer(Layer layer) {
+        this.layer = layer;
+    }
+    public Style getStyle(){
+        return style;
+    }
+    public Style getStyleAssigned(){
+        return style==null?layer.getStyle():style;
+    }
+    public void setStyle(Style style){
+        this.style = style;
+    }
+    public Color getColor() {
+        return getStyleAssigned().getColor();
+    }
+    public void setColor(Color color) {
+        if(style==null&&color!=null) style=new Style();
+        if(style!=null) style.setColor(color);
+    }
+
+    public Color getBackColor() {
+        return getStyleAssigned().getBackColor();
+    }
+    public void setBackColor(Color backColor) {
+        if(style==null&&backColor!=null) style=new Style();
+        if(style!=null) style.setBackColor(backColor);
+    }
+
+    public Stroke getStroke() {
+        return getStyleAssigned().getStroke();
+    }
+    public void setStroke(Stroke stroke) {
+        if(style==null&&stroke!=null) style=new Style();
+        if(style!=null) style.setStroke(stroke);
+    }
+    
+    public Font getFont() {
+        return getStyleAssigned().getFont();
+    }
+    public void setFont(Font font) {
+        if(style==null&&font!=null) style=new Style();
+        if(style!=null) style.setFont(font);
+    }
+    private boolean isVisibleLayer(){
+        return layer==null||layer.isVisible()==null?true:layer.isVisible();
+    }
+    public boolean isVisible() {
+        return visible==null?isVisibleLayer():visible.booleanValue();
+    }
+    public void setVisible(Boolean visible) {
+        this.visible = visible;
+    }
+    public String getName() {
+        return name;
+    }
+    public void setName(String txt) {
+        this.name = txt;
+    }
+    public static Font getDefaultFont(){
+        Font f = UIManager.getDefaults().getFont("TextField.font");
+        return new Font(f.getName(), Font.BOLD, f.getSize());
+    }
+    public void paintText(Graphics g, Point position) {
+        if(name!=null && g!=null && position!=null){
+            if(getFont()==null){
+                Font f = getDefaultFont(); // g.getFont();
+                setFont(new Font(f.getName(), Font.BOLD, f.getSize()));
+            }
+            g.setColor(Color.DARK_GRAY);
+            g.setFont(getFont());
+            g.drawString(name, position.x+MapMarkerDot.DOT_RADIUS+2, position.y+MapMarkerDot.DOT_RADIUS);
+        }
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapPolygonImpl.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapPolygonImpl.java	(revision 29512)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapPolygonImpl.java	(revision 29513)
@@ -2,13 +2,18 @@
 package org.openstreetmap.gui.jmapviewer;
 
+import java.awt.AlphaComposite;
 import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Composite;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Polygon;
+import java.awt.Rectangle;
 import java.awt.Stroke;
+import java.util.Arrays;
 import java.util.List;
 
+import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
 import org.openstreetmap.gui.jmapviewer.interfaces.MapPolygon;
 
@@ -17,18 +22,29 @@
  *
  */
-public class MapPolygonImpl implements MapPolygon {
+public class MapPolygonImpl extends MapObjectImpl implements MapPolygon {
 
-    private List<Coordinate> points;
-    private Color color;
-    private Stroke stroke;
+    private List<ICoordinate> points;
 
-    public MapPolygonImpl(List<Coordinate> points) {
-        this(points, Color.BLUE, new BasicStroke(2));
+    public MapPolygonImpl(ICoordinate ... points) {
+        this(null, null, points);
     }
-
-    public MapPolygonImpl(List<Coordinate> points, Color color, Stroke stroke) {
+    public MapPolygonImpl(String name, List<ICoordinate> points) {
+        this(null, name, points);
+    }
+    public MapPolygonImpl(String name, ICoordinate ... points) {
+        this(null, name, points);
+    }
+    public MapPolygonImpl(Layer layer, List<ICoordinate> points) {
+        this(layer, null, points);
+    }
+    public MapPolygonImpl(Layer layer, String name, List<ICoordinate> points) {
+        this(layer, name, points, getDefaultStyle());
+    }
+    public MapPolygonImpl(Layer layer, String name, ICoordinate ... points) {
+        this(layer, name, Arrays.asList(points), getDefaultStyle());
+    }
+    public MapPolygonImpl(Layer layer, String name, List<ICoordinate> points, Style style) {
+        super(layer, name, style);
         this.points = points;
-        this.color = color;
-        this.stroke = stroke;
     }
 
@@ -37,5 +53,5 @@
      */
     @Override
-    public List<Coordinate> getPoints() {
+    public List<ICoordinate> getPoints() {
         return this.points;
     }
@@ -60,13 +76,22 @@
         // Prepare graphics
         Color oldColor = g.getColor();
-        g.setColor(color);
+        g.setColor(getColor());
+        
         Stroke oldStroke = null;
         if (g instanceof Graphics2D) {
             Graphics2D g2 = (Graphics2D) g;
             oldStroke = g2.getStroke();
-            g2.setStroke(stroke);
+            g2.setStroke(getStroke());
         }
         // Draw
         g.drawPolygon(polygon);
+        if (g instanceof Graphics2D && getBackColor()!=null) {
+            Graphics2D g2 = (Graphics2D) g;
+            Composite oldComposite = g2.getComposite();
+            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
+            g2.setPaint(getBackColor());
+            g2.fillPolygon(polygon);
+            g2.setComposite(oldComposite);
+        }
         // Restore graphics
         g.setColor(oldColor);
@@ -74,6 +99,13 @@
             ((Graphics2D) g).setStroke(oldStroke);
         }
+        Rectangle rec = polygon.getBounds();
+        Point corner = rec.getLocation();
+        Point p= new Point(corner.x+(rec.width/2), corner.y+(rec.height/2));
+        if(getLayer()==null||getLayer().isVisibleTexts()) paintText(g, p);
     }
 
+    public static Style getDefaultStyle(){
+        return new Style(Color.BLUE, new Color(100,100,100,50), new BasicStroke(2), getDefaultFont());
+    }
     /* (non-Javadoc)
      * @see java.lang.Object#toString()
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapRectangleImpl.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapRectangleImpl.java	(revision 29512)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/MapRectangleImpl.java	(revision 29513)
@@ -7,4 +7,5 @@
 import java.awt.Graphics2D;
 import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.Stroke;
 
@@ -15,20 +16,22 @@
  *
  */
-public class MapRectangleImpl implements MapRectangle {
+public class MapRectangleImpl extends MapObjectImpl implements MapRectangle {
 
     private Coordinate topLeft;
     private Coordinate bottomRight;
-    private Color color;
-    private Stroke stroke;
 
-    public MapRectangleImpl(Coordinate topLeft, Coordinate bottomRight) {
-        this(topLeft, bottomRight, Color.BLUE, new BasicStroke(2));
+    public MapRectangleImpl(String name, Coordinate topLeft, Coordinate bottomRight) {
+        this(null, name, topLeft, bottomRight);
     }
-
-    public MapRectangleImpl(Coordinate topLeft, Coordinate bottomRight, Color color, Stroke stroke) {
+    public MapRectangleImpl(Layer layer, Coordinate topLeft, Coordinate bottomRight) {
+        this(layer, null, topLeft, bottomRight);
+    }
+    public MapRectangleImpl(Layer layer, String name, Coordinate topLeft, Coordinate bottomRight) {
+        this(layer, name, topLeft, bottomRight, getDefaultStyle());
+    }
+    public MapRectangleImpl(Layer layer, String name, Coordinate topLeft, Coordinate bottomRight, Style style) {
+        super(layer, name, style);
         this.topLeft = topLeft;
         this.bottomRight = bottomRight;
-        this.color = color;
-        this.stroke = stroke;
     }
 
@@ -56,10 +59,10 @@
         // Prepare graphics
         Color oldColor = g.getColor();
-        g.setColor(color);
+        g.setColor(getColor());
         Stroke oldStroke = null;
         if (g instanceof Graphics2D) {
             Graphics2D g2 = (Graphics2D) g;
             oldStroke = g2.getStroke();
-            g2.setStroke(stroke);
+            g2.setStroke(getStroke());
         }
         // Draw
@@ -70,6 +73,12 @@
             ((Graphics2D) g).setStroke(oldStroke);
         }
+        int width=bottomRight.x-topLeft.x;
+        int height=bottomRight.y-topLeft.y;
+        Point p= new Point(topLeft.x+(width/2), topLeft.y+(height/2));
+        if(getLayer()==null||getLayer().isVisibleTexts()) paintText(g, p);
     }
-
+    public static Style getDefaultStyle(){
+        return new Style(Color.BLUE, null, new BasicStroke(2), getDefaultFont());
+    }
     @Override
     public String toString() {
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Style.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Style.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Style.java	(revision 29513)
@@ -0,0 +1,61 @@
+package org.openstreetmap.gui.jmapviewer;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Stroke;
+
+public class Style {
+    private Color color;
+    private Color backColor;
+    private Stroke stroke;
+    private Font font;
+    
+    private static final AlphaComposite TRANSPARENCY = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
+    private static final AlphaComposite OPAQUE = AlphaComposite.getInstance(AlphaComposite.SRC);
+
+    public Style(){
+        super();
+    }
+    public Style(Color color, Color backColor, Stroke stroke, Font font) {
+        super();
+        this.color = color;
+        this.backColor = backColor;
+        this.stroke = stroke;
+        this.font = font;
+    }
+
+    public Color getColor() {
+        return color;
+    }
+    public void setColor(Color color) {
+        this.color = color;
+    }
+    public Color getBackColor() {
+        return backColor;
+    }
+    public void setBackColor(Color backColor) {
+        this.backColor = backColor;
+    }
+    public Stroke getStroke() {
+        return stroke;
+    }
+    public void setStroke(Stroke stroke) {
+        this.stroke = stroke;
+    }
+    public Font getFont() {
+        return font;
+    }
+    public void setFont(Font font) {
+        this.font = font;
+    }
+    private AlphaComposite getAlphaComposite(Color color){
+        return color.getAlpha()==255?OPAQUE:TRANSPARENCY;
+    }
+    public AlphaComposite getAlphaComposite(){
+        return getAlphaComposite(color);
+    }
+    public AlphaComposite getBackAlphaComposite(){
+        return getAlphaComposite(backColor);
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeData.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeData.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeData.java	(revision 29513)
@@ -0,0 +1,44 @@
+package org.openstreetmap.gui.jmapviewer.checkBoxTree;
+
+import org.openstreetmap.gui.jmapviewer.AbstractLayer;
+import org.openstreetmap.gui.jmapviewer.LayerGroup;
+
+/**
+ * Node Data for checkBox Tree
+ * 
+ * @author galo
+ */
+public class CheckBoxNodeData {
+    private AbstractLayer layer;
+
+    public CheckBoxNodeData(final AbstractLayer layer) {
+        this.layer = layer;
+    }
+    public CheckBoxNodeData(final String txt) {
+        this(new LayerGroup(txt));
+    }
+    public CheckBoxNodeData(final String txt, final Boolean selected) {
+        this(new LayerGroup(txt));
+        layer.setVisible(selected);
+    }
+    public Boolean isSelected() {
+            return layer.isVisible();
+    }
+    public void setSelected(final Boolean newValue) {
+        System.out.println("CheckBoxNodeData "+layer+" changed to "+newValue);
+        layer.setVisible(newValue);
+    }
+    public String getText() {
+            return layer.getName();
+    }
+    public AbstractLayer getAbstractLayer() {
+        return layer;
+}
+    public void setAbstractLayer(final AbstractLayer layer) {
+            this.layer = layer;
+    }
+    @Override
+    public String toString() {
+            return getClass().getSimpleName() + "[" + getText() + "/" + isSelected() + "]";
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeEditor.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeEditor.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeEditor.java	(revision 29513)
@@ -0,0 +1,101 @@
+package org.openstreetmap.gui.jmapviewer.checkBoxTree;
+
+import java.awt.Component;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.EventObject;
+
+import javax.swing.AbstractCellEditor;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeCellEditor;
+import javax.swing.tree.TreePath;
+
+/**
+ * Editor for checkBox Tree
+ * 
+ * @author galo
+ */
+public class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor{
+    /** SerialVersionUID */
+    private static final long serialVersionUID = -8921320784224636657L;
+
+    private final CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
+
+    private final CheckBoxTree theTree;
+
+    public CheckBoxNodeEditor(final CheckBoxTree tree) {
+        theTree = tree;
+    }
+
+    @Override
+    public Object getCellEditorValue() {
+        final CheckBoxNodePanel panel = renderer.getPanel();
+        /*final CheckBoxNodeData checkBoxNode =
+            new CheckBoxNodeData(panel.label.getText(), panel.check.isSelected());
+        return checkBoxNode;
+        CheckBoxNodeData data = search(theTree.rootNode(), panel.label.getText());
+        data.setSelected(panel.check.isSelected());*/
+        return panel.getData();
+    }
+    /*public CheckBoxNodeData search(DefaultMutableTreeNode node, String name){
+        CheckBoxNodeData data = CheckBoxTree.data(node);
+        if(data.getText().equals(name)) return data;
+        else{
+            data = null;
+            for(int i=0; i<node.getChildCount() && data==null; i++){
+                data = search((DefaultMutableTreeNode)node.getChildAt(i), name);
+            }
+            return data;
+        }
+    }*/
+    public void addNodeListener(MouseAdapter listener){
+        renderer.addNodeListener(listener);
+    }
+    @Override
+    public boolean isCellEditable(final EventObject event) {
+        if (!(event instanceof MouseEvent)) return false;
+        final MouseEvent mouseEvent = (MouseEvent) event;
+
+        final TreePath path =
+            theTree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
+        if (path == null) return false;
+
+        final Object node = path.getLastPathComponent();
+        if (!(node instanceof DefaultMutableTreeNode)) return false;
+        final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
+
+        final Object userObject = treeNode.getUserObject();
+        return userObject instanceof CheckBoxNodeData;
+    }
+
+    @Override
+    public Component getTreeCellEditorComponent(final JTree tree,
+        final Object value, final boolean selected, final boolean expanded,
+        final boolean leaf, final int row)
+    {
+
+        final Component editor =
+            renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf,
+                row, true);
+
+        // editor always selected / focused
+        final ItemListener itemListener = new ItemListener() {
+
+            @Override
+            public void itemStateChanged(final ItemEvent itemEvent) {
+                if (stopCellEditing()) {
+                    fireEditingStopped();
+                }
+            }
+        };
+        if (editor instanceof CheckBoxNodePanel) {
+            final CheckBoxNodePanel panel = (CheckBoxNodePanel) editor;
+            panel.check.addItemListener(itemListener);
+        }
+
+        return editor;
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodePanel.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodePanel.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodePanel.java	(revision 29513)
@@ -0,0 +1,48 @@
+package org.openstreetmap.gui.jmapviewer.checkBoxTree;
+
+import java.awt.BorderLayout;
+import java.awt.Insets;
+
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+/**
+ * Node Panel for checkBox Tree
+ * 
+ * @author galo
+ */
+public class CheckBoxNodePanel extends JPanel {
+    /** Serial Version UID */
+    private static final long serialVersionUID = -7236481597785619029L;
+    private final JLabel label = new JLabel();
+    private CheckBoxNodeData data;
+    public final JCheckBox check = new JCheckBox();
+
+    public CheckBoxNodePanel() {
+        this.check.setMargin(new Insets(0, 0, 0, 0));
+        setLayout(new BorderLayout());
+        add(check, BorderLayout.WEST);
+        add(label, BorderLayout.CENTER);
+    }
+    public void setSelected(Boolean bool){
+        if(bool==null){
+            check.getModel().setPressed(true);
+            check.getModel().setArmed(true);
+        }else{
+            check.setSelected(bool.booleanValue());
+            check.getModel().setArmed(false);
+        }
+    }
+    public CheckBoxNodeData getData() {
+        data.setSelected(check.isSelected());
+        return data;
+    }
+    public void setData(CheckBoxNodeData data) {
+        this.data = data;
+        label.setText(data.getText());
+    }
+    public JLabel getLabel() {
+        return label;
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeRenderer.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeRenderer.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxNodeRenderer.java	(revision 29513)
@@ -0,0 +1,127 @@
+package org.openstreetmap.gui.jmapviewer.checkBoxTree;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JTree;
+import javax.swing.UIManager;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreeCellRenderer;
+
+import org.openstreetmap.gui.jmapviewer.AbstractLayer;
+import org.openstreetmap.gui.jmapviewer.LayerGroup;
+
+/**
+ * Renderer for checkBox Tree
+ * 
+ * @author galo
+ */
+public class CheckBoxNodeRenderer implements TreeCellRenderer{
+
+    private final CheckBoxNodePanel panel = new CheckBoxNodePanel();
+    private final DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
+    private final Color selectionForeground, selectionBackground;
+    private final Color textForeground, textBackground;
+
+    protected CheckBoxNodePanel getPanel() {
+        return panel;
+    }
+
+    public CheckBoxNodeRenderer() {
+        final Font fontValue = UIManager.getFont("Tree.font");
+        if (fontValue != null) panel.getLabel().setFont(fontValue);
+
+        final Boolean focusPainted =
+            (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
+        panel.check.setFocusPainted(focusPainted != null && focusPainted);
+
+        selectionForeground = UIManager.getColor("Tree.selectionForeground");
+        selectionBackground = UIManager.getColor("Tree.selectionBackground");
+        textForeground = UIManager.getColor("Tree.textForeground");
+        textBackground = UIManager.getColor("Tree.textBackground");
+    }
+    public void addNodeListener(MouseAdapter listener){
+        panel.addMouseListener(listener);
+    }
+    // -- TreeCellRenderer methods --
+
+    @Override
+    public Component getTreeCellRendererComponent(final JTree tree,
+        final Object value, final boolean selected, final boolean expanded,
+        final boolean leaf, final int row, final boolean hasFocus)
+    {
+        CheckBoxNodeData data = null;
+        if (value instanceof DefaultMutableTreeNode) {
+            final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
+            final Object userObject = node.getUserObject();
+            if (userObject instanceof CheckBoxNodeData) {
+                data = (CheckBoxNodeData) userObject;
+            }
+        }
+
+        //final String stringValue =
+        //    tree.convertValueToText(value, selected, expanded, leaf, row, false);
+        //panel.label.setText(stringValue);
+
+        panel.setSelected(false);
+
+        panel.setEnabled(tree.isEnabled());
+
+        if (selected) {
+            panel.setForeground(selectionForeground);
+            panel.setBackground(selectionBackground);
+            panel.getLabel().setForeground(selectionForeground);
+            panel.getLabel().setBackground(selectionBackground);
+        }
+        else {
+            panel.setForeground(textForeground);
+            panel.setBackground(textBackground);
+            panel.getLabel().setForeground(textForeground);
+            panel.getLabel().setBackground(textBackground);
+        }
+
+        if (data == null) {
+            // not a check box node; return default cell renderer
+            return defaultRenderer.getTreeCellRendererComponent(tree, value,
+                selected, expanded, leaf, row, hasFocus);
+        }
+
+        //panel.label.setText(data.getText());
+        panel.setData(data);
+        panel.setSelected(data.isSelected());
+
+        return panel;
+    }
+    private JPopupMenu createPopupMenu(final AbstractLayer layer) {
+        JMenuItem menuItem;
+ 
+        //Create the popup menu.
+        if(layer.isVisibleTexts()) menuItem = new JMenuItem("hide texts");
+        else menuItem = new JMenuItem("show texts");
+        JPopupMenu popup = new JPopupMenu();
+        popup.add(menuItem);
+        menuItem.addActionListener(new ActionListener(){
+            @Override
+            public void actionPerformed(ActionEvent arg0) {
+                setVisibleTexts(layer, !layer.isVisibleTexts());
+            }
+        });
+ 
+        return popup;
+    }
+    private void setVisibleTexts(AbstractLayer layer, boolean visible){
+        layer.setVisibleTexts(visible);
+        if(layer instanceof LayerGroup){
+            LayerGroup group = (LayerGroup)layer;
+            if(group.getLayers()!=null) for(AbstractLayer al: group.getLayers()) setVisibleTexts(al, visible);
+        }
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxTree.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxTree.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/checkBoxTree/CheckBoxTree.java	(revision 29513)
@@ -0,0 +1,237 @@
+package org.openstreetmap.gui.jmapviewer.checkBoxTree;
+
+import java.awt.BorderLayout;
+import java.awt.event.MouseAdapter;
+
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+import javax.swing.JTree;
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+
+import org.openstreetmap.gui.jmapviewer.AbstractLayer;
+import org.openstreetmap.gui.jmapviewer.Layer;
+import org.openstreetmap.gui.jmapviewer.LayerGroup;
+
+/**
+ * JTree for checkBox Tree Layers
+ * 
+ * @author galo
+ */
+public class CheckBoxTree extends JTree{
+    /** Serial Version UID */
+    private static final long serialVersionUID = 6943401106938034256L;
+    
+    private final CheckBoxNodeEditor editor;
+
+    public CheckBoxTree(AbstractLayer layer){
+        this(new CheckBoxNodeData(layer));
+    }
+    public CheckBoxTree(String rootName){
+        this(new CheckBoxNodeData(rootName));
+    }
+    public CheckBoxTree(CheckBoxNodeData root ){
+        this(new DefaultMutableTreeNode(root));
+    }
+    public CheckBoxTree(DefaultMutableTreeNode node){
+        super(new DefaultTreeModel(node));
+
+        final CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
+        setCellRenderer(renderer);
+
+        editor = new CheckBoxNodeEditor(this);
+        setCellEditor(editor);
+        setEditable(true);
+        
+        // listen for changes in the model (including check box toggles)
+        getModel().addTreeModelListener(new TreeModelListener() {
+            @Override
+            public void treeNodesChanged(final TreeModelEvent e) {
+                DefaultTreeModel model = (DefaultTreeModel)e.getSource();
+                Object[] nodes = e.getChildren();
+                DefaultMutableTreeNode node;
+                if(nodes==null||nodes.length==0){
+                    node = node(model.getRoot());
+                }else{
+                    node = node(nodes[0]);
+                }
+                nodeChanged(node);
+                repaint();
+            }
+
+            @Override
+            public void treeNodesInserted(final TreeModelEvent e) {
+                //System.out.println("nodes inserted");
+            }
+
+            @Override
+            public void treeNodesRemoved(final TreeModelEvent e) {
+                //System.out.println("nodes removed");
+            }
+
+            @Override
+            public void treeStructureChanged(final TreeModelEvent e) {
+                //System.out.println("structure changed");
+            }
+        });
+    }
+    public void addNodeListener(MouseAdapter listener){
+        editor.addNodeListener(listener);
+    }
+    public static void main(final String args[]) {
+        final DefaultMutableTreeNode root = new DefaultMutableTreeNode(new CheckBoxNodeData("Root",true));
+
+        final DefaultMutableTreeNode accessibility =
+            add(root, "Accessibility", true);
+        add(accessibility, "Move system caret with focus/selection changes", false);
+        add(accessibility, "Always expand alt text for images", true);
+        root.add(accessibility);
+
+        final DefaultMutableTreeNode browsing =
+            new DefaultMutableTreeNode(new CheckBoxNodeData("Browsing", null));
+        add(browsing, "Notify when downloads complete", true);
+        add(browsing, "Disable script debugging", true);
+        add(browsing, "Use AutoComplete", true);
+        add(browsing, "Browse in a new process", false);
+        root.add(browsing);
+
+        final CheckBoxTree tree = new CheckBoxTree(root);
+        ((DefaultMutableTreeNode)tree.getModel().getRoot()).add(new DefaultMutableTreeNode(new CheckBoxNodeData("gggg", null)));
+        ((DefaultTreeModel)tree.getModel()).reload();
+        // listen for changes in the selection
+        tree.addTreeSelectionListener(new TreeSelectionListener() {
+            @Override
+            public void valueChanged(final TreeSelectionEvent e) {
+                //System.out.println("selection changed");
+            }
+        });
+        // show the tree on screen
+        final JFrame frame = new JFrame("CheckBox Tree");
+        final JScrollPane scrollPane = new JScrollPane(tree);
+        frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        frame.setSize(300, 150);
+        frame.setVisible(true);
+    }
+    private static Boolean childStatus(DefaultMutableTreeNode node){
+        Boolean status = data(node.getChildAt(0)).isSelected();
+        for(int i=1; i<node.getChildCount()&&status!=null; i++){
+            if(status != data(node.getChildAt(i)).isSelected()) return null;
+        }
+        return status;
+    }
+    private static void changeParents(DefaultMutableTreeNode node){
+        if(node!=null){
+            DefaultMutableTreeNode parent = node(node.getParent());
+            if(parent!=null){
+                CheckBoxNodeData dataParent = data(parent);
+                Boolean childStatus = childStatus(parent);
+                if(dataParent.isSelected()!=childStatus){
+                    dataParent.setSelected(childStatus);
+                    changeParents(parent);
+                }
+            }
+        }
+    }
+    private static void nodeChanged(DefaultMutableTreeNode node){
+        if(node!=null){
+            changeParents(node);
+            setChildrens(node, data(node).isSelected());
+        }
+    }
+    private static void setChildrens(DefaultMutableTreeNode node, Boolean value){
+        for(int i=0; i<node.getChildCount(); i++){
+            DefaultMutableTreeNode childNode = node(node.getChildAt(i));
+            if (data(childNode).isSelected() !=data(node).isSelected()){
+                data(childNode).setSelected(data(node).isSelected());
+                setChildrens(childNode, value);
+            }
+        }
+    }
+    public DefaultMutableTreeNode rootNode(){
+        return node(getModel().getRoot());
+    }
+    public LayerGroup rootLayer(){
+        return (LayerGroup)rootData().getAbstractLayer();
+    }
+    public CheckBoxNodeData rootData(){
+        return data(rootNode());
+    }
+    private static DefaultMutableTreeNode node(Object node){
+        return (DefaultMutableTreeNode)node;
+    }
+    public static CheckBoxNodeData data(DefaultMutableTreeNode node){
+        return node==null?null:(CheckBoxNodeData)node.getUserObject();
+    }
+    private static CheckBoxNodeData data(Object node){
+        return data(node(node));
+    }
+    private static DefaultMutableTreeNode add(final DefaultMutableTreeNode parent, final String text, final boolean checked){
+        final CheckBoxNodeData data = new CheckBoxNodeData(text, checked);
+        final DefaultMutableTreeNode node = new DefaultMutableTreeNode(data);
+        parent.add(node);
+        return node;
+    }
+    public static CheckBoxNodeData createNodeData(AbstractLayer layer){
+        return new CheckBoxNodeData(layer);
+    }
+    public static DefaultMutableTreeNode createNode(AbstractLayer layer){
+        return new DefaultMutableTreeNode(createNodeData(layer));
+    }
+    /*public DefaultMutableTreeNode addLayerGroup(LayerGroup group){
+        if(group!=null){
+            if(group.getParent()==null){
+                return add(rootNode(), group);
+            }else{
+                DefaultMutableTreeNode parentGroup = searchNode(group.getParent());
+                if(parentGroup==null) parentGroup = addLayerGroup(group.getParent());
+                DefaultMutableTreeNode node = add(parentGroup, group);
+                return node;
+            }
+        }else return null;
+    }*/
+    public Layer addLayer(String name){
+        Layer layer = new Layer(name);
+        addLayer(layer);
+        return layer;
+    }
+    public DefaultMutableTreeNode addLayer(AbstractLayer layer){
+        if (layer!=null){
+            DefaultMutableTreeNode parent;
+            if(layer.getParent()==null){
+                rootLayer().add(layer);
+                parent = rootNode();
+            }else{
+                parent = searchNode(layer.getParent());
+                if(parent==null) parent=addLayer(layer.getParent());
+            }
+            return add(parent, layer);
+        }else return null;
+    }
+    public DefaultMutableTreeNode add(DefaultMutableTreeNode parent, final AbstractLayer layer){
+        layer.setVisible(data(parent).isSelected());
+        DefaultMutableTreeNode node = createNode(layer); 
+        parent.add(node);
+        ((DefaultTreeModel)getModel()).reload();
+        //System.out.println("Created node "+layer+" upper of "+data(parent));
+        return node;
+    }
+    public DefaultMutableTreeNode searchNode(AbstractLayer layer){
+        return searchNode(rootNode(), layer);
+    }
+    public DefaultMutableTreeNode searchNode(DefaultMutableTreeNode node, AbstractLayer layer){
+        CheckBoxNodeData data = CheckBoxTree.data(node);
+        if(data.getAbstractLayer() == layer) return node;
+        else{
+            DefaultMutableTreeNode found = null;
+            for(int i=0; i<node.getChildCount() && found==null; i++){
+                found = searchNode((DefaultMutableTreeNode)node.getChildAt(i), layer);
+            }
+            return found;
+        }
+    }
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/ICoordinate.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/ICoordinate.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/ICoordinate.java	(revision 29513)
@@ -0,0 +1,8 @@
+package org.openstreetmap.gui.jmapviewer.interfaces;
+
+public interface ICoordinate {
+    public double getLat();
+    public void setLat(double lat);
+    public double getLon();
+    public void setLon(double lon);
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapMarker.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapMarker.java	(revision 29512)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapMarker.java	(revision 29513)
@@ -6,4 +6,5 @@
 import java.awt.Point;
 
+import org.openstreetmap.gui.jmapviewer.Coordinate;
 import org.openstreetmap.gui.jmapviewer.JMapViewer;
 
@@ -15,6 +16,12 @@
  * @see JMapViewer#getMapMarkerList()
  */
-public interface MapMarker {
+public interface MapMarker extends MapObject, ICoordinate{
 
+    public static enum STYLE {FIXED, VARIABLE};
+
+    /**
+     * @return Latitude and Longitude of the map marker position
+     */
+    public Coordinate getCoordinate();
     /**
      * @return Latitude of the map marker position
@@ -26,4 +33,14 @@
      */
     public double getLon();
+    
+    /**
+     * @return Radius of the map marker position
+     */
+    public double getRadius();
+    
+    /**
+     * @return Style of the map marker
+     */
+    public STYLE getMarkerStyle();
 
     /**
@@ -33,5 +50,6 @@
      * @param g
      * @param position
+     * @param radio
      */
-    public void paint(Graphics g, Point position);
+    public void paint(Graphics g, Point position, int radio);
 }
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapObject.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapObject.java	(revision 29513)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapObject.java	(revision 29513)
@@ -0,0 +1,22 @@
+package org.openstreetmap.gui.jmapviewer.interfaces;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Stroke;
+
+import org.openstreetmap.gui.jmapviewer.Layer;
+import org.openstreetmap.gui.jmapviewer.Style;
+
+public interface MapObject {
+
+    public Layer getLayer();
+    public void setLayer(Layer layer);
+    public Style getStyle();
+    public Style getStyleAssigned();
+    public Color getColor();
+    public Color getBackColor();
+    public Stroke getStroke();
+    public Font getFont();
+    public String getName();
+    public boolean isVisible();
+}
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapPolygon.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapPolygon.java	(revision 29512)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapPolygon.java	(revision 29513)
@@ -14,10 +14,10 @@
  * @author Vincent
  */
-public interface MapPolygon {
+public interface MapPolygon extends MapObject{
 
     /**
      * @return Latitude/Longitude of each point of polygon
      */
-    public List<Coordinate> getPoints();
+    public List<ICoordinate> getPoints();
 
     /**
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapRectangle.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapRectangle.java	(revision 29512)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/MapRectangle.java	(revision 29513)
@@ -16,5 +16,5 @@
  * @see JMapViewer#getMapRectangleList()
  */
-public interface MapRectangle {
+public interface MapRectangle extends MapObject{
 
     /**
