Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/Buildings.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/Buildings.java	(revision 20390)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/Buildings.java	(revision 20390)
@@ -0,0 +1,460 @@
+package cadastre_fr;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Color;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.actions.mapmode.MapMode;
+import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.ChangeCommand;
+import org.openstreetmap.josm.command.ChangePropertyCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.MoveCommand;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.osm.BBox;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.WaySegment;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Shortcut;
+import org.openstreetmap.josm.gui.layer.Layer;
+
+/**
+ * Trace a way around buildings from cadastre images. 
+ * Inspired by Lakewalker plugin.
+ * @author Pieren
+ */
+public class Buildings extends MapMode implements MouseListener, MouseMotionListener {
+    
+    private static final long serialVersionUID = 1L;
+    GeorefImage selectedImage;
+    WMSLayer selectedLayer;
+    private EastNorth clickedEastNorth;
+    private class Pixel {
+        public Point p;
+        public int dir;
+        public Pixel(int x, int y, int dir) {
+            this.p = new Point(x,y);
+            this.dir = dir;
+        }
+        @Override
+        public int hashCode() {
+            return p.hashCode();
+        }
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Pixel)
+                return p.equals(new Point(((Pixel)obj).p.x, ((Pixel)obj).p.y));
+            return p.equals(obj);
+        }
+    }
+    private ArrayList<Pixel> listPixels = new ArrayList<Pixel>();
+    
+    private static final int cMaxnode = 10000;
+    private int[] dirsX = new int[] {1,1,0,-1,-1,-1,0,1};
+    private int[] dirsY = new int[] {0,1,1,1,0,-1,-1,-1};
+
+    private int orange = Color.ORANGE.getRGB(); // new color of pixels ending nowhere (cul-de-sac)
+    BuildingsImageModifier bim = new BuildingsImageModifier();
+
+    private double snapDistance = Main.pref.getDouble("cadastrewms.snap-distance", 60); // in centimeters
+    private double snapDistanceSq = snapDistance*snapDistance;
+    private double dx, dy;
+
+    
+    public Buildings(MapFrame mapFrame) {
+        super(tr("Grab buildings"), "buildings",
+                        tr("Extract building on click (vector images only)"),
+                        Shortcut.registerShortcut("mapmode:buildings", tr("Mode: {0}", tr("Buildings")), KeyEvent.VK_E, Shortcut.GROUP_EDIT),
+                        mapFrame, ImageProvider.getCursor("normal", "move"));
+    }
+
+    @Override public void enterMode() {
+        super.enterMode();
+        boolean atLeastOneBuildingLayer = false;
+        for (Layer layer : Main.map.mapView.getAllLayers()) {
+            if (layer instanceof WMSLayer && ((WMSLayer)layer).isBuildingsOnly()) {
+                atLeastOneBuildingLayer = true;
+                break;
+            }
+        }
+        if (atLeastOneBuildingLayer && Main.main.getCurrentDataSet() != null) {
+            Main.map.mapView.addMouseListener(this);
+            Main.map.mapView.addMouseMotionListener(this);
+        } else {
+            JOptionPane.showMessageDialog(Main.parent,tr("This feature requires (at least) one special cadastre\nBuildings layer and an OSM data layer."));
+            exitMode();
+            Main.map.selectMapMode((MapMode)Main.map.getDefaultButtonAction());
+        }
+    }
+
+    @Override public void exitMode() {
+        super.exitMode();
+        Main.map.mapView.removeMouseListener(this);
+        Main.map.mapView.removeMouseMotionListener(this);
+    }
+
+    @Override
+    public void mousePressed(MouseEvent e) {
+        if (e.getButton() != MouseEvent.BUTTON1)
+            return;
+        selectedImage = null;
+        // boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
+        // boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
+        boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
+        for (Layer layer : Main.map.mapView.getAllLayers()) {
+            if (layer.isVisible() && layer instanceof WMSLayer && ((WMSLayer)layer).isBuildingsOnly() ) {
+                clickedEastNorth = Main.map.mapView.getEastNorth(e.getX(), e.getY());
+                selectedLayer = ((WMSLayer) layer);
+                selectedImage = selectedLayer.findImage(clickedEastNorth);
+            }
+        }
+        if (selectedImage != null) {
+            int x = (int)((clickedEastNorth.east() - selectedImage.min.east())*selectedImage.getPixelPerEast());
+            int y = selectedImage.image.getHeight() - (int)((clickedEastNorth.north() - selectedImage.min.north())*selectedImage.getPixelPerNorth());
+            int rgb = selectedImage.image.getRGB(x, y);
+            System.out.println("image found"+", x="+x+", y="+y+", RGB="+rgb);
+            boolean clickOnRoof = bim.isRoofColor(rgb, shift);
+            boolean clickOnBuilding = bim.isBuildingColor(rgb, shift);
+            if (clickOnRoof || clickOnBuilding) {
+                if (traceBuilding(x, y, clickOnBuilding, shift) && listPixels.size() > 3) {
+                    Way wayToCreate = new Way();
+                    Way way2 = new Way();
+                    double pPE = selectedImage.getPixelPerEast();
+                    double pPN = selectedImage.getPixelPerNorth();
+                    for (int i=0; i < listPixels.size(); i++) {
+                        EastNorth en = new EastNorth(selectedImage.min.east() + ((listPixels.get(i).p.x + 0.5)/ pPE),
+                                selectedImage.max.north() - ((listPixels.get(i).p.y + 0.5)/ pPN));
+                        Node nodeToAdd = new Node(Main.proj.eastNorth2latlon(en));
+                        wayToCreate.addNode(nodeToAdd);
+                    }
+                    wayToCreate.addNode(wayToCreate.getNode(0)); // close the way
+                    new SimplifyWay().simplifyWay(wayToCreate, 0.2);
+                    // move the node closing the loop and simplify again
+                    for (int i = 1; i < wayToCreate.getNodesCount(); i++) {
+                        way2.addNode(wayToCreate.getNode(i));
+                    }
+                    way2.addNode(way2.getNode(0));
+                    new SimplifyWay().simplifyWay(way2, 0.2);
+                    Way wayToAdd = new Way();
+                    Collection<Command> cmds = new LinkedList<Command>();
+                    for (int i = 0; i < way2.getNodesCount()-1; i++) {
+                        Node nearestNode = getNearestNode(way2.getNode(i));
+                        if (nearestNode == null) {
+                            List<WaySegment> wss = getNearestWaySegments(way2.getNode(i));
+                            wayToAdd.addNode(way2.getNode(i));
+                            cmds.add(new AddCommand(way2.getNode(i)));
+                            if (wss.size() > 0)
+                                cmds.add(new MoveCommand(way2.getNode(i), dx, dy));
+                                joinNodeToExistingWays(wss, way2.getNode(i), cmds);
+                        } else {// reuse the existing node
+                            wayToAdd.addNode(nearestNode);
+                            cmds.add(new MoveCommand(nearestNode, dx, dy));
+                        }
+                    }
+                    wayToAdd.addNode(wayToAdd.getNode(0));
+                    cmds.add(new AddCommand(wayToAdd));
+                    if (clickOnBuilding)
+                        addBuildingTags(cmds, wayToAdd);
+                    if (clickOnRoof) {
+                        addRoofTags(cmds, wayToAdd);
+                    }
+                    Main.main.undoRedo.add(new SequenceCommand(tr("Create building"), cmds));
+                    getCurrentDataSet().setSelected(wayToAdd);
+                    Main.map.repaint();
+                }
+            }
+        }
+    }
+    
+    @Override public void mouseDragged(MouseEvent e) {
+    }
+
+    @Override public void mouseReleased(MouseEvent e) {
+    }
+
+    public void mouseEntered(MouseEvent e) {
+    }
+    public void mouseExited(MouseEvent e) {
+    }
+    public void mouseMoved(MouseEvent e) {
+    }
+
+    @Override public void mouseClicked(MouseEvent e) {
+    }
+    
+    private void addBuildingTags(Collection<Command> cmds, Way wayToAdd) {
+        cmds.add(new ChangePropertyCommand(wayToAdd, "building", "yes"));
+    }
+    
+    private void addRoofTags(Collection<Command> cmds, Way wayToAdd) {
+        cmds.add(new ChangePropertyCommand(wayToAdd, "building", "yes"));
+        cmds.add(new ChangePropertyCommand(wayToAdd, "wall", "no"));
+    }
+    
+    private boolean traceBuilding (int x, int y, boolean buildingColors, boolean ignoreParcels) {
+        // search start point at same x but smallest y (upper border on the screen)
+        int startY = 0; int startX = x;
+        while (y > 0) {
+            y--;
+            if (!bim.isBuildingOrRoofColor(selectedImage.image, x, y, buildingColors, ignoreParcels)) {
+                System.out.println("at "+x+","+y+" color was "+selectedImage.image.getRGB(x,y));
+                y++;
+                startY = y;
+                break;
+            }
+        }
+        if (startY == 0) {
+            System.out.println("border not found");
+            return false;
+        } else
+            System.out.println("start at x="+startX+", y="+startY);
+        listPixels.clear();
+        int test_x = 0;
+        int test_y = 0;
+        int new_dir = 0;
+        addPixeltoList(x, y, new_dir);
+        int last_dir = 1;
+        for(int i = 0; i < cMaxnode; i++){
+            //System.out.println("node "+i);
+            for(int d = 1; d <= this.dirsY.length; d++){
+                new_dir = (last_dir + d + 4) % 8;
+                test_x = x + this.dirsX[new_dir];
+                test_y = y + this.dirsY[new_dir];
+                if(test_x < 0 || test_x >= selectedImage.image.getWidth() ||
+                        test_y < 0 || test_y >= selectedImage.image.getHeight()){
+                    System.out.println("Outside image");
+                    return false;
+                }
+                if(bim.isBuildingOrRoofColor(selectedImage.image, test_x, test_y, buildingColors, ignoreParcels)){
+                    System.out.println("building color at "+test_x+","+test_y+" new_dir="+new_dir);
+                    break;
+                }
+
+                if(d == this.dirsY.length-1){
+                    System.out.println("Got stuck at "+x+","+y);
+                    // cul-de-sac : disable current pixel and move two steps back
+                    selectedImage.image.setRGB(x, y, orange);
+                    if (removeTwoLastPixelsFromList()) {
+                        x = listPixels.get(listPixels.size()-1).p.x;
+                        y = listPixels.get(listPixels.size()-1).p.y;
+                        last_dir = listPixels.get(listPixels.size()-1).dir; 
+                        System.out.println("return at "+x+","+y+" and try again");
+                        d = 1;
+                        continue;
+                    } else {
+                        System.out.println("cannot try another way");
+                        return false;
+                    }
+                }
+            }
+//            if (last_dir == new_dir)
+//                // Same direction. First simplification by removing previous pixel.
+//                listPixels.remove(listPixels.size()-1);
+            last_dir = new_dir;
+            // Set the pixel we found as current
+            x = test_x;
+            y = test_y;
+            // Break the loop if we managed to get back to our starting point
+            if (listPixels.contains(new Pixel(x, y, 0))){
+                System.out.println("loop closed at "+x+","+y+", exit");
+                break;
+            }
+            addPixeltoList(x, y, new_dir);
+        }
+        System.out.println("list size="+listPixels.size());
+        return true;
+    }
+    
+    private void addPixeltoList(int x, int y, int dir) {
+        listPixels.add( new Pixel(x, y, dir));
+        System.out.println("added pixel at "+x+","+y);
+    }
+    
+    private boolean removeTwoLastPixelsFromList() {
+        if (listPixels.size() > 2) {
+            System.out.println("remove "+listPixels.get(listPixels.size()-1).p.x + ","+listPixels.get(listPixels.size()-1).p.y);
+            listPixels.remove(listPixels.size()-1);
+            System.out.println("remove "+listPixels.get(listPixels.size()-1).p.x + ","+listPixels.get(listPixels.size()-1).p.y);
+            listPixels.remove(listPixels.size()-1);
+            return true;
+        }
+        return false;
+    }
+    
+    private BBox getSnapDistanceBBox(Node n) {
+        return new BBox(Main.proj.eastNorth2latlon(new EastNorth(n.getEastNorth().east() - snapDistance, n.getEastNorth().north() - snapDistance)),
+                Main.proj.eastNorth2latlon(new EastNorth(n.getEastNorth().east() + snapDistance, n.getEastNorth().north() + snapDistance)));
+    }
+
+    private Point getPointInCentimeters(Node n) {
+        return new Point(new Double(n.getEastNorth().getX()*100).intValue(),
+                new Double(n.getEastNorth().getY()*100).intValue());
+    }
+    
+    public Node getNearestNode(Node newNode) {
+        Point newP = getPointInCentimeters(newNode);
+        DataSet ds = getCurrentDataSet();
+        if (ds == null)
+            return null;
+
+        double minDistanceSq = snapDistanceSq;
+        Node minNode = null;
+        for (Node n : ds.searchNodes(getSnapDistanceBBox(newNode))) {
+            if (!n.isUsable()) {
+                continue;
+            }
+            Point sp = new Point(new Double(n.getEastNorth().getX()*100).intValue(),
+                    new Double(n.getEastNorth().getY()*100).intValue());
+            double dist = newP.distanceSq(sp); // in centimeter !
+            if (dist < minDistanceSq) {
+                minDistanceSq = dist;
+                minNode = n;
+            }
+            // when multiple nodes on one point, prefer new or selected nodes
+            else if (dist == minDistanceSq && minNode != null
+                    && ((n.isNew() && ds.isSelected(n))
+                            || (!ds.isSelected(minNode) && (ds.isSelected(n) || n.isNew())))) {
+                minNode = n;
+            }
+        }
+        if (minNode != null) {
+            dx = (newNode.getEastNorth().getX() - minNode.getEastNorth().getX())/2;
+            dy = (newNode.getEastNorth().getY() - minNode.getEastNorth().getY())/2;
+        }
+        return minNode;
+    }
+
+    private List<WaySegment> getNearestWaySegments(Node newNode) {
+        Point newP = new Point(new Double(newNode.getEastNorth().getX()*100).intValue(),
+                new Double(newNode.getEastNorth().getY()*100).intValue());
+        TreeMap<Double, List<WaySegment>> nearest = new TreeMap<Double, List<WaySegment>>();
+        DataSet ds = getCurrentDataSet();
+        if (ds == null)
+            return null;
+
+        for (Way w : ds.searchWays(getSnapDistanceBBox(newNode))) {
+            if (!w.isUsable()) {
+                continue;
+            }
+            Node lastN = null;
+            int i = -2;
+            for (Node n : w.getNodes()) {
+                i++;
+                if (n.isDeleted() || n.isIncomplete()) {
+                    continue;
+                }
+                if (lastN == null) {
+                    lastN = n;
+                    continue;
+                }
+
+                Point A = getPointInCentimeters(lastN);
+                Point B = getPointInCentimeters(n);
+                double c = A.distanceSq(B);
+                double a = newP.distanceSq(B);
+                double b = newP.distanceSq(A);
+                double perDist = a - (a - b + c) * (a - b + c) / 4 / c; // perpendicular distance squared
+                if (perDist < snapDistanceSq && a < c + snapDistanceSq && b < c + snapDistanceSq) {
+                    if (ds.isSelected(w)) {
+                        perDist -= 0.00001;
+                    }
+                    List<WaySegment> l;
+                    if (nearest.containsKey(perDist)) {
+                        l = nearest.get(perDist);
+                    } else {
+                        l = new LinkedList<WaySegment>();
+                        nearest.put(perDist, l);
+                    }
+                    Point pivot = A;
+                    double startAngle = Math.atan2(B.x-pivot.x, B.y-pivot.y);
+                    double endAngle = Math.atan2(newP.x-pivot.x, newP.y-pivot.y);
+                    double angle = endAngle - startAngle;
+                    double ratio = A.distance(newP)/A.distance(B);//).intValue();
+                    Point perP = new Point(A.x+new Double((B.x-A.x)*ratio).intValue(),
+                            A.y+new Double((B.y-A.y)*ratio).intValue());
+                    dx = (perP.x-newP.x)/200.0; // back to meters this time and whole distance by two 
+                    dy = (perP.y-newP.y)/200.0;
+                    System.out.println(angle+","+ ratio+","+perP );
+                    l.add(new WaySegment(w, i));
+                }
+
+                lastN = n;
+            }
+        }
+        ArrayList<WaySegment> nearestList = new ArrayList<WaySegment>();
+        for (List<WaySegment> wss : nearest.values()) {
+            nearestList.addAll(wss);
+        }
+        return nearestList;
+    }
+    
+    private void joinNodeToExistingWays(List<WaySegment> wss, Node newNode, Collection<Command> cmds) {
+        HashMap<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
+        for (WaySegment ws : wss) {
+            List<Integer> is;
+            if (insertPoints.containsKey(ws.way)) {
+                is = insertPoints.get(ws.way);
+            } else {
+                is = new ArrayList<Integer>();
+                insertPoints.put(ws.way, is);
+            }
+
+            if (ws.way.getNode(ws.lowerIndex) != newNode
+                    && ws.way.getNode(ws.lowerIndex+1) != newNode) {
+                is.add(ws.lowerIndex);
+            }
+        }
+        
+        for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
+            List<Integer> is = insertPoint.getValue();
+            if (is.size() == 0)
+                continue;
+
+            Way w = insertPoint.getKey();
+            List<Node> nodesToAdd = w.getNodes();
+            pruneSuccsAndReverse(is);
+            for (int i : is) {
+                nodesToAdd.add(i+1, newNode);
+            }
+            Way wnew = new Way(w);
+            wnew.setNodes(nodesToAdd);
+            cmds.add(new ChangeCommand(w, wnew));
+        }        
+    }
+    
+    private static void pruneSuccsAndReverse(List<Integer> is) {
+        HashSet<Integer> is2 = new HashSet<Integer>();
+        for (int i : is) {
+            if (!is2.contains(i - 1) && !is2.contains(i + 1)) {
+                is2.add(i);
+            }
+        }
+        is.clear();
+        is.addAll(is2);
+        Collections.sort(is);
+        Collections.reverse(is);
+    }
+
+}
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/BuildingsImageModifier.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/BuildingsImageModifier.java	(revision 20390)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/BuildingsImageModifier.java	(revision 20390)
@@ -0,0 +1,21 @@
+package cadastre_fr;
+
+public class BuildingsImageModifier extends ImageModifier {
+
+    public BuildingsImageModifier() {super();};
+        
+    public BuildingsImageModifier(GeorefImage buildings, GeorefImage parcels) {
+        bufferedImage = buildings.image;
+        VectorImageModifier vim = new VectorImageModifier();
+        for (int x = 0; x < bufferedImage.getWidth(); x++) {
+            for (int y = 0; y < bufferedImage.getHeight(); y++) {
+                if (vim.isBuildingOrRoofColor(bufferedImage, x, y, false)
+                        && !vim.isBackgroundColor(parcels.image, x, y)) {
+                    // create a clear 'cut' for the parcels
+                    bufferedImage.setRGB(x, y, parcelColor);
+                }
+            }
+        }
+    }
+    
+}
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CacheControl.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CacheControl.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CacheControl.java	(revision 20390)
@@ -94,10 +94,5 @@
     public boolean loadCacheIfExist() {
         try {
-            String extension = String.valueOf((wmsLayer.getLambertZone() + 1));
-            if (Main.proj instanceof LambertCC9Zones)
-                extension = cLambertCC9Z + extension;
-            else if (Main.proj instanceof UTM_20N_France_DOM)
-                extension = cUTM20N + extension;
-            File file = new File(CadastrePlugin.cacheDir + wmsLayer.getName() + "." + extension);
+            File file = new File(CadastrePlugin.cacheDir + wmsLayer.getName() + "." + WMSFileExtension());
             if (file.exists()) {
                 JOptionPane pane = new JOptionPane(
@@ -127,8 +122,5 @@
     public void deleteCacheFile() {
         try {
-            String extension = String.valueOf((wmsLayer.getLambertZone() + 1));
-            if (Main.proj instanceof LambertCC9Zones)
-                extension = cLambertCC9Z + extension;
-            delete(new File(CadastrePlugin.cacheDir + wmsLayer.getName() + "." + extension));
+            delete(new File(CadastrePlugin.cacheDir + wmsLayer.getName() + "." + WMSFileExtension()));
         } catch (Exception e) {
             e.printStackTrace(System.out);
@@ -182,10 +174,5 @@
             imagesLock.unlock();
             if (size > 0) {
-                String extension = String.valueOf((wmsLayer.getLambertZone() + 1));
-                if (Main.proj instanceof LambertCC9Zones)
-                    extension = cLambertCC9Z + extension;
-                else if (Main.proj instanceof UTM_20N_France_DOM)
-                    extension = cUTM20N + extension;
-                File file = new File(CadastrePlugin.cacheDir + wmsLayer.getName() + "." + extension);
+                File file = new File(CadastrePlugin.cacheDir + wmsLayer.getName() + "." + WMSFileExtension());
                 try {
                     if (file.exists()) {
@@ -219,3 +206,13 @@
         }
     }
+    
+    private String WMSFileExtension() {
+        String ext = String.valueOf((wmsLayer.getLambertZone() + 1));
+        if (Main.proj instanceof LambertCC9Zones)
+            ext = cLambertCC9Z + ext;
+        else if (Main.proj instanceof UTM_20N_France_DOM)
+            ext = cUTM20N + ext;
+        return ext;
+    }
+
 }
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CadastreGrabber.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CadastreGrabber.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CadastreGrabber.java	(revision 20390)
@@ -35,5 +35,5 @@
                 imageModified = new RasterImageModifier(img);
             else
-                imageModified = new VectorImageModifier(img);
+                imageModified = new VectorImageModifier(img, false);
             return new GeorefImage(imageModified.bufferedImage, lambertMin, lambertMax);
         } catch (MalformedURLException e) {
@@ -42,4 +42,26 @@
     }
 
+    public GeorefImage grabBuildings(WMSLayer wmsLayer, EastNorth lambertMin, EastNorth lambertMax) throws IOException, OsmTransferException {
+        try {
+            URL url = getURLVectorBuildings(lambertMin, lambertMax);
+            BufferedImage img = grab(url);
+            ImageModifier imageModified = new VectorImageModifier(img, true);
+            return new GeorefImage(imageModified.bufferedImage, lambertMin, lambertMax);
+        } catch (MalformedURLException e) {
+            throw (IOException) new IOException(tr("CadastreGrabber: Illegal url.")).initCause(e);
+        }
+    }
+    
+    public GeorefImage grabParcels(WMSLayer wmsLayer, EastNorth lambertMin, EastNorth lambertMax) throws IOException, OsmTransferException {
+        try {
+            URL url = getURLVectorParcels(lambertMin, lambertMax);
+            BufferedImage img = grab(url);
+            //ImageModifier imageModified = new VectorImageModifier(img, true);
+            return new GeorefImage(/*imageModified.bufferedImage*/img, lambertMin, lambertMax);
+        } catch (MalformedURLException e) {
+            throw (IOException) new IOException(tr("CadastreGrabber: Illegal url.")).initCause(e);
+        }
+    }
+    
     private URL getURLRaster(WMSLayer wmsLayer, EastNorth lambertMin, EastNorth lambertMax) throws MalformedURLException {
         // GET /scpc/wms?version=1.1&request=GetMap&layers=CDIF:PMC@QH4480001701&format=image/png&bbox=-1186,0,13555,8830&width=576&height=345&exception=application/vnd.ogc.se_inimage&styles= HTTP/1.1
@@ -49,16 +71,19 @@
         str += wmsLayer.getCodeCommune();
         str += "&format=image/png";
+        //str += "&format=image/jpeg";
         str += "&bbox=";
         str += wmsLayer.eastNorth2raster(lambertMin, lambertMax);
-        //str += "&width=1000&height=800"; // maximum allowed by wms server
         str += "&width="+cRasterX+"&height="; // maximum allowed by wms server (576/345, 800/378, 1000/634)
         str += (int)(cRasterX*(wmsLayer.communeBBox.max.getY() - wmsLayer.communeBBox.min.getY())/(wmsLayer.communeBBox.max.getX() - wmsLayer.communeBBox.min.getX()));
-        str += "&exception=application/vnd.ogc.se_inimage&styles=";
+        str += "&exception=application/vnd.ogc.se_inimage&styles="; // required for raster images
+        System.out.println("URL="+str);
         return new URL(str.replace(" ", "%20"));
     }
 
-    private URL getURLVector(EastNorth lambertMin, EastNorth lambertMax) throws MalformedURLException {
+    private URL buildURLVector(String layers, String styles,
+            int width, int height,
+            EastNorth lambertMin, EastNorth lambertMax) throws MalformedURLException {
         String str = new String(wmsInterface.baseURL+"/scpc/wms?version=1.1&request=GetMap");
-        str += "&layers="+CadastrePlugin.grabLayers;
+        str += "&layers="+ layers;  
         str += "&format=image/png";
         //str += "&format=image/jpeg";
@@ -67,9 +92,23 @@
         str += lambertMax.east() + ",";
         str += lambertMax.north();
-        str += "&width="+CadastrePlugin.imageWidth+"&height="+CadastrePlugin.imageHeight;
-        //str += "&exception=application/vnd.ogc.se_inimage"; // used by normal client but not required
-        str += "&styles="+CadastrePlugin.grabStyles;
+        str += "&width="+width+"&height="+height;
+        str += "&exception=application/vnd.ogc.se_inimage"; // works also without (but slower ?)
+        str += "&styles=" + styles;
         System.out.println("URL="+str);
         return new URL(str.replace(" ", "%20"));
+    }
+
+    private URL getURLVector(EastNorth lambertMin, EastNorth lambertMax) throws MalformedURLException {
+        return buildURLVector(CadastrePlugin.grabLayers, CadastrePlugin.grabStyles, 
+                CadastrePlugin.imageWidth, CadastrePlugin.imageHeight, 
+                lambertMin, lambertMax);
+    }
+
+    private URL getURLVectorBuildings(EastNorth lambertMin, EastNorth lambertMax) throws MalformedURLException {
+        return buildURLVector("CDIF:LS2", "LS2_90", 1000, 800, lambertMin, lambertMax);
+    }
+
+    private URL getURLVectorParcels(EastNorth lambertMin, EastNorth lambertMax) throws MalformedURLException {
+        return buildURLVector("CDIF:PARCELLE", "PARCELLE_90", 1000, 800, lambertMin, lambertMax);
     }
 
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CadastrePlugin.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CadastrePlugin.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CadastrePlugin.java	(revision 20390)
@@ -90,5 +90,5 @@
  * 1.6 28-Nov-2009 - Fix minor issues if Grab is called without layer (possible since projection rework)
  * 1.7 12-Dec-2009 - Change URL's changes for cookie and downgrade imgs resolution due to WMS changes
- * 1.8 xxx         - filter the mouse button 1 during georeferencing
+ * 1.8 09-Mar-2010 - filter the mouse button 1 during georeferencing
  *                 - retry if getting a new cookie failed (10 times during 30 seconds)
  *                 - cookie expiration automatically detected and renewed (after 30 minutes)
@@ -188,5 +188,5 @@
             // temporary disabled:
             //JMenuItem menuActionBoundaries = new JMenuItem(new MenuActionBoundaries());
-            //JMenuItem menuActionBuildings = new JMenuItem(new MenuActionBuildings());
+            JMenuItem menuActionBuildings = new JMenuItem(new MenuActionBuildings());
 
             cadastreJMenu.add(menuGrab);
@@ -196,8 +196,9 @@
             //cadastreJMenu.add(menuResetCookie); not required any more
             //cadastreJMenu.add(menuLambertZone);
+            if (Main.pref.getBoolean("cadastrewms.buildingsMenu", false))
+                cadastreJMenu.add(menuActionBuildings);
             cadastreJMenu.add(menuLoadFromCache);
             // all SVG features disabled until official WMS is released
             //cadastreJMenu.add(menuActionBoundaries);
-            //cadastreJMenu.add(menuActionBuildings);
         }
         setEnabledAll(menuEnabled);
@@ -224,46 +225,5 @@
             imageWidth = 600; imageHeight = 400;
         }
-        grabLayers = "";
-        grabStyles = "";
-        if (Main.pref.getBoolean("cadastrewms.layerWater", true)) {
-            grabLayers += "CDIF:LS3,";
-            grabStyles += "LS3_90,";
-        }
-        if (Main.pref.getBoolean("cadastrewms.layerBuilding", true)) {
-            grabLayers += "CDIF:LS2,";
-            grabStyles += "LS2_90,";
-        }
-        if (Main.pref.getBoolean("cadastrewms.layerSymbol", true)) {
-            grabLayers += "CDIF:LS1,";
-            grabStyles += "LS1_90,";
-        }
-        if (Main.pref.getBoolean("cadastrewms.layerParcel", true)) {
-            grabLayers += "CDIF:PARCELLE,";
-            grabStyles += "PARCELLE_90,";
-        }
-        if (Main.pref.getBoolean("cadastrewms.layerNumero", true)) {
-            grabLayers += "CDIF:NUMERO,";
-            grabStyles += "NUMERO_90,";
-        }
-        if (Main.pref.getBoolean("cadastrewms.layerLabel", true)) {
-            grabLayers += "CDIF:PT3,CDIF:PT2,CDIF:PT1,";
-            grabStyles += "PT3_90,PT2_90,PT1_90,";
-        }
-        if (Main.pref.getBoolean("cadastrewms.layerLieudit", true)) {
-            grabLayers += "CDIF:LIEUDIT,";
-            grabStyles += "LIEUDIT_90,";
-        }
-        if (Main.pref.getBoolean("cadastrewms.layerSection", true)) {
-            grabLayers += "CDIF:SUBSECTION,CDIF:SECTION,";
-            grabStyles += "SUBSECTION_90,SECTION_90,";
-        }
-        if (Main.pref.getBoolean("cadastrewms.layerCommune", true)) {
-            grabLayers += "CDIF:COMMUNE,";
-            grabStyles += "COMMUNE_90,";
-        }
-        if (grabLayers.length() > 0) { // remove the last ','
-            grabLayers = grabLayers.substring(0, grabLayers.length()-1);
-            grabStyles = grabStyles.substring(0, grabStyles.length()-1);
-        }
+        refreshLayersURL();
         
         // overwrite F11 shortcut used from the beginning by this plugin and recently used
@@ -296,4 +256,49 @@
         refreshMenu();
     }
+    
+    private static void refreshLayersURL() {
+        grabLayers = "";
+        grabStyles = "";
+        if (Main.pref.getBoolean("cadastrewms.layerWater", true)) {
+            grabLayers += "CDIF:LS3,";
+            grabStyles += "LS3_90,";
+        }
+        if (Main.pref.getBoolean("cadastrewms.layerBuilding", true)) {
+            grabLayers += "CDIF:LS2,";
+            grabStyles += "LS2_90,";
+        }
+        if (Main.pref.getBoolean("cadastrewms.layerSymbol", true)) {
+            grabLayers += "CDIF:LS1,";
+            grabStyles += "LS1_90,";
+        }
+        if (Main.pref.getBoolean("cadastrewms.layerParcel", true)) {
+            grabLayers += "CDIF:PARCELLE,";
+            grabStyles += "PARCELLE_90,";
+        }
+        if (Main.pref.getBoolean("cadastrewms.layerNumero", true)) {
+            grabLayers += "CDIF:NUMERO,";
+            grabStyles += "NUMERO_90,";
+        }
+        if (Main.pref.getBoolean("cadastrewms.layerLabel", true)) {
+            grabLayers += "CDIF:PT3,CDIF:PT2,CDIF:PT1,";
+            grabStyles += "PT3_90,PT2_90,PT1_90,";
+        }
+        if (Main.pref.getBoolean("cadastrewms.layerLieudit", true)) {
+            grabLayers += "CDIF:LIEUDIT,";
+            grabStyles += "LIEUDIT_90,";
+        }
+        if (Main.pref.getBoolean("cadastrewms.layerSection", true)) {
+            grabLayers += "CDIF:SUBSECTION,CDIF:SECTION,";
+            grabStyles += "SUBSECTION_90,SECTION_90,";
+        }
+        if (Main.pref.getBoolean("cadastrewms.layerCommune", true)) {
+            grabLayers += "CDIF:COMMUNE,";
+            grabStyles += "COMMUNE_90,";
+        }
+        if (grabLayers.length() > 0) { // remove the last ','
+            grabLayers = grabLayers.substring(0, grabLayers.length()-1);
+            grabStyles = grabStyles.substring(0, grabStyles.length()-1);
+        }
+    }
 
     @Override
@@ -322,4 +327,6 @@
                 Main.map.addMapMode(new IconToggleButton
                         (new WMSAdjustAction(Main.map)));
+                Main.map.addMapMode(new IconToggleButton
+                        (new Buildings(Main.map)));
             } else if (oldFrame != null && newFrame == null) {
                 setEnabledAll(false);
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadSVGBuilding.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadSVGBuilding.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadSVGBuilding.java	(revision 20390)
@@ -129,6 +129,6 @@
 
         // simplify ways and check if we can reuse existing OSM nodes
-        for (Way wayToAdd : svgDataSet.getWays())
-            new SimplifyWay().simplifyWay(wayToAdd, svgDataSet, 0.5);
+//        for (Way wayToAdd : svgDataSet.getWays())
+//            new SimplifyWay().simplifyWay(wayToAdd, svgDataSet, 0.5);
         // check if the new way or its nodes is already in OSM layer
         for (Node n : svgDataSet.getNodes()) {
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadSVGTask.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadSVGTask.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadSVGTask.java	(revision 20390)
@@ -123,6 +123,6 @@
 
         // simplify the way
-        double threshold = Double.parseDouble(Main.pref.get("cadastrewms.simplify-way-boundary", "1.0"));
-        new SimplifyWay().simplifyWay(wayToAdd, Main.main.getCurrentDataSet(), threshold);
+//        double threshold = Double.parseDouble(Main.pref.get("cadastrewms.simplify-way-boundary", "1.0"));
+//        new SimplifyWay().simplifyWay(wayToAdd, Main.main.getCurrentDataSet(), threshold);
 
         cmds.add(new AddCommand(wayToAdd));
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadWMSPlanImage.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadWMSPlanImage.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadWMSPlanImage.java	(revision 20390)
@@ -66,5 +66,5 @@
                             } else {
                                 // next steps follow in method finish() when download is terminated
-                                wmsLayer.joinRasterImages();
+                                wmsLayer.joinBufferedImages();
                             }
                         } else {
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadWMSVectorImage.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadWMSVectorImage.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/DownloadWMSVectorImage.java	(revision 20390)
@@ -16,12 +16,13 @@
 
     private Bounds bounds;
-
+    
     private CadastreGrabber grabber = CadastrePlugin.cadastreGrabber;
 
-    public DownloadWMSVectorImage(WMSLayer wmsLayer, Bounds bounds) {
+    public DownloadWMSVectorImage(WMSLayer wmsLayer, Bounds bounds, boolean buildingsOnly) {
         super(tr("Downloading {0}", wmsLayer.getName()));
 
         this.wmsLayer = wmsLayer;
         this.bounds = bounds;
+        this.wmsLayer.setBuildingsOnly(buildingsOnly);
     }
 
@@ -73,9 +74,9 @@
     }
 
-    public static void download(WMSLayer wmsLayer) {
+    public static void download(WMSLayer wmsLayer, boolean buildingsOnly) {
         MapView mv = Main.map.mapView;
         Bounds bounds = new Bounds(mv.getLatLon(0, mv.getHeight()), mv.getLatLon(mv.getWidth(), 0));
 
-        Main.worker.execute(new DownloadWMSVectorImage(wmsLayer, bounds));
+        Main.worker.execute(new DownloadWMSVectorImage(wmsLayer, bounds, buildingsOnly));
 
     }
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/GeorefImage.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/GeorefImage.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/GeorefImage.java	(revision 20390)
@@ -337,5 +337,5 @@
         int newWidth = Math.abs(sx2 - sx1);
         int newHeight = Math.abs(sy2 - sy1);
-        BufferedImage new_img = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
+        BufferedImage new_img = new BufferedImage(newWidth, newHeight, image.getType());
         Graphics g = new_img.getGraphics();
         g.drawImage(image, 0, 0, newWidth-1, newHeight-1,
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/ImageModifier.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/ImageModifier.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/ImageModifier.java	(revision 20390)
@@ -3,4 +3,5 @@
 package cadastre_fr;
 
+import java.awt.Color;
 import java.awt.Transparency;
 import java.awt.image.BufferedImage;
@@ -17,5 +18,10 @@
     private static final long serialVersionUID = 1L;
 
+    protected int parcelColor = Color.RED.getRGB();
+    
     public BufferedImage bufferedImage;
+
+    public static int[] cRoofColors = new int[] {-197380, -592138};
+    public static int[] cBuilingFootColors = new int[] {-256};
 
     protected BufferedImage convert1(BufferedImage src) {
@@ -107,3 +113,47 @@
         return dest;
       }
+
+    public boolean isBuildingColor(int rgb, boolean ignoreParcelColor) {
+        for (int i = 0; i < cBuilingFootColors.length; i++) 
+            if (rgb == cBuilingFootColors[i])
+                    return true;
+        if (ignoreParcelColor && (rgb == parcelColor))
+            return true;
+        return false;
+    }
+
+    public boolean isRoofColor(int rgb, boolean ignoreParcelColor) {
+        for (int i = 0; i < cRoofColors.length; i++) 
+            if (rgb == cRoofColors[i])
+                    return true;
+        if (ignoreParcelColor && (rgb == parcelColor))
+            return true;
+        return false;
+    }
+
+    public boolean isBuildingOrRoofColor(BufferedImage img, int x, int y, boolean ignoreParcelColor) {
+        int rgb = img.getRGB(x, y);
+        boolean ret = isBuildingColor(rgb, ignoreParcelColor) || isRoofColor(rgb, ignoreParcelColor);
+        return ret;
+    }
+
+    public boolean isBuildingOrRoofColor(BufferedImage img, int x, int y, boolean colorType, boolean ignoreParcelColor) {
+        int rgb = img.getRGB(x, y);
+        boolean ret;
+        if (colorType)
+            ret = isBuildingColor(rgb, ignoreParcelColor);
+        else
+            ret = isRoofColor(rgb, ignoreParcelColor);
+        return ret;
+    }
+
+    /**
+     * Checks if the rgb value is the black background color
+     * @param  
+     * @return
+     */
+    public boolean isBackgroundColor(BufferedImage img, int x, int y) {
+        return (img.getRGB(x, y) == -1);
+    }
+
 }
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionBuildings.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionBuildings.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionBuildings.java	(revision 20390)
@@ -13,24 +13,26 @@
 public class MenuActionBuildings extends JosmAction {
     
-    public static String name = "Building footprints";
+    public static String name = "Grab buildings only";
 
     private static final long serialVersionUID = 1L;
-    private WMSLayer wmsLayer = null;
    
     public MenuActionBuildings() {
-        super(tr(name), "cadastre_small", tr("Extract building footprints"), null, false);
+        super(tr(name), "cadastre_small", tr("Grab building layer only"), null, false);
     }
 
-    public void actionPerformed(ActionEvent arg0) {
-        wmsLayer = WMSDownloadAction.getLayer();
-        if (wmsLayer != null) {
-            if (wmsLayer.isRaster()) {
+    public void actionPerformed(ActionEvent e) {
+        if (Main.map != null) {
+            if (CadastrePlugin.isCadastreProjection()) {
+                WMSLayer wmsLayer = WMSDownloadAction.getLayer();
+                if (wmsLayer != null)
+                    DownloadWMSVectorImage.download(wmsLayer, true);
+            } else {
                 JOptionPane.showMessageDialog(Main.parent,
-                        tr("Only on vectorized layers"), tr("Error"),
-                        JOptionPane.ERROR_MESSAGE);
-                return;
+                        tr("To enable the cadastre WMS plugin, change\n"
+                         + "the current projection to one of the cadastre\n"
+                         + "projections and retry"));
             }
-            DownloadSVGBuilding.download(wmsLayer);
-        }
+        } else
+            new MenuActionNewLocation().actionPerformed(e);
     }
 
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionGrab.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionGrab.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionGrab.java	(revision 20390)
@@ -33,5 +33,5 @@
                 WMSLayer wmsLayer = WMSDownloadAction.getLayer();
                 if (wmsLayer != null)
-                    DownloadWMSVectorImage.download(wmsLayer);
+                    DownloadWMSVectorImage.download(wmsLayer, false);
             } else {
                 JOptionPane.showMessageDialog(Main.parent,
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionNewLocation.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionNewLocation.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionNewLocation.java	(revision 20390)
@@ -32,5 +32,5 @@
         WMSLayer wmsLayer = addNewLayer(new ArrayList<WMSLayer>());
         if (wmsLayer != null)
-            DownloadWMSVectorImage.download(wmsLayer);
+            DownloadWMSVectorImage.download(wmsLayer, false);
     }
 
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/SimplifyWay.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/SimplifyWay.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/SimplifyWay.java	(revision 20390)
@@ -3,23 +3,8 @@
 
 import java.util.ArrayList;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.command.ChangeCommand;
-import org.openstreetmap.josm.command.Command;
-import org.openstreetmap.josm.command.DeleteCommand;
-import org.openstreetmap.josm.command.SequenceCommand;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
-import static org.openstreetmap.josm.tools.I18n.trn;
-
- 
 
 /**
@@ -29,42 +14,42 @@
  */
 public class SimplifyWay {
-    public void simplifyWay(Way w, DataSet dataSet, double threshold) {
+    public void simplifyWay(Way w/*, DataSet dataSet*/, double threshold) {
         Way wnew = new Way(w);
 
-        int toI = wnew.getNodesCount() - 1;
-        List<OsmPrimitive> parents = new ArrayList<OsmPrimitive>();
-        for (int i = wnew.getNodesCount() - 1; i >= 0; i--) {
-            //CollectBackReferencesVisitor backRefsV = new CollectBackReferencesVisitor(dataSet, false);
-            //backRefsV.visit(wnew.getNode(i));
-           parents.addAll(w.getNode(i).getReferrers());
-            boolean used = false;
-            if (parents.size() == 1) {
-                used = Collections.frequency(w.getNodes(), wnew.getNode(i)) > 1;
-            } else {
-                //backRefsV.getData().remove(w);
-                parents.remove(w);
-                used = !parents.isEmpty();
-            }
-            if (!used)
-                used = wnew.getNode(i).isTagged();
+//        int toI = wnew.getNodesCount() - 1;
+//        List<OsmPrimitive> parents = new ArrayList<OsmPrimitive>();
+//        for (int i = wnew.getNodesCount() - 1; i >= 0; i--) {
+//            //CollectBackReferencesVisitor backRefsV = new CollectBackReferencesVisitor(dataSet, false);
+//            //backRefsV.visit(wnew.getNode(i));
+//           parents.addAll(w.getNode(i).getReferrers());
+//            boolean used = false;
+//            if (parents.size() == 1) {
+//                used = Collections.frequency(w.getNodes(), wnew.getNode(i)) > 1;
+//            } else {
+//                //backRefsV.getData().remove(w);
+//                parents.remove(w);
+//                used = !parents.isEmpty();
+//            }
+//            if (!used)
+//                used = wnew.getNode(i).isTagged();
+//
+//            if (used) {
+//                simplifyWayRange(wnew, i, toI, threshold);
+//                toI = i;
+//            }
+//        }
+        simplifyWayRange(wnew, 0, wnew.getNodesCount() - 1, threshold);
+        w.setNodes(wnew.getNodes());
+//        HashSet<Node> delNodes = new HashSet<Node>();
+//        delNodes.addAll(w.getNodes());
+//        delNodes.removeAll(wnew.getNodes());
 
-            if (used) {
-                simplifyWayRange(wnew, i, toI, threshold);
-                toI = i;
-            }
-        }
-        simplifyWayRange(wnew, 0, toI, threshold);
-
-        HashSet<Node> delNodes = new HashSet<Node>();
-        delNodes.addAll(w.getNodes());
-        delNodes.removeAll(wnew.getNodes());
-
-        if (wnew.getNodesCount() != w.getNodesCount()) {
-            Collection<Command> cmds = new LinkedList<Command>();
-            cmds.add(new ChangeCommand(w, wnew));
-            cmds.add(new DeleteCommand(delNodes));
-            Main.main.undoRedo.add(new SequenceCommand(trn("Simplify Way (remove {0} node)", "Simplify Way (remove {0} nodes)", delNodes.size(), delNodes.size()), cmds));
-            Main.map.repaint();
-        }
+//        if (wnew.getNodesCount() != w.getNodesCount()) {
+//            Collection<Command> cmds = new LinkedList<Command>();
+//            cmds.add(new ChangeCommand(w, wnew));
+//            cmds.add(new DeleteCommand(delNodes));
+//            Main.main.undoRedo.add(new SequenceCommand(trn("Simplify Way (remove {0} node)", "Simplify Way (remove {0} nodes)", delNodes.size(), delNodes.size()), cmds));
+//            Main.map.repaint();
+//        }
     }
 
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/VectorImageModifier.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/VectorImageModifier.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/VectorImageModifier.java	(revision 20390)
@@ -18,5 +18,7 @@
     private int backgroundPixel = 0;
 
-    public VectorImageModifier(BufferedImage bi) {
+    public VectorImageModifier() {super();}
+    
+    public VectorImageModifier(BufferedImage bi, boolean monocolor) {
         bufferedImage = bi;
         if (Main.pref.getBoolean("cadastrewms.backgroundTransparent"))
@@ -26,5 +28,6 @@
         if (Main.pref.getBoolean("cadastrewms.invertGrey"))
             invertGrey();
-        //bufferedImage = convert8(convert1(bufferedImage));
+        if (monocolor)
+            bufferedImage = convert8(convert4(bufferedImage));
     }
 
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSDownloadAction.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSDownloadAction.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSDownloadAction.java	(revision 20390)
@@ -4,5 +4,5 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.event.ActionEvent;
+//import java.awt.event.ActionEvent;
 import java.util.ArrayList;
 
@@ -10,18 +10,18 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.JosmAction;
+//import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.gui.layer.Layer;
 
-public class WMSDownloadAction extends JosmAction {
+public class WMSDownloadAction /*extends JosmAction */{
 
     private static final long serialVersionUID = 1L;
 
-    public WMSDownloadAction(String layerName) {
-        super(layerName, "wmsmenu", tr("Download WMS tile from {0}",layerName), null, false);
-    }
-
-    public void actionPerformed(ActionEvent e) {
-        DownloadWMSVectorImage.download(getLayer());
-    }
+//    public WMSDownloadAction(String layerName) {
+//        super(layerName, "wmsmenu", tr("Download WMS tile from {0}",layerName), null, false);
+//    }
+//
+//    public void actionPerformed(ActionEvent e) {
+//        DownloadWMSVectorImage.download(getLayer());
+//    }
 
     public static WMSLayer getLayer() {
@@ -30,8 +30,8 @@
         if (Main.map != null) {
             Layer activeLayer = Main.map.mapView.getActiveLayer();
-            if (activeLayer instanceof WMSLayer)
+            if (activeLayer instanceof WMSLayer && !((WMSLayer)activeLayer).isBuildingsOnly())
                 return (WMSLayer) activeLayer;
             for (Layer l : Main.map.mapView.getAllLayers()) {
-                if (l instanceof WMSLayer) {
+                if (l instanceof WMSLayer && !((WMSLayer)l).isBuildingsOnly()) {
                     existingWMSlayers.add((WMSLayer)l);
                 }
Index: applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSLayer.java
===================================================================
--- applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSLayer.java	(revision 20389)
+++ applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSLayer.java	(revision 20390)
@@ -19,4 +19,5 @@
 import java.io.ObjectOutputStream;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Vector;
 
@@ -72,7 +73,6 @@
 
     private boolean isRaster = false;
-
     private boolean isAlreadyGeoreferenced = false;
-
+    private boolean buildingsOnly = false;
     public double X0, Y0, angle, fX, fY;
 
@@ -86,4 +86,5 @@
     public boolean adjustModeEnabled;
 
+
     public WMSLayer() {
         this(tr("Blank Layer"), "", -1);
@@ -91,5 +92,5 @@
 
     public WMSLayer(String location, String codeCommune, int lambertZone) {
-        super(buildName(location, codeCommune));
+        super(buildName(location, codeCommune, false));
         this.location = location;
         this.codeCommune = codeCommune;
@@ -113,13 +114,15 @@
     }
     
-    private static String buildName(String location, String codeCommune) {
+    private static String buildName(String location, String codeCommune, boolean buildingOnly) {
         String ret = new String(location.toUpperCase());
         if (codeCommune != null && !codeCommune.equals(""))
             ret += "(" + codeCommune + ")";
+        if (buildingOnly)
+            ret += ".b";
         return  ret;
     }
 
     private String rebuildName() {
-        return buildName(this.location.toUpperCase(), this.codeCommune);
+        return buildName(this.location.toUpperCase(), this.codeCommune, this.buildingsOnly);
     }
 
@@ -133,14 +136,24 @@
                 b = new Bounds(Main.proj.eastNorth2latlon(rasterMin), Main.proj.eastNorth2latlon(rasterMax));
                 divideBbox(b, Integer.parseInt(Main.pref.get("cadastrewms.rasterDivider",
-                        CadastrePreferenceSetting.DEFAULT_RASTER_DIVIDER)));
-            } else
-                divideBbox(b, Integer.parseInt(Main.pref.get("cadastrewms.scale", Scale.X1.toString())));
+                        CadastrePreferenceSetting.DEFAULT_RASTER_DIVIDER)), 0);
+            } else if (buildingsOnly)
+                divideBbox(b, 5, 80); // hard coded size of 80 meters per box
+            else
+                divideBbox(b, Integer.parseInt(Main.pref.get("cadastrewms.scale", Scale.X1.toString())), 0);
         } else
-            divideBbox(b, 1);
-
+            divideBbox(b, 1, 0);
+
+        int lastSavedImage = images.size();
         for (EastNorthBound n : dividedBbox) {
             GeorefImage newImage;
             try {
-                newImage = grabber.grab(this, n.min, n.max);
+                if (buildingsOnly == false)
+                    newImage = grabber.grab(this, n.min, n.max);
+                else { // TODO
+                    GeorefImage buildings = grabber.grabBuildings(this, n.min, n.max);
+                    GeorefImage parcels = grabber.grabParcels(this, n.min, n.max);
+                    new BuildingsImageModifier(buildings, parcels);
+                    newImage = buildings;
+                }
             } catch (IOException e) {
                 System.out.println("Download action cancelled by user or server did not respond");
@@ -166,7 +179,10 @@
             }
             images.add(newImage);
-            saveToCache(newImage);
             Main.map.mapView.repaint();
         }
+        if (buildingsOnly)
+            joinBufferedImages();
+        for (int i=lastSavedImage; i < images.size(); i++)
+            saveToCache(images.get(i));
     }
 
@@ -177,8 +193,10 @@
      *               2 = source bbox divided by 2x2 smaller boxes
      *               3 = source bbox divided by 3x3 smaller boxes
-     *               4 = hard coded size of boxes (100 meters) rounded allowing
-     *                   grabbing of next contiguous zone
-     */
-    private void divideBbox(Bounds b, int factor) {
+     *               4 = configurable size from preferences (100 meters per default) rounded
+     *                   allowing grabbing of next contiguous zone
+     *               5 = use the size provided in next argument optionalSize
+     * @param optionalSize box size used when factor is 5.
+     */
+    private void divideBbox(Bounds b, int factor, int optionalSize) {
         EastNorth lambertMin = Main.proj.latlon2eastNorth(b.getMin());
         EastNorth lambertMax = Main.proj.latlon2eastNorth(b.getMax());
@@ -196,5 +214,5 @@
         } else {
             // divide to fixed size squares
-            int cSquare = Integer.parseInt(Main.pref.get("cadastrewms.squareSize", "100"));
+            int cSquare = factor == 4 ? Integer.parseInt(Main.pref.get("cadastrewms.squareSize", "100")) : optionalSize;   
             minEast = minEast - minEast % cSquare;
             minNorth = minNorth - minNorth % cSquare;
@@ -298,5 +316,5 @@
     public boolean isOverlapping(Bounds bounds) {
         GeorefImage georefImage =
-            new GeorefImage(new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB ), // not really important
+            new GeorefImage(null,
             Main.proj.latlon2eastNorth(bounds.getMin()),
             Main.proj.latlon2eastNorth(bounds.getMax()));
@@ -358,4 +376,13 @@
     public void setCodeCommune(String codeCommune) {
         this.codeCommune = codeCommune;
+        setName(rebuildName());
+    }
+
+    public boolean isBuildingsOnly() {
+        return buildingsOnly;
+    }
+
+    public void setBuildingsOnly(boolean buildingsOnly) {
+        this.buildingsOnly = buildingsOnly;
         setName(rebuildName());
     }
@@ -412,4 +439,5 @@
         oos.writeInt(this.lambertZone);
         oos.writeBoolean(this.isRaster);
+        oos.writeBoolean(this.buildingsOnly);
         if (this.isRaster) {
             oos.writeDouble(this.rasterMin.getX());
@@ -443,4 +471,6 @@
         this.lambertZone = ois.readInt();
         this.setRaster(ois.readBoolean());
+        if (currentFormat >= 4)
+            this.setBuildingsOnly(ois.readBoolean());
         if (this.isRaster) {
             double X = ois.readDouble();
@@ -491,8 +521,6 @@
     /**
      * Join the grabbed images into one single.
-     * Works only for images grabbed from non-georeferenced images (Feuilles cadastrales)(same amount of
-     * images in x and y)
-     */
-    public void joinRasterImages() {
+     */
+    public void joinBufferedImages() {
         if (images.size() > 1) {
             EastNorth min = images.get(0).min;
@@ -500,12 +528,18 @@
             int oldImgWidth = images.get(0).image.getWidth();
             int oldImgHeight = images.get(0).image.getHeight();
-            int newWidth = oldImgWidth*(int)Math.sqrt(images.size());
-            int newHeight = oldImgHeight*(int)Math.sqrt(images.size());
-            BufferedImage new_img = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
+            HashSet<Double> lx = new HashSet<Double>();
+            HashSet<Double> ly = new HashSet<Double>();
+            for (GeorefImage img : images) {
+                lx.add(img.min.east());
+                ly.add(img.min.north());
+            }
+            int newWidth = oldImgWidth*lx.size();
+            int newHeight = oldImgHeight*ly.size();
+            BufferedImage new_img = new BufferedImage(newWidth, newHeight, images.get(0).image.getType()/*BufferedImage.TYPE_INT_ARGB*/);
             Graphics g = new_img.getGraphics();
             // Coordinate (0,0) is on top,left corner where images are grabbed from bottom left
             int rasterDivider = (int)Math.sqrt(images.size());
-            for (int h = 0; h < rasterDivider; h++) {
-                for (int v = 0; v < rasterDivider; v++) {
+            for (int h = 0; h < lx.size(); h++) {
+                for (int v = 0; v < ly.size(); v++) {
                     int newx = h*oldImgWidth;
                     int newy = newHeight - oldImgHeight - (v*oldImgHeight);
@@ -543,5 +577,5 @@
         rasterRatio = (rasterMax.getX()-rasterMin.getX())/(communeBBox.max.getX() - communeBBox.min.getX());
     }
-
+    
     public EastNorthBound getCommuneBBox() {
         return communeBBox;
