Index: trunk/data_nodist/projection/josm-epsg
===================================================================
--- trunk/data_nodist/projection/josm-epsg	(revision 9949)
+++ trunk/data_nodist/projection/josm-epsg	(revision 9950)
@@ -418,2 +418,9 @@
 # NAD83(2011) / Oregon Columbia River West zone (m)
 <6810> +proj=omerc +lat_0=45.91666666666666 +lonc=-123 +alpha=295 +k=1 +x_0=7000000 +y_0=-3000000 +no_uoff +gamma=295 +ellps=GRS80 +units=m +no_defs +bounds=-125,45,-121,47 <>
+##
+## Following entries use Sinusoidal projection
+##
+# ESRI:53008 / Sphere Sinusoidal
+<53008> +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs <>
+# ESRI:54008 / World Sinusoidal
+<54008> +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs <>
Index: trunk/data_nodist/projection/projection-reference-data
===================================================================
--- trunk/data_nodist/projection/projection-reference-data	(revision 9949)
+++ trunk/data_nodist/projection/projection-reference-data	(revision 9950)
@@ -99434,2 +99434,4 @@
     33.6479986243214,-30.979129564646307,275384.928819043,6570337.187710123
     36.34727380495864,-10.780930970153477,537965.480218321,8808221.436680382
+<EPSG:53008> +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs <>
+<EPSG:54008> +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs <>
Index: trunk/data_nodist/projection/projection-regression-test-data
===================================================================
--- trunk/data_nodist/projection/projection-regression-test-data	(revision 9949)
+++ trunk/data_nodist/projection/projection-regression-test-data	(revision 9950)
@@ -18941,2 +18941,10 @@
   en  -4112844.748691825 -2.0612730742246613E7
   ll2 -7.287777357194223 -99.21276976541854
+EPSG:53008
+  ll  58.982194186686854 -88.06214048573408
+  en  -5045893.591670716 6558520.755923763
+  ll2 58.982194186686850 -88.06214048573406
+EPSG:54008
+  ll  58.982194186686854 -88.06214048573408
+  en  -5064010.776136052 6540685.607089906
+  ll2 58.982194186686850 -88.06214048573408
Index: trunk/data_nodist/projection/projection-regression-test-data-java9
===================================================================
--- trunk/data_nodist/projection/projection-regression-test-data-java9	(revision 9949)
+++ trunk/data_nodist/projection/projection-regression-test-data-java9	(revision 9950)
@@ -18941,2 +18941,10 @@
   en  -7479308.587239638 1.6640290829933831E7
   ll2 74.61273823049683 -172.00114028240444
+EPSG:53008
+  ll  58.982194186686854 -88.06214048573408
+  en  -5045893.591670716 6558520.755923763
+  ll2 58.982194186686850 -88.06214048573406
+EPSG:54008
+  ll  58.982194186686854 -88.06214048573408
+  en  -5064010.776136052 6540685.607089906
+  ll2 58.982194186686850 -88.06214048573408
Index: trunk/src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 9949)
+++ trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 9950)
@@ -63,6 +63,8 @@
 
     private static DecimalFormat cDmsMinuteFormatter = new DecimalFormat("00");
-    private static DecimalFormat cDmsSecondFormatter = new DecimalFormat(Main.pref.get("latlon.dms.decimal-format", "00.0"));
-    private static DecimalFormat cDmMinuteFormatter = new DecimalFormat(Main.pref.get("latlon.dm.decimal-format", "00.000"));
+    private static DecimalFormat cDmsSecondFormatter = new DecimalFormat(
+            Main.pref == null ? "00.0" : Main.pref.get("latlon.dms.decimal-format", "00.0"));
+    private static DecimalFormat cDmMinuteFormatter = new DecimalFormat(
+            Main.pref == null ? "00.000" : Main.pref.get("latlon.dm.decimal-format", "00.000"));
     public static final DecimalFormat cDdFormatter;
     public static final DecimalFormat cDdHighPecisionFormatter;
Index: trunk/src/org/openstreetmap/josm/data/projection/Projections.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 9949)
+++ trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 9950)
@@ -41,4 +41,5 @@
 import org.openstreetmap.josm.data.projection.proj.Proj;
 import org.openstreetmap.josm.data.projection.proj.ProjFactory;
+import org.openstreetmap.josm.data.projection.proj.Sinusoidal;
 import org.openstreetmap.josm.data.projection.proj.SwissObliqueMercator;
 import org.openstreetmap.josm.data.projection.proj.TransverseMercator;
@@ -95,4 +96,5 @@
         registerBaseProjection("omerc", ObliqueMercator.class, "core");
         registerBaseProjection("somerc", SwissObliqueMercator.class, "core");
+        registerBaseProjection("sinu", Sinusoidal.class, "core");
         registerBaseProjection("stere", PolarStereographic.class, "core");
         registerBaseProjection("sterea", DoubleStereographic.class, "core");
Index: trunk/src/org/openstreetmap/josm/data/projection/proj/Sinusoidal.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/proj/Sinusoidal.java	(revision 9950)
+++ trunk/src/org/openstreetmap/josm/data/projection/proj/Sinusoidal.java	(revision 9950)
@@ -0,0 +1,64 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.projection.proj;
+
+import static java.lang.Math.abs;
+import static java.lang.Math.cos;
+import static java.lang.Math.sin;
+import static java.lang.Math.sqrt;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import org.openstreetmap.josm.data.Bounds;
+
+/**
+ * Sinusoidal projection (aka. Sanson–Flamsteed, Mercator equal-area projection)
+ * <p/>
+ * This class has been derived from the implementation of the <a href="https://github.com/geotools/geotools">Geotools</a> project;
+ * git 577dd2d, org.geotools.referencing.operation.projection.Sinusoidal at the time of migration.
+ */
+public class Sinusoidal extends AbstractProj {
+
+    @Override
+    public String getName() {
+        return tr("Sinusoidal");
+    }
+
+    @Override
+    public String getProj4Id() {
+        return "sinu";
+    }
+
+    @Override
+    public double[] project(final double phi, final double lambda) {
+        if (spherical) {
+            return new double[]{lambda * cos(phi), phi};
+        } else {
+            final double s = sin(phi);
+            return new double[]{lambda * cos(phi) / sqrt(1. - e2 * s * s), mlfn(phi, s, cos(phi))};
+        }
+    }
+
+    @Override
+    public double[] invproject(final double east, final double north) {
+        if (spherical) {
+            return new double[]{north, east / cos(north)};
+        } else {
+            final double phi = inv_mlfn(north);
+            double s = abs(phi);
+            final double lambda;
+            if (abs(s - Math.PI / 2) < 1e-10) {
+                lambda = 0.;
+            } else if (s < Math.PI / 2) {
+                s = sin(phi);
+                lambda = (east * sqrt(1. - e2 * s * s) / cos(phi)) % Math.PI;
+            } else {
+                return new double[]{0., 0.}; // this is an error and should be handled somehow
+            }
+            return new double[]{phi, lambda};
+        }
+    }
+
+    @Override
+    public Bounds getAlgorithmBounds() {
+        return new Bounds(-90, -180, 90, 180, false);
+    }
+}
Index: trunk/test/unit/org/openstreetmap/josm/data/projection/ProjectionTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/data/projection/ProjectionTest.java	(revision 9949)
+++ trunk/test/unit/org/openstreetmap/josm/data/projection/ProjectionTest.java	(revision 9950)
@@ -125,4 +125,5 @@
         testProj("laea", 3e-3, "+lat_0=34");
         testProj("merc", 1e-5, "");
+        testProj("sinu", 1e-4, "");
 
         if (error2) {
