Index: /applications/editors/josm/plugins/pdfimport/src/pdfimport/FilePlacement.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/pdfimport/FilePlacement.java	(revision 24188)
+++ /applications/editors/josm/plugins/pdfimport/src/pdfimport/FilePlacement.java	(revision 24189)
@@ -7,4 +7,5 @@
 import java.util.Properties;
 
+import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -22,5 +23,5 @@
 	public double minNorth = 0;
 	public double maxNorth = 10000;
-	
+
 	private AffineTransform transform;
 
@@ -38,5 +39,5 @@
 		this.minNorth = minNorth;
 		this.maxNorth = maxNorth;
-	}	
+	}
 
 	public Properties toProperties() {
@@ -98,64 +99,108 @@
 	}
 
-	
+
 	public String prepareTransform()
 	{
-		if (this.minX >= this.maxX){
+		if (this.minX > this.maxX){
 			return tr("Transform error: Min X must be smaller than max");
 		}
 
-		if (this.minY >= this.maxY){
+		if (this.minY > this.maxY){
 			return tr("Transform error: Min Y must be smaller than max");
 		}
-		
-		
+
+		if (Math.abs(this.minY - this.maxY) < 1 &&
+				Math.abs(this.minX - this.maxX) < 1)
+		{
+			return tr("Transform error: Points too close");
+		}
+		else if (Math.abs(this.minX - this.maxX) < 1){
+			//x axis equal, assume same scale in both dimensions
+			if (this.minEast == this.maxEast){
+				//no rotation
+				this.maxX = this.minX + this.maxY - this.minY;
+				this.maxEast = this.minEast + this.maxNorth - this.minNorth;
+			} else if (this.minNorth == this.maxNorth) {
+				//needs rotated 90 degrees clockwise, or counter
+				this.maxX = this.minX + this.maxY - this.minY;
+				this.maxNorth = this.minNorth - (this.maxEast - this.minEast);
+			} else {
+				return tr("Transform error: Unsupported variant.");
+			}
+		} else if (Math.abs(this.minY - this.maxY) < 1) {
+			//Y axis equal, assume same scale in both dimensions
+			if (this.minNorth == this.maxNorth){
+				//no rotation
+				this.maxY = this.minY + this.maxX - this.minX;
+				this.maxNorth = this.minNorth + this.maxEast - this.minEast;
+			} else if (this.minEast == this.maxEast){
+				//needs rotated 90 degrees clockwise, or counter
+				this.maxY = this.minY + this.maxX - this.minX;
+				this.maxEast = this.minEast - (this.maxNorth - this.minNorth);
+			} else {
+				return tr("Transform error: Unsupported variant.");
+			}
+		} else {
+			return tr("Transform error: Unsupported variant.");
+		}
+
+
 		if (this.minEast < this.maxEast && this.minNorth < this.maxNorth) {
 			//no rotation
 			this.transform = new AffineTransform();
-			this.transform.translate(-this.minX, -this.minY);
+			this.transform.translate(this.minEast, this.minNorth);
 			this.transform.scale(
 					(this.maxEast - this.minEast) / (this.maxX - this.minX),
 					(this.maxNorth - this.minNorth) /  (this.maxY - this.minY));
-			this.transform.translate(this.minEast, this.minNorth);
+			this.transform.translate(-this.minX, -this.minY);
 		} else if (this.minEast < this.maxEast && this.minNorth > this.maxNorth) {
 			//need to rotate 90 degrees counterclockwise
+			this.transform = new AffineTransform();
 			//transform to 0..1, 0..1 range
-			this.transform.translate(-this.minX, -this.minY);
-			this.transform.scale(1/(this.maxX - this.minX), 1/(this.minY - this.maxY));
-			
+			this.transform.preConcatenate(AffineTransform.getTranslateInstance(-this.minX, -this.minY));
+			this.transform.preConcatenate(AffineTransform.getScaleInstance(1/(this.maxX - this.minX), 1/(this.minY - this.maxY)));
+
 			//rotate -90 degs around center
-			this.transform.quadrantRotate(-1,  0.5, 0.5);
-			
+			this.transform.preConcatenate(AffineTransform.getQuadrantRotateInstance(-1,  0.5, 0.5));
+
 			//transform back to target range
-			this.transform.scale(
+			this.transform.preConcatenate(AffineTransform.getScaleInstance(
 					(this.maxEast - this.minEast),
-					(this.minNorth - this.maxNorth));
-			this.transform.translate(this.minEast, this.maxNorth);			
+					(this.minNorth - this.maxNorth)));
+			this.transform.preConcatenate(AffineTransform.getTranslateInstance(this.minEast, this.maxNorth));
 		} else if (this.minEast > this.maxEast && this.minNorth < this.maxNorth) {
 			//need to rotate 90 degrees clockwise
+			this.transform = new AffineTransform();
 			//transform to 0..1, 0..1 range
-			this.transform.translate(-this.minX, -this.minY);
-			this.transform.scale(1/(this.maxX - this.minX), 1/(this.maxY - this.minY));
-			
+			this.transform.preConcatenate(AffineTransform.getTranslateInstance(-this.minX, -this.minY));
+			this.transform.preConcatenate(AffineTransform.getScaleInstance(1/(this.maxX - this.minX), 1/(this.maxY - this.minY)));
+
 			//rotate 90 degs around center
-			this.transform.quadrantRotate(1, 0.5, 0.5);
-			
+			this.transform.preConcatenate(AffineTransform.getQuadrantRotateInstance(1, 0.5, 0.5));
+
 			//transform back to target range
-			this.transform.scale(
+			this.transform.preConcatenate(AffineTransform.getScaleInstance(
 					(this.minEast - this.maxEast),
-					(this.maxNorth - this.minNorth));
-			this.transform.translate(this.maxEast, this.minNorth);			
-		}		
+					(this.maxNorth - this.minNorth)));
+			this.transform.preConcatenate(AffineTransform.getTranslateInstance(this.maxEast, this.minNorth));
+		}
 		else
 		{
 			return tr("Transform error: Unsupported orientation");
 		}
-		
+
 		return null;
-			
-	}	
-	
+
+	}
+
 	EastNorth en = new EastNorth(0, 0);
 	Point2D src = new Point2D.Double();
+
+
+	public Bounds getWorldBounds(PathOptimizer data) {
+		LatLon min = this.tranformCoords(new Point2D.Double(data.bounds.getMinX(), data.bounds.getMinY()));
+		LatLon max = this.tranformCoords(new Point2D.Double(data.bounds.getMaxX(), data.bounds.getMaxY()));
+		return new Bounds(min, max);
+	}
 
 	public LatLon tranformCoords(Point2D pt) {
Index: /applications/editors/josm/plugins/pdfimport/src/pdfimport/LoadPdfDialog.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/pdfimport/LoadPdfDialog.java	(revision 24188)
+++ /applications/editors/josm/plugins/pdfimport/src/pdfimport/LoadPdfDialog.java	(revision 24189)
@@ -29,4 +29,5 @@
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
+import javax.swing.JProgressBar;
 import javax.swing.JTextField;
 import javax.swing.SwingUtilities;
@@ -41,13 +42,58 @@
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.gui.progress.ProgressRenderer;
+import org.openstreetmap.josm.gui.progress.SwingRenderingProgressMonitor;
 import org.openstreetmap.josm.io.OsmExporter;
 
 import pdfimport.pdfbox.PdfBoxParser;
 
-public class LoadPdfDialog extends JFrame {
+public class LoadPdfDialog extends JFrame{
+
+	class LoadProgressRenderer implements ProgressRenderer{
+		private final JProgressBar pBar;
+		private String title = "";
+
+		public LoadProgressRenderer(JProgressBar pb)
+		{
+			this.pBar =pb;
+			this.pBar.setMinimum(0);
+			this.pBar.setValue(0);
+			this.pBar.setMaximum(1);
+			this.pBar.setString("");
+			this.pBar.setStringPainted(true);
+
+		}
+
+		public void setCustomText(String message) {
+			this.pBar.setString(this.title + message);
+		}
+
+		public void setIndeterminate(boolean indeterminate) {
+			this.pBar.setIndeterminate(indeterminate);
+		}
+
+		public void setMaximum(int maximum) {
+			this.pBar.setMaximum(maximum);
+		}
+
+		public void setTaskTitle(String taskTitle) {
+			this.title = taskTitle;
+			this.pBar.setString(this.title);
+		}
+
+		public void setValue(int value) {
+			this.pBar.setValue(value);
+		}
+
+		public void finish() {
+			this.pBar.setString(tr("Finished"));
+			this.pBar.setValue(this.pBar.getMaximum());
+		}
+
+	}
 
 	private File fileName;
 	private PathOptimizer data;
-	private final FilePlacement placement;
 	private OsmDataLayer layer;
 
@@ -82,10 +128,14 @@
 	private JCheckBox removeLargeObjectsCheck;
 	private JTextField removeLargeObjectsSize;
+	private JProgressBar loadProgress;
+	protected OsmDataLayer newLayer;
+
+	private LoadProgressRenderer progressRenderer;
+
 
 	public LoadPdfDialog() {
-
-		this.placement = new FilePlacement();
-
 		this.buildGUI();
+		FilePlacement pl = new FilePlacement();
+		this.setPlacement(pl);
 		this.addListeners();
 		this.removeLayer();
@@ -161,15 +211,17 @@
 		this.showButton = new JButton(tr("Show target"));
 		this.cancelButton = new JButton(tr("Discard"));
-
-		this.minXField = new JTextField(""+this.placement.minX);
-		this.minYField = new JTextField(""+this.placement.minY);
-		this.minEastField = new JTextField(""+this.placement.minEast);
-		this.minNorthField = new JTextField(""+this.placement.minNorth);
+		this.loadProgress = new JProgressBar();
+		this.progressRenderer = new LoadProgressRenderer(this.loadProgress);
+
+		this.minXField = new JTextField("");
+		this.minYField = new JTextField("");
+		this.minEastField = new JTextField("");
+		this.minNorthField = new JTextField("");
 		this.getMinButton = new JButton(tr("Take X and Y from selected node"));
 
-		this.maxXField = new JTextField(""+this.placement.maxX);
-		this.maxYField = new JTextField(""+this.placement.maxY);
-		this.maxEastField = new JTextField(""+this.placement.maxEast);
-		this.maxNorthField = new JTextField(""+this.placement.maxNorth);
+		this.maxXField = new JTextField("");
+		this.maxYField = new JTextField("");
+		this.maxEastField = new JTextField("");
+		this.maxNorthField = new JTextField("");
 		this.getMaxButton = new JButton(tr("Take X and Y from selected node"));
 
@@ -235,5 +287,4 @@
 		c.gridx = 0; c.gridy = 0; c.gridwidth = 1;
 		selectFilePanel.add(this.loadFileButton, c);
-
 
 		JPanel projectionPanel = new JPanel(new GridBagLayout());
@@ -280,4 +331,5 @@
 		projectionPanel.add(this.getMaxButton, c);
 
+
 		JPanel okCancelPanel = new JPanel(new GridLayout(1,3));
 		okCancelPanel.add(this.cancelButton);
@@ -285,4 +337,5 @@
 		okCancelPanel.add(this.okButton);
 		okCancelPanel.add(this.saveButton);
+
 
 		JPanel panel = new JPanel(new GridBagLayout());
@@ -295,6 +348,9 @@
 		c.gridx = 0; c.gridy = 3; c.gridwidth = 1;
 		panel.add(okCancelPanel, c);
-
-		this.setSize(400, 520);
+		c.gridx = 0; c.gridy = 4; c.gridwidth = 1;
+		panel.add(this.loadProgress, c);
+
+
+		this.setSize(450, 550);
 		this.setContentPane(panel);
 	}
@@ -316,5 +372,16 @@
 				new Runnable() {
 					public void run() {
-						data = loadPDF(newFileName);
+						//async part
+						SwingRenderingProgressMonitor monitor = new SwingRenderingProgressMonitor(progressRenderer);
+						monitor.beginTask("Loading file", 1000);
+						data = loadPDF(newFileName, monitor.createSubTaskMonitor(500, false));
+						OsmBuilder.Mode mode = LoadPdfDialog.this.debugModeCheck.isSelected() ? OsmBuilder.Mode.Debug: OsmBuilder.Mode.Draft;
+
+						if (data!= null) {
+							LoadPdfDialog.this.newLayer = LoadPdfDialog.this.makeLayer(tr("PDF file preview"), new FilePlacement(), mode, monitor.createSubTaskMonitor(500, false));
+						}
+
+						monitor.finishTask();
+						progressRenderer.finish();
 					}
 				},
@@ -322,12 +389,13 @@
 
 					public void actionPerformed(ActionEvent e) {
+						//sync part
 						if (data!= null) {
-							OsmBuilder.Mode mode = LoadPdfDialog.this.debugModeCheck.isSelected() ? OsmBuilder.Mode.Debug: OsmBuilder.Mode.Draft;
-							LoadPdfDialog.this.fileName = newFileName;
-							LoadPdfDialog.this.makeLayer(tr("PDF file preview"), new FilePlacement(), mode);
+							LoadPdfDialog.this.placeLayer(newLayer, new FilePlacement());
+							fileName = newFileName;
+							newLayer = null;
 							LoadPdfDialog.this.loadFileButton.setText(tr("Loaded"));
 							LoadPdfDialog.this.loadFileButton.setEnabled(true);
-							LoadPdfDialog.this.loadPlacement();
-							LoadPdfDialog.this.setPlacement();
+							FilePlacement placement =  LoadPdfDialog.this.loadPlacement();
+							LoadPdfDialog.this.setPlacement(placement);
 						}
 					}
@@ -335,53 +403,83 @@
 	}
 
-	
-	private boolean preparePlacement()
+
+	private FilePlacement preparePlacement()
 	{
-		boolean ok = this.parsePlacement();
-		if (!ok){
-			JOptionPane.showMessageDialog(Main.parent, tr("Problems parsing placement."));
-			return false;
-		}
-		
-		String transformError = this.placement.prepareTransform();
+		FilePlacement placement = this.parsePlacement();
+		if (placement == null){
+			return null;
+		}
+
+		String transformError = placement.prepareTransform();
 		if (transformError != null){
-			JOptionPane.showMessageDialog(Main.parent, transformError);			
-		}		
-
-		this.savePlacement();
-		
-		return true;
+			JOptionPane.showMessageDialog(Main.parent, transformError);
+			return null;
+		}
+
+		this.savePlacement(placement);
+
+		return placement;
 	}
 
 	private void okPressed() {
 
-		if (!preparePlacement()) {
+		final FilePlacement placement = preparePlacement();
+		if (placement == null) {
 			return;
 		}
 
-		//rebuild layer with latest projection
-		this.makeLayer(tr("Imported PDF: ") + this.fileName, this.placement, OsmBuilder.Mode.Final);
-
-		this.setVisible(false);
+		this.removeLayer();
+
+		this.runAsBackgroundTask(
+				new Runnable() {
+					public void run() {
+						//async part
+						SwingRenderingProgressMonitor monitor = new SwingRenderingProgressMonitor(progressRenderer);
+						LoadPdfDialog.this.newLayer = LoadPdfDialog.this.makeLayer(tr("Imported PDF: ") + fileName, placement, OsmBuilder.Mode.Final, monitor);
+						progressRenderer.finish();
+					}
+				},
+				new ActionListener() {
+
+					public void actionPerformed(ActionEvent e) {
+						//sync part
+						//rebuild layer with latest projection
+						LoadPdfDialog.this.placeLayer(newLayer, placement);
+						LoadPdfDialog.this.setVisible(false);
+					}
+				});
 	}
 
 	private void savePressed() {
 
-		if (!preparePlacement()) {
+		final FilePlacement placement = preparePlacement();
+		if (placement == null) {
 			return;
-		}		
-
-		java.io.File file = this.chooseSaveFile();
+		}
+
+		final java.io.File file = this.chooseSaveFile();
 
 		if (file == null){
 			return;
-		}		
-		
-		//rebuild layer with latest projection
+		}
+
 		this.removeLayer();
 
-
-		this.saveLayer(file);
-		this.setVisible(false);
+		this.runAsBackgroundTask(
+				new Runnable() {
+					public void run() {
+						//async part
+						SwingRenderingProgressMonitor monitor = new SwingRenderingProgressMonitor(progressRenderer);
+						LoadPdfDialog.this.saveLayer(file, placement, monitor);
+						progressRenderer.finish();
+					}
+				},
+				new ActionListener() {
+
+					public void actionPerformed(ActionEvent e) {
+						//sync part
+						LoadPdfDialog.this.setVisible(false);
+					}
+				});
 	}
 
@@ -389,13 +487,11 @@
 	private void showPressed() {
 
-		boolean ok = this.parsePlacement();
-		if (!ok){
+		FilePlacement placement = preparePlacement();
+		if (placement == null) {
 			return;
 		}
 
-		OsmBuilder builder = new OsmBuilder(this.placement);
-
 		//zoom to new location
-		Main.map.mapView.zoomTo(builder.getWorldBounds(this.data));
+		Main.map.mapView.zoomTo(placement.getWorldBounds(this.data));
 		Main.map.repaint();
 	}
@@ -511,11 +607,49 @@
 	}
 
-	private PathOptimizer loadPDF(File fileName) {
-
-		PathOptimizer data = new PathOptimizer();
+	private PathOptimizer loadPDF(File fileName, ProgressMonitor monitor) {
+
+		monitor.beginTask(tr(""), 100);
+		monitor.setTicks(0);
+		monitor.setCustomText(tr("Preparing"));
+
+		double nodesTolerance = 0.0;
+		Color color = null;
+
+		if (this.mergeCloseNodesCheck.isSelected()) {
+			try {
+				nodesTolerance = Double.parseDouble(this.mergeCloseNodesTolerance.getText());
+			}
+			catch (Exception e) {
+				JOptionPane
+				.showMessageDialog(
+						Main.parent,
+						tr("Tolerance is not a number"));
+				return null;
+			}
+		}
+
+		if (this.colorFilterCheck.isSelected()) {
+			try {
+				String colString = this.colorFilterColor.getText().replace("#", "");
+				color = new Color(Integer.parseInt(colString, 16));
+			}
+			catch (Exception e) {
+				JOptionPane
+				.showMessageDialog(
+						Main.parent,
+						tr("Could not parse color"));
+				return null;
+			}
+		}
+
+
+		monitor.setTicks(10);
+		monitor.setCustomText(tr("Parsing file"));
+
+		PathOptimizer data = new PathOptimizer(nodesTolerance, color);
 
 		try {
 			PdfBoxParser parser = new PdfBoxParser(data);
-			parser.parse(fileName);
+			parser.parse(fileName, monitor.createSubTaskMonitor(80, false));
 
 		} catch (FileNotFoundException e1) {
@@ -534,23 +668,10 @@
 		}
 
-		if (this.colorFilterCheck.isSelected()) {
-			try {
-				String colString = this.colorFilterColor.getText().replace("#", "");
-				Color color = new Color(Integer.parseInt(colString, 16));
-				data.filterByColor(color);
-			}
-			catch (Exception e) {
-				JOptionPane
-				.showMessageDialog(
-						Main.parent,
-						tr("Could not parse color"));
-				return null;
-			}
-		}
-
+		monitor.setTicks(80);
 
 		if (this.removeParallelSegmentsCheck.isSelected()) {
 			try {
 				double tolerance = Double.parseDouble(this.removeParallelSegmentsTolerance.getText());
+				monitor.setCustomText(tr("Removing parallel segments"));
 				data.removeParallelLines(tolerance);
 			}
@@ -564,8 +685,15 @@
 		}
 
-		if (this.mergeCloseNodesCheck.isSelected()) {
+		monitor.setTicks(85);
+		monitor.setCustomText(tr("Joining adjacent segments"));
+		data.mergeSegments();
+
+		if (this.removeSmallObjectsCheck.isSelected()) {
 			try {
-				double tolerance = Double.parseDouble(this.mergeCloseNodesTolerance.getText());
-				data.mergeNodes(tolerance);
+				double tolerance = Double.parseDouble(this.removeSmallObjectsSize.getText());
+				monitor.setTicks(90);
+				monitor.setCustomText(tr("Removing small objects"));
+
+				data.removeSmallObjects(tolerance);
 			}
 			catch (Exception e) {
@@ -578,10 +706,10 @@
 		}
 
-		data.mergeSegments();
-
-		if (this.removeSmallObjectsCheck.isSelected()) {
+		if (this.removeLargeObjectsCheck.isSelected()) {
 			try {
-				double tolerance = Double.parseDouble(this.removeSmallObjectsSize.getText());
-				data.removeSmallObjects(tolerance);
+				double tolerance = Double.parseDouble(this.removeLargeObjectsSize.getText());
+				monitor.setTicks(90);
+				monitor.setCustomText(tr("Removing large objects"));
+				data.removeLargeObjects(tolerance);
 			}
 			catch (Exception e) {
@@ -594,21 +722,10 @@
 		}
 
-
-		if (this.removeLargeObjectsCheck.isSelected()) {
-			try {
-				double tolerance = Double.parseDouble(this.removeLargeObjectsSize.getText());
-				data.removeLargeObjects(tolerance);
-			}
-			catch (Exception e) {
-				JOptionPane
-				.showMessageDialog(
-						Main.parent,
-						tr("Tolerance is not a number"));
-				return null;
-			}
-		}
-
+		monitor.setTicks(95);
+		monitor.setCustomText(tr("Finalizing layers"));
 		data.splitLayersByPathKind();
 		data.finish();
+
+		monitor.finishTask();
 		return data;
 	}
@@ -616,5 +733,5 @@
 
 
-	private boolean parsePlacement() {
+	private FilePlacement parsePlacement() {
 		Object selectedProjection = this.projectionCombo.getSelectedItem();
 
@@ -622,17 +739,19 @@
 		{
 			JOptionPane.showMessageDialog(Main.parent, tr("Please set a projection."));
-			return false;
-		}
-
-		this.placement.projection = (Projection)this.projectionCombo.getSelectedItem();
+			return null;
+		}
+
+		FilePlacement placement = new FilePlacement();
+
+		placement.projection = (Projection)this.projectionCombo.getSelectedItem();
 
 		try
 		{
-			this.placement.setPdfBounds(
+			placement.setPdfBounds(
 					Double.parseDouble(this.minXField.getText()),
 					Double.parseDouble(this.minYField.getText()),
 					Double.parseDouble(this.maxXField.getText()),
 					Double.parseDouble(this.maxYField.getText()));
-			this.placement.setEastNorthBounds(
+			placement.setEastNorthBounds(
 					Double.parseDouble(this.minEastField.getText()),
 					Double.parseDouble(this.minNorthField.getText()),
@@ -642,11 +761,16 @@
 		catch (Exception e) {
 			JOptionPane.showMessageDialog(Main.parent, tr("Could not parse numbers. Please check."));
-			return false;
-		}
-
-		return true;
-	}
-
-	private void setPlacement() {
+			return null;
+		}
+
+		return placement;
+	}
+
+	private void setPlacement(FilePlacement placement) {
+
+		if (placement == null) {
+			//use default values.
+			placement = new FilePlacement();
+		}
 
 		this.projectionCombo.setSelectedItem(placement.projection);
@@ -662,5 +786,6 @@
 
 
-	private void loadPlacement() {
+	private FilePlacement loadPlacement() {
+		FilePlacement pl = null;
 		//load saved transformation
 		File propertiesFile = new File(fileName.getAbsoluteFile()+ ".placement");
@@ -668,18 +793,22 @@
 
 			if (propertiesFile.exists()){
+				pl = new FilePlacement();
 				Properties p = new Properties();
 				p.load(new FileInputStream(propertiesFile));
-				this.placement.fromProperties(p);
+				pl.fromProperties(p);
 			}
 		}catch (Exception e){
+			pl = null;
 			e.printStackTrace();
 		}
-	}
-
-	private void savePlacement(){
+
+		return pl;
+	}
+
+	private void savePlacement(FilePlacement pl){
 		//load saved transformation
 		File propertiesFile = new File(fileName.getAbsoluteFile()+ ".placement");
 		try {
-			Properties p = this.placement.toProperties();
+			Properties p = pl.toProperties();
 			p.store(new FileOutputStream(propertiesFile), "PDF file placement on OSM");
 		} catch (Exception e){
@@ -689,23 +818,22 @@
 
 
-	private void makeLayer(String name, FilePlacement placement, OsmBuilder.Mode mode) {
+	private OsmDataLayer makeLayer(String name, FilePlacement placement, OsmBuilder.Mode mode, ProgressMonitor monitor) {
+		monitor.beginTask(tr("Building JOSM layer"), 100);
+		OsmBuilder builder = new OsmBuilder(placement);
+		DataSet data = builder.build(this.data.getLayers(), mode, monitor.createSubTaskMonitor(50, false));
+		monitor.setTicks(50);
+		monitor.setCustomText(tr("Postprocessing layer"));
+		OsmDataLayer result = new OsmDataLayer(data, name, null);
+		result.onPostLoadFromFile();
+
+		monitor.finishTask();
+		return result;
+	}
+
+	private void placeLayer(OsmDataLayer _layer, FilePlacement placement) {
 		this.removeLayer();
-
-		if (placement == null) {
-			return;
-		}
-
-		OsmBuilder builder = new OsmBuilder(placement);
-
-		DataSet data = builder.build(this.data.getLayers(), mode);
-		this.layer = new OsmDataLayer(data, name, null);
-
-		// Commit
-		this.layer.onPostLoadFromFile();
+		this.layer = _layer;
 		Main.main.addLayer(this.layer);
-		Main.map.mapView.zoomTo(builder.getWorldBounds(this.data));
-
-		this.okButton.setEnabled(true);
-		this.showButton.setEnabled(true);
+		Main.map.mapView.zoomTo(placement.getWorldBounds(this.data));
 	}
 
@@ -716,13 +844,15 @@
 			this.layer = null;
 		}
-
-		this.okButton.setEnabled(false);
-		this.showButton.setEnabled(false);
-	}
-
-	private void saveLayer(java.io.File file) {		
-		OsmBuilder builder = new OsmBuilder(this.placement);
-		DataSet data = builder.build(this.data.getLayers(), OsmBuilder.Mode.Final);
+	}
+
+	private void saveLayer(java.io.File file, FilePlacement placement, ProgressMonitor monitor) {
+		monitor.beginTask(tr("Saving to file."), 1000);
+
+		OsmBuilder builder = new OsmBuilder(placement);
+		DataSet data = builder.build(this.data.getLayers(), OsmBuilder.Mode.Final, monitor.createSubTaskMonitor(500, false));
 		OsmDataLayer layer = new OsmDataLayer(data, file.getName(), file);
+
+		monitor.setCustomText(tr(" Writing to file"));
+		monitor.setTicks(500);
 
 		OsmExporter exporter = new OsmExporter();
@@ -734,4 +864,6 @@
 			//TODO:
 		}
+
+		monitor.finishTask();
 	}
 
Index: /applications/editors/josm/plugins/pdfimport/src/pdfimport/OsmBuilder.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/pdfimport/OsmBuilder.java	(revision 24188)
+++ /applications/editors/josm/plugins/pdfimport/src/pdfimport/OsmBuilder.java	(revision 24189)
@@ -1,3 +1,5 @@
 package pdfimport;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.Color;
@@ -8,6 +10,4 @@
 import java.util.Map;
 
-import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
 public class OsmBuilder {
@@ -27,4 +28,7 @@
 	private Mode mode;
 
+	private ProgressMonitor monitor;
+	private int monitorPos;
+	private int monitorTotal;
 
 	public OsmBuilder(FilePlacement placement)
@@ -33,19 +37,28 @@
 	}
 
+	public DataSet build(List<LayerContents> data, Mode mode, ProgressMonitor monitor) {
 
-	public Bounds getWorldBounds(PathOptimizer data) {
-		LatLon min = placement.tranformCoords(new Point2D.Double(data.bounds.getMinX(), data.bounds.getMinY()));
-		LatLon max = placement.tranformCoords(new Point2D.Double(data.bounds.getMaxX(), data.bounds.getMaxY()));
-		return new Bounds(min, max);
-	}
-
-	public DataSet build(List<LayerContents> data, Mode mode) {
-
+		this.monitor = monitor;
+		this.monitorPos = 0;
 		this.mode = mode;
 		DataSet result = new DataSet();
+
+		//count total items for progress monitor.
+		this.monitorTotal = 0;
+		for (LayerContents layer: data) {
+			this.monitorTotal += layer.paths.size();
+			for(PdfMultiPath mp: layer.multiPaths){
+				this.monitorTotal += mp.paths.size();
+			}
+		}
+
+		monitor.beginTask(tr("Building JOSM layer."), this.monitorTotal);
+
 
 		for (LayerContents layer: data) {
 			this.addLayer(result, layer);
 		}
+
+		monitor.finishTask();
 		return result;
 	}
@@ -108,4 +121,8 @@
 
 	private Way insertWay(PdfPath path, Map<Point2D, Node> point2Node, int multipathId, boolean multipolygon) {
+
+		monitor.setExtraText(tr(" "+this.monitorPos+"/"+this.monitorTotal));
+		monitor.setTicks(this.monitorPos);
+		this.monitorPos ++;
 
 		List<Node> nodes = new ArrayList<Node>(path.points.size());
Index: /applications/editors/josm/plugins/pdfimport/src/pdfimport/PathOptimizer.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/pdfimport/PathOptimizer.java	(revision 24188)
+++ /applications/editors/josm/plugins/pdfimport/src/pdfimport/PathOptimizer.java	(revision 24189)
@@ -19,11 +19,16 @@
 	private List<LayerContents> layers;
 	public Rectangle2D bounds;
-
-	public PathOptimizer()
+	private final double pointsTolerance;
+	private final Color color;
+
+	public PathOptimizer(double _pointsTolerance, Color _color)
 	{
+
 		uniquePointMap = new HashMap<Point2D, Point2D>();
 		uniquePoints = new ArrayList<Point2D>();
 		layerMap = new HashMap<LayerInfo, LayerContents>();
 		layers = new ArrayList<LayerContents>();
+		pointsTolerance = _pointsTolerance;
+		color = _color;
 	}
 
@@ -42,4 +47,13 @@
 	public void addPath(LayerInfo info, PdfPath path)
 	{
+		if (!isColorOK(info)){
+			return;
+		}
+
+		if (path.points.size() > 10){
+			int a = 10;
+			a++;
+		}
+
 		LayerContents layer = this.getLayer(info);
 		layer.paths.add(path);
@@ -48,7 +62,24 @@
 	public void addMultiPath(LayerInfo info, List<PdfPath> paths) {
 
+		if (!isColorOK(info)){
+			return;
+		}
+
 		LayerContents layer = this.getLayer(info);
+
+		//optimize the paths
+		Set<Point2D> points = new HashSet<Point2D>();
+		for(PdfPath path: paths) {
+			points.addAll(path.points);
+		}
+		LayerContents multipathLayer = new LayerContents();
+		multipathLayer.paths = paths;
+		Map<Point2D, Point2D> pointMap = DuplicateNodesFinder.findDuplicateNodes(points, pointsTolerance);
+		this.fixPoints(multipathLayer,pointMap);
+		this.concatenatePaths(multipathLayer);
+
+		paths = multipathLayer.paths;
+
 		boolean goodMultiPath = true;
-
 		for(PdfPath path: paths) {
 			goodMultiPath &= path.isClosed();
@@ -63,27 +94,22 @@
 	}
 
-	public void filterByColor(Color color) {
+	private boolean isColorOK(LayerInfo info) {
+
+		if (color == null) {
+			return true;
+		}
 
 		int rgb = color.getRGB() & 0xffffff;
-
-		List<LayerContents> newLayers = new ArrayList<LayerContents>();
-		for(LayerContents l: this.layers) {
-
-			boolean good = false;
-
-
-			if (l.info.fill != null && (l.info.fill.getRGB() & 0xffffff) == rgb) {
-				good = true;
-			}
-
-			if (l.info.stroke != null && (l.info.stroke.getRGB() & 0xffffff) == rgb) {
-				good = true;
-			}
-
-			if (good) {
-				newLayers.add(l);
-			}
-		}
-		this.layers = newLayers;
+		boolean good = false;
+
+		if (info.fill != null && (info.fill.getRGB() & 0xffffff) == rgb) {
+			good = true;
+		}
+
+		if (info.stroke != null && (info.stroke.getRGB() & 0xffffff) == rgb) {
+			good = true;
+		}
+
+		return good;
 	}
 
@@ -95,6 +121,6 @@
 	}
 
-	public void mergeNodes(double tolerance) {
-		Map<Point2D, Point2D> pointMap = DuplicateNodesFinder.findDuplicateNodes(uniquePoints, tolerance);
+	public void mergeNodes() {
+		Map<Point2D, Point2D> pointMap = DuplicateNodesFinder.findDuplicateNodes(uniquePoints, pointsTolerance);
 
 		for(LayerContents layer: this.layers) {
@@ -491,12 +517,13 @@
 			}
 
-			//construct path
-
 			//remove from map
 			for (PdfPath path: pathChain) {
 				pathEndpoints.get(path.firstPoint()).remove(path);
 				pathEndpoints.get(path.lastPoint()).remove(path);
-			}
-
+				mergedPaths.add(path);
+			}
+
+
+			//construct path
 			PdfPath path = pathChain.get(0);
 
@@ -507,6 +534,4 @@
 					throw new RuntimeException();
 				}
-
-				mergedPaths.add(pathChain.get(pos));
 			}
 
Index: /applications/editors/josm/plugins/pdfimport/src/pdfimport/pdfbox/GraphicsProcessor.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/pdfimport/pdfbox/GraphicsProcessor.java	(revision 24188)
+++ /applications/editors/josm/plugins/pdfimport/src/pdfimport/pdfbox/GraphicsProcessor.java	(revision 24189)
@@ -1,3 +1,5 @@
 package pdfimport.pdfbox;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.BasicStroke;
@@ -11,4 +13,6 @@
 import java.util.List;
 
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+
 import pdfimport.LayerInfo;
 import pdfimport.PathOptimizer;
@@ -26,6 +30,7 @@
 
 	private final AffineTransform transform;
-
-	public GraphicsProcessor(PathOptimizer target, int rotation)
+	private final ProgressMonitor monitor;
+
+	public GraphicsProcessor(PathOptimizer target, int rotation, ProgressMonitor monitor)
 	{
 		this.target = target;
@@ -34,4 +39,5 @@
 		this.info.stroke = Color.BLACK;
 		this.info.fill = Color.BLACK;
+		this.monitor = monitor;
 	}
 
@@ -48,8 +54,11 @@
 		if (paths.size() > 1) {
 			this.target.addMultiPath(this.info, paths);
+			this.parsePath(s, closed);
 		}
 		else if (paths.size() == 1) {
 			this.target.addPath(this.info, paths.get(0));
 		}
+
+		this.monitor.setCustomText(tr(" {0} objects so far", pathNo));
 	}
 
Index: /applications/editors/josm/plugins/pdfimport/src/pdfimport/pdfbox/PageDrawer.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/pdfimport/pdfbox/PageDrawer.java	(revision 24188)
+++ /applications/editors/josm/plugins/pdfimport/src/pdfimport/pdfbox/PageDrawer.java	(revision 24189)
@@ -88,4 +88,5 @@
 			processStream( page, resources, page.getContents().getStream() );
 		}
+
 		List annotations = page.getAnnotations();
 		for( int i=0; i<annotations.size(); i++ )
Index: /applications/editors/josm/plugins/pdfimport/src/pdfimport/pdfbox/PdfBoxParser.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/pdfimport/pdfbox/PdfBoxParser.java	(revision 24188)
+++ /applications/editors/josm/plugins/pdfimport/src/pdfimport/pdfbox/PdfBoxParser.java	(revision 24189)
@@ -1,3 +1,4 @@
 package pdfimport.pdfbox;
+
 import static org.openstreetmap.josm.tools.I18n.tr;
 
@@ -10,4 +11,5 @@
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.util.PDFStreamEngine;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
 import pdfimport.PathOptimizer;
@@ -21,6 +23,8 @@
 
 	@SuppressWarnings("unchecked")
-	public void parse(File file) throws Exception
+	public void parse(File file, ProgressMonitor monitor) throws Exception
 	{
+		monitor.beginTask(tr("Parsing PDF", 1));
+
 		PDDocument document = PDDocument.load( file);
 
@@ -43,8 +47,10 @@
 		}
 
-		GraphicsProcessor p = new GraphicsProcessor(target, rotation);
+		GraphicsProcessor p = new GraphicsProcessor(target, rotation, monitor);
 		PageDrawer drawer = new PageDrawer();
 		drawer.drawPage(p, page);
 		this.target.bounds = new Rectangle2D.Double(pageSize.getLowerLeftX(), pageSize.getLowerLeftY(), pageSize.getWidth(), pageSize.getHeight());
+
+		monitor.finishTask();
 	}
 }
