source: josm/trunk/src/org/openstreetmap/josm/data/projection/AbstractProjection.java@ 10621

Last change on this file since 10621 was 10001, checked in by Don-vip, 8 years ago

sonar - Local variable and method parameter names should comply with a naming convention

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.projection;
3
4import org.openstreetmap.josm.data.Bounds;
5import org.openstreetmap.josm.data.ProjectionBounds;
6import org.openstreetmap.josm.data.coor.EastNorth;
7import org.openstreetmap.josm.data.coor.LatLon;
8import org.openstreetmap.josm.data.projection.datum.Datum;
9import org.openstreetmap.josm.data.projection.proj.Proj;
10
11/**
12 * Implementation of the Projection interface that represents a coordinate reference system and delegates
13 * the real projection and datum conversion to other classes.
14 *
15 * It handles false easting and northing, central meridian and general scale factor before calling the
16 * delegate projection.
17 *
18 * Forwards lat/lon values to the real projection in units of radians.
19 *
20 * The fields are named after Proj.4 parameters.
21 *
22 * Subclasses of AbstractProjection must set ellps and proj to a non-null value.
23 * In addition, either datum or nadgrid has to be initialized to some value.
24 */
25public abstract class AbstractProjection implements Projection {
26
27 protected Ellipsoid ellps;
28 protected Datum datum;
29 protected Proj proj;
30 protected double x0; /* false easting (in meters) */
31 protected double y0; /* false northing (in meters) */
32 protected double lon0; /* central meridian */
33 protected double pm; /* prime meridian */
34 protected double k0 = 1.0; /* general scale factor */
35 protected double toMeter = 1.0; /* switch from meters to east/north coordinate units */
36
37 private volatile ProjectionBounds projectionBoundsBox;
38
39 public final Ellipsoid getEllipsoid() {
40 return ellps;
41 }
42
43 public final Datum getDatum() {
44 return datum;
45 }
46
47 /**
48 * Replies the projection (in the narrow sense)
49 * @return The projection object
50 */
51 public final Proj getProj() {
52 return proj;
53 }
54
55 public final double getFalseEasting() {
56 return x0;
57 }
58
59 public final double getFalseNorthing() {
60 return y0;
61 }
62
63 public final double getCentralMeridian() {
64 return lon0;
65 }
66
67 public final double getScaleFactor() {
68 return k0;
69 }
70
71 /**
72 * Get the factor that converts meters to intended units of east/north coordinates.
73 *
74 * For projected coordinate systems, the semi-major axis of the ellipsoid is
75 * always given in meters, which means the preliminary projection result will
76 * be in meters as well. This factor is used to convert to the intended units
77 * of east/north coordinates (e.g. feet in the US).
78 *
79 * For geographic coordinate systems, the preliminary "projection" result will
80 * be in degrees, so there is no reason to convert anything and this factor
81 * will by 1 by default.
82 *
83 * @return factor that converts meters to intended units of east/north coordinates
84 */
85 public final double getToMeter() {
86 return toMeter;
87 }
88
89 @Override
90 public EastNorth latlon2eastNorth(LatLon ll) {
91 ll = datum.fromWGS84(ll);
92 double[] en = proj.project(Math.toRadians(ll.lat()), Math.toRadians(LatLon.normalizeLon(ll.lon() - lon0 - pm)));
93 return new EastNorth((ellps.a * k0 * en[0] + x0) / toMeter, (ellps.a * k0 * en[1] + y0) / toMeter);
94 }
95
96 @Override
97 public LatLon eastNorth2latlon(EastNorth en) {
98 double[] latlonRad = proj.invproject((en.east() * toMeter - x0) / ellps.a / k0, (en.north() * toMeter - y0) / ellps.a / k0);
99 LatLon ll = new LatLon(Math.toDegrees(latlonRad[0]), LatLon.normalizeLon(Math.toDegrees(latlonRad[1]) + lon0 + pm));
100 return datum.toWGS84(ll);
101 }
102
103 @Override
104 public double getDefaultZoomInPPD() {
105 // this will set the map scaler to about 1000 m
106 return 10;
107 }
108
109 /**
110 * @return The EPSG Code of this CRS, null if it doesn't have one.
111 */
112 public abstract Integer getEpsgCode();
113
114 /**
115 * Default implementation of toCode().
116 * Should be overridden, if there is no EPSG code for this CRS.
117 */
118 @Override
119 public String toCode() {
120 return "EPSG:" + getEpsgCode();
121 }
122
123 protected static final double convertMinuteSecond(double minute, double second) {
124 return (minute/60.0) + (second/3600.0);
125 }
126
127 protected static final double convertDegreeMinuteSecond(double degree, double minute, double second) {
128 return degree + (minute/60.0) + (second/3600.0);
129 }
130
131 @Override
132 public final ProjectionBounds getWorldBoundsBoxEastNorth() {
133 ProjectionBounds result = projectionBoundsBox;
134 if (result == null) {
135 synchronized (this) {
136 result = projectionBoundsBox;
137 if (result == null) {
138 Bounds b = getWorldBoundsLatLon();
139 // add 4 corners
140 result = new ProjectionBounds(latlon2eastNorth(b.getMin()));
141 result.extend(latlon2eastNorth(b.getMax()));
142 result.extend(latlon2eastNorth(new LatLon(b.getMinLat(), b.getMaxLon())));
143 result.extend(latlon2eastNorth(new LatLon(b.getMaxLat(), b.getMinLon())));
144 // and trace along the outline
145 double dLon = (b.getMaxLon() - b.getMinLon()) / 1000;
146 double dLat = (b.getMaxLat() - b.getMinLat()) / 1000;
147 for (double lon = b.getMinLon(); lon < b.getMaxLon(); lon += dLon) {
148 result.extend(latlon2eastNorth(new LatLon(b.getMinLat(), lon)));
149 result.extend(latlon2eastNorth(new LatLon(b.getMaxLat(), lon)));
150 }
151 for (double lat = b.getMinLat(); lat < b.getMaxLat(); lat += dLat) {
152 result.extend(latlon2eastNorth(new LatLon(lat, b.getMinLon())));
153 result.extend(latlon2eastNorth(new LatLon(lat, b.getMaxLon())));
154 }
155 projectionBoundsBox = result;
156 }
157 }
158 }
159 return projectionBoundsBox;
160 }
161}
Note: See TracBrowser for help on using the repository browser.