Class LambertEqualAreaProjection
- All Implemented Interfaces:
IMapProjection
Forward equations (Snyder, spherical form)
k = √(2 / (1 + sin φ₀ sin φ + cos φ₀ cos φ cos(λ - λ₀))) x = k · cos φ · sin(λ - λ₀) y = k · (cos φ₀ · sin φ − sin φ₀ · cos φ · cos(λ - λ₀))
Inverse equations
ρ = √(x² + y²), c = 2 arcsin(ρ / 2) φ = arcsin(cos c · sin φ₀ + (y · sin c · cos φ₀) / ρ) λ = λ₀ + atan2(x · sin c, ρ · cos φ₀ · cos c − y · sin φ₀ · sin c)
Domain
The entire sphere maps to a disk of radius 2 (for R = 1). The antipode of the center point maps to the outer boundary circle. The bounding box is [-2, -2] to [2, 2].
Antipode singularity
When the denominator 1 + cos γ approaches zero, the input point is at
or extremely close to the antipode of the projection center. The antipode is
not represented by one unique point in the projected disk; the limiting point
on the boundary depends on the direction of approach. This implementation
therefore returns NaN for the exact singular point, and drawing
routines break the polyline at that location.
No seam
The Lambert projection has no antimeridian seam because the mapping from
globe to disk is continuous. The default IMapProjection.crossesSeam(double, double)
returning false is correct for this class.
-
Constructor Summary
ConstructorsConstructorDescriptionConvenience constructor centered at (0°, 0°).LambertEqualAreaProjection(double centerLon, double centerLat) Creates a Lambert equal-area projection centered at the given geographic point.LambertEqualAreaProjection(double centerLon, double centerLat, MapTheme theme) Convenience constructor that sets both the center and the theme atomically, preventing the NullPointerException that arises when drawing methods are called before the theme is set.Convenience constructor centered at (0°, 0°) with the given theme. -
Method Summary
Modifier and TypeMethodDescriptioncreateClipShape(IContainer container) Creates a clipShapein device coordinates that matches the projection's valid domain.voiddrawLatitudeLine(Graphics2D g2, IContainer container, double latitude) Draws a line of constant latitude (a parallel) at the given latitude.voiddrawLongitudeLine(Graphics2D g2, IContainer container, double longitude) Draws a line of constant longitude (a meridian) at the given longitude.voiddrawMapOutline(Graphics2D g2, IContainer container) Draws the outer boundary of the projection domain.Returns theEProjectionenum constant that identifies this implementation, if this projection is one of MDI's built-in projections.getTheme()Returns theMapThemecurrently used by this projection for drawing outlines and graticule lines.Returns the bounding rectangle of the projection-space domain in world coordinates.booleanTests whether a projection-space point lies within the valid domain of this projection.booleanisPointVisible(Point2D.Double latLon) Tests whether a geographic location is visible in this projection.voidlatLonFromXY(Point2D.Double latLon, Point2D.Double xy) Inverse projection: projection-space (x, y) → geographic (λ, φ).voidlatLonToXY(Point2D.Double latLon, Point2D.Double xy) Forward projection: geographic (λ, φ) → projection-space (x, y).voidsetCenter(double centerLon, double centerLat) Changes the center of the projection.voidSets theMapThemeused by this projection for all subsequent drawing operations.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface edu.cnu.mdi.mapping.projection.IMapProjection
crossesSeam, fillOcean, isLongitudePeriodic, name, recenterOn, supportsRecenter, wrapLatitude, wrapLongitude
-
Constructor Details
-
LambertEqualAreaProjection
public LambertEqualAreaProjection(double centerLon, double centerLat) Creates a Lambert equal-area projection centered at the given geographic point. TheMapThememust be set viasetTheme(MapTheme)before any drawing methods are called, or use the three-argument constructor to set it atomically.- Parameters:
centerLon- central longitude λ₀ in radianscenterLat- central latitude φ₀ in radians
-
LambertEqualAreaProjection
public LambertEqualAreaProjection()Convenience constructor centered at (0°, 0°). The theme must still be set before drawing. -
LambertEqualAreaProjection
Convenience constructor that sets both the center and the theme atomically, preventing the NullPointerException that arises when drawing methods are called before the theme is set.- Parameters:
centerLon- central longitude λ₀ in radianscenterLat- central latitude φ₀ in radianstheme- map theme; must not benull
-
LambertEqualAreaProjection
Convenience constructor centered at (0°, 0°) with the given theme.- Parameters:
theme- map theme; must not benull
-
-
Method Details
-
setCenter
public void setCenter(double centerLon, double centerLat) Changes the center of the projection. The next repaint will show the globe centred on the new point.- Parameters:
centerLon- central longitude λ₀ in radianscenterLat- central latitude φ₀ in radians
-
latLonToXY
Forward projection: geographic (λ, φ) → projection-space (x, y).Implementations should clamp the latitude to their valid range before computing to avoid
NaNorInfinityresults at the poles.For hemispherical projections (e.g. orthographic) a point on the far side of the globe should set
xyto(Double.NaN, Double.NaN)rather than throwing, because callers testisPointVisibleseparately.Latitude is clamped to [
MIN_LAT,MAX_LAT] before projection. When the input point is the antipode of the center (the denominator1 + cos γ ≈ 0, tested asdenom <= 1e-15), both output coordinates are set toDouble.NaNrather than a boundary point, since the true projected location is undefined at that singularity.- Specified by:
latLonToXYin interfaceIMapProjection- Parameters:
latLon- input geographic point in radians (x=λ, y=φ); must not benullxy- output projection-space point; must not benull
-
latLonFromXY
Inverse projection: projection-space (x, y) → geographic (λ, φ).If the input point lies outside the valid projection domain, implementations should set
latLonto(Double.NaN, Double.NaN)rather than throwing.- Specified by:
latLonFromXYin interfaceIMapProjection- Parameters:
latLon- output geographic point in radians (x=λ, y=φ); must not benullxy- input projection-space point; must not benull
-
isPointVisible
Tests whether a geographic location is visible in this projection.Global projections (Mercator, Mollweide, Lambert) generally return
truefor any point within their latitude range. Hemispherical projections (Orthographic) returntrueonly for points on the visible hemisphere.The Lambert projection maps the entire globe, so every point in the valid latitude range is visible.
- Specified by:
isPointVisiblein interfaceIMapProjection- Parameters:
latLon- geographic point in radians (x=λ, y=φ)- Returns:
trueif the point is visible;falseotherwise
-
isPointOnMap
Tests whether a projection-space point lies within the valid domain of this projection.This is used after
IMapProjection.latLonToXY(java.awt.geom.Point2D.Double, java.awt.geom.Point2D.Double)to guard against rendering points that fall slightly outside the projection boundary due to floating-point rounding.A point is on the map when it lies within or on the boundary of the disk: x² + y² ≤ RHO_MAX².
- Specified by:
isPointOnMapin interfaceIMapProjection- Parameters:
xy- projection-space point- Returns:
trueif the point is on (or inside) the map;falseotherwise
-
drawMapOutline
Draws the outer boundary of the projection domain.Typical implementations build a
Path2Din world coordinates, transform each vertex to screen space viacontainer.worldToLocal, then stroke the path using colors and widths from the currentMapTheme.Draws the circular boundary of the projection disk (radius
RHO_MAX = 2) using the theme's outline color and stroke width.- Specified by:
drawMapOutlinein interfaceIMapProjection- Parameters:
g2- graphics context to draw intocontainer- container providing the world-to-local transform
-
drawLatitudeLine
Draws a line of constant latitude (a parallel) at the given latitude.Implementations should approximate the curve by sampling at a sufficient number of longitude values, projecting each sample, and connecting the resulting screen points with a polyline. The line color must be
MapTheme.getGraticuleColor()so that theme switching takes full effect.Samples 360 evenly-spaced longitudes at the given latitude and connects the projected screen points. NaN results (e.g. near the antipode boundary) are skipped. Uses
MapTheme.getGraticuleColor()so the line color reflects the active theme.- Specified by:
drawLatitudeLinein interfaceIMapProjection- Parameters:
g2- graphics contextcontainer- container providing the world-to-local transformlatitude- latitude φ in radians, typically in [-π/2, π/2]
-
drawLongitudeLine
Draws a line of constant longitude (a meridian) at the given longitude.Implementations should approximate the curve by sampling at a sufficient number of latitude values, projecting each sample, and connecting the resulting screen points with a polyline. The line color must be
MapTheme.getGraticuleColor()so that theme switching takes full effect.Samples 180 evenly-spaced latitudes at the given longitude and connects the projected screen points. Uses
MapTheme.getGraticuleColor()for the line color.- Specified by:
drawLongitudeLinein interfaceIMapProjection- Parameters:
g2- graphics contextcontainer- container providing the world-to-local transformlongitude- longitude λ in radians, typically in [-π, π]
-
getProjection
Returns theEProjectionenum constant that identifies this implementation, if this projection is one of MDI's built-in projections.Application-supplied projections are allowed to return
null. This permits an application to provide a projection without modifyingEProjection,ProjectionFactory, or other MDI built-in projection registries.- Specified by:
getProjectionin interfaceIMapProjection- Returns:
- the built-in projection type, or
nullfor a custom application-supplied projection
-
getXYBounds
Returns the bounding rectangle of the projection-space domain in world coordinates.This rectangle is used by
IContainerimplementations to build the initial world-to-screen transform. The returned rectangle should tightly enclose the entire valid projected domain (e.g. [-π, π] × [MIN_Y, MAX_Y] for Mercator).Returns the bounding square of the disk: [-RHO_MAX, -RHO_MAX] to [RHO_MAX, RHO_MAX], i.e. [-2, -2] to [2, 2] for a unit sphere.
- Specified by:
getXYBoundsin interfaceIMapProjection- Returns:
- bounding rectangle in projection space; never
null
-
getTheme
Returns theMapThemecurrently used by this projection for drawing outlines and graticule lines.Implementations must never return
nullonce the theme has been set.- Specified by:
getThemein interfaceIMapProjection- Returns:
- the active map theme
-
setTheme
Sets theMapThemeused by this projection for all subsequent drawing operations.- Specified by:
setThemein interfaceIMapProjection- Parameters:
theme- the new theme; must not benull- Throws:
IllegalArgumentException- ifthemeisnull
-
createClipShape
Creates a clipShapein device coordinates that matches the projection's valid domain.This shape is used to:
- Clip land/ocean rendering to the map region.
- Fill the ocean background via
IMapProjection.fillOcean(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer).
Returns a circular path in device coordinates matching the disk boundary (radius
RHO_MAX), used as a clip region for ocean fill and land rendering.- Specified by:
createClipShapein interfaceIMapProjection- Parameters:
container- container providing the world-to-local transform- Returns:
- a device-space
Shape, ornullif no clip is defined for this projection
-