Index: /trunk/src/org/openstreetmap/josm/data/imagery/Shape.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/Shape.java	(revision 17726)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/Shape.java	(revision 17727)
@@ -2,8 +2,7 @@
 package org.openstreetmap.josm.data.imagery;
 
-import static org.openstreetmap.josm.tools.I18n.tr;
-
+import java.awt.Polygon;
 import java.text.MessageFormat;
-import java.util.ArrayList;
+import java.util.AbstractList;
 import java.util.List;
 import java.util.Objects;
@@ -13,7 +12,7 @@
 import org.openstreetmap.gui.jmapviewer.Coordinate;
 import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.Geometry;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 /**
@@ -25,5 +24,5 @@
 public class Shape {
 
-    private final List<Coordinate> coords = new ArrayList<>();
+    private final Polygon coords;
 
     public Shape(String asString, String separator) {
@@ -33,4 +32,6 @@
             throw new IllegalArgumentException(MessageFormat.format("Even number of doubles expected in string, got {0}: {1}",
                     components.length, asString));
+        int size = components.length / 2;
+        this.coords = new Polygon(new int[size], new int[size], 0);
         for (int i = 0; i < components.length; i += 2) {
             addPoint(components[i], components[i+1]);
@@ -42,4 +43,5 @@
      */
     public Shape() {
+        coords = new Polygon();
         // shape contents can be set later with addPoint()
     }
@@ -51,5 +53,5 @@
      */
     public String encodeAsString(String separator) {
-        return coords.stream()
+        return getPoints().stream()
                 .flatMap(c -> Stream.of(c.getLat(), c.getLon()))
                 .map(String::valueOf)
@@ -69,14 +71,23 @@
 
     public List<Coordinate> getPoints() {
-        return coords;
+        return new AbstractList<Coordinate>() {
+            @Override
+            public Coordinate get(int index) {
+                double lat = coords.ypoints[index] / LatLon.MAX_SERVER_INV_PRECISION;
+                double lon = coords.xpoints[index] / LatLon.MAX_SERVER_INV_PRECISION;
+                return new Coordinate(lat, lon);
+            }
+
+            @Override
+            public int size() {
+                return coords.npoints;
+            }
+        };
     }
 
     public boolean contains(LatLon latlon) {
-        if (latlon == null)
-            return false;
-        List<Node> nodes = coords.stream()
-                .map(c -> new Node(new LatLon(c.getLat(), c.getLon())))
-                .collect(Collectors.toList());
-        return Geometry.nodeInsidePolygon(new Node(latlon), nodes);
+        return coords.contains(
+                latlon.getX() * LatLon.MAX_SERVER_INV_PRECISION,
+                latlon.getY() * LatLon.MAX_SERVER_INV_PRECISION);
     }
 
@@ -103,10 +114,12 @@
         }
 
-        coords.add(new Coordinate(LatLon.roundToOsmPrecision(lat), LatLon.roundToOsmPrecision(lon)));
+        coords.addPoint(
+                (int) (lon * LatLon.MAX_SERVER_INV_PRECISION),
+                (int) (lat * LatLon.MAX_SERVER_INV_PRECISION));
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(coords);
+        return Objects.hash(getPoints());
     }
 
@@ -116,5 +129,10 @@
         if (obj == null || getClass() != obj.getClass()) return false;
         Shape shape = (Shape) obj;
-        return Objects.equals(coords, shape.coords);
+        return Objects.equals(getPoints(), shape.getPoints());
+    }
+
+    @Override
+    public String toString() {
+        return "Shape{coords=" + getPoints() + '}';
     }
 }
