sector.java
来自「world wind java sdk 源码」· Java 代码 · 共 1,046 行 · 第 1/3 页
JAVA
1,046 行
/*Copyright (C) 2001, 2006 United States Governmentas represented by the Administrator of theNational Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.geom;import gov.nasa.worldwind.cache.*;import gov.nasa.worldwind.globes.*;import gov.nasa.worldwind.tracks.*;import gov.nasa.worldwind.util.*;import java.util.*;/** * <code>Sector</code> represents a rectangular reqion of latitude and longitude. The region is defined by four angles: * its minimum and maximum latitude, its minimum and maximum longitude. The angles are assumed to be normalized to +/- * 90 degrees latitude and +/- 180 degrees longitude. The minimums and maximums are relative to these ranges, e.g., -80 * is less than 20. Behavior of the class is undefined for angles outside these ranges. Normalization is not performed * on the angles by this class, nor is it verifed by the class' methods. See {@link Angle} for a description of * specifying angles. <p/> <code>Sector</code> instances are immutable. </p> * * @author Tom Gaskins * @version $Id: Sector.java 10899 2009-05-06 01:02:39Z dcollins $ * @see Angle */public class Sector implements Cacheable, Comparable<Sector>, Iterable<LatLon>{ /** * A <code>Sector</code> of latitude [-90 degrees, + 90 degrees] and longitude [-180 degrees, + 180 degrees]. */ public static final Sector FULL_SPHERE = new Sector(Angle.NEG90, Angle.POS90, Angle.NEG180, Angle.POS180); public static final Sector EMPTY_SECTOR = new Sector(Angle.ZERO, Angle.ZERO, Angle.ZERO, Angle.ZERO); private final Angle minLatitude; private final Angle maxLatitude; private final Angle minLongitude; private final Angle maxLongitude; private final Angle deltaLat; private final Angle deltaLon; /** * Creates a new <code>Sector</code> and initializes it to the specified angles. The angles are assumed to be * normalized to +/- 90 degrees latitude and +/- 180 degrees longitude, but this method does not verify that. * * @param minLatitude the sector's minimum latitude in degrees. * @param maxLatitude the sector's maximum latitude in degrees. * @param minLongitude the sector's minimum longitude in degrees. * @param maxLongitude the sector's maximum longitude in degrees. * @return the new <code>Sector</code> */ public static Sector fromDegrees(double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) { return new Sector(Angle.fromDegrees(minLatitude), Angle.fromDegrees(maxLatitude), Angle.fromDegrees( minLongitude), Angle.fromDegrees(maxLongitude)); } /** * Creates a new <code>Sector</code> and initializes it to the specified angles. The angles are assumed to be * normalized to +/- \u03c0/2 radians latitude and +/- \u03c0 radians longitude, but this method does not verify * that. * * @param minLatitude the sector's minimum latitude in radians. * @param maxLatitude the sector's maximum latitude in radians. * @param minLongitude the sector's minimum longitude in radians. * @param maxLongitude the sector's maximum longitude in radians. * @return the new <code>Sector</code> */ public static Sector fromRadians(double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) { return new Sector(Angle.fromRadians(minLatitude), Angle.fromRadians(maxLatitude), Angle.fromRadians( minLongitude), Angle.fromRadians(maxLongitude)); } public static Sector boundingSector(java.util.Iterator<TrackPoint> positions) { if (positions == null) { String message = Logging.getMessage("nullValue.TracksPointsIteratorNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (!positions.hasNext()) return EMPTY_SECTOR; TrackPoint position = positions.next(); double minLat = position.getLatitude(); double minLon = position.getLongitude(); double maxLat = minLat; double maxLon = minLon; while (positions.hasNext()) { TrackPoint p = positions.next(); double lat = p.getLatitude(); if (lat < minLat) minLat = lat; else if (lat > maxLat) maxLat = lat; double lon = p.getLongitude(); if (lon < minLon) minLon = lon; else if (lon > maxLon) maxLon = lon; } return Sector.fromDegrees(minLat, maxLat, minLon, maxLon); } public static Sector boundingSector(Iterable<? extends LatLon> locations) { if (locations == null) { String message = Logging.getMessage("nullValue.PositionsListIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } double minLat = Angle.POS90.getDegrees(); double minLon = Angle.POS180.getDegrees(); double maxLat = Angle.NEG90.getDegrees(); double maxLon = Angle.NEG180.getDegrees(); for (LatLon p : locations) { double lat = p.getLatitude().getDegrees(); if (lat < minLat) minLat = lat; if (lat > maxLat) maxLat = lat; double lon = p.getLongitude().getDegrees(); if (lon < minLon) minLon = lon; if (lon > maxLon) maxLon = lon; } if (minLat == maxLat && minLon == maxLon) return EMPTY_SECTOR; return Sector.fromDegrees(minLat, maxLat, minLon, maxLon); } public static Sector[] splitBoundingSectors(Iterable<? extends LatLon> locations) { if (locations == null) { String message = Logging.getMessage("nullValue.LocationInListIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } double minLat = Angle.POS90.getDegrees(); double minLon = Angle.POS180.getDegrees(); double maxLat = Angle.NEG90.getDegrees(); double maxLon = Angle.NEG180.getDegrees(); LatLon lastLocation = null; for (LatLon ll : locations) { double lat = ll.getLatitude().getDegrees(); if (lat < minLat) minLat = lat; if (lat > maxLat) maxLat = lat; double lon = ll.getLongitude().getDegrees(); if (lon >= 0 && lon < minLon) minLon = lon; if (lon <= 0 && lon > maxLon) maxLon = lon; if (lastLocation != null) { double lastLon = lastLocation.getLongitude().getDegrees(); if (Math.signum(lon) != Math.signum(lastLon)) { if (Math.abs(lon - lastLon) < 180) { // Crossing the zero longitude line too maxLon = 0; minLon = 0; } } } lastLocation = ll; } return new Sector[] { Sector.fromDegrees(minLat, maxLat, minLon, 180), // Sector on eastern hemisphere. Sector.fromDegrees(minLat, maxLat, -180, maxLon) // Sector on western hemisphere. }; } public static Sector boundingSector(LatLon pA, LatLon pB) { if (pA == null || pB == null) { String message = Logging.getMessage("nullValue.PositionsListIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } double minLat = pA.getLatitude().degrees; double minLon = pA.getLongitude().degrees; double maxLat = pA.getLatitude().degrees; double maxLon = pA.getLongitude().degrees; if (pB.getLatitude().degrees < minLat) minLat = pB.getLatitude().degrees; else if (pB.getLatitude().degrees > maxLat) maxLat = pB.getLatitude().degrees; if (pB.getLongitude().degrees < minLon) minLon = pB.getLongitude().degrees; else if (pB.getLongitude().degrees > maxLon) maxLon = pB.getLongitude().degrees; if (minLat == maxLat && minLon == maxLon) return EMPTY_SECTOR; return Sector.fromDegrees(minLat, maxLat, minLon, maxLon); } /** * Returns a new <code>Sector</code> encompassing a circle centered at a given position, * with a given radius in meter. * * @param globe a Globe instance. * @param center the circle center position. * @param radius the circle radius in meter. * @return the circle bounding sector. */ public static Sector boundingSector(Globe globe, LatLon center, double radius) { double halfDeltaLatRadians = radius / globe.getRadiusAt(center); double halfDeltaLonRadians = Math.PI * 2; if (center.getLatitude().cos() > 0) halfDeltaLonRadians = halfDeltaLatRadians / center.getLatitude().cos(); return new Sector( Angle.fromRadiansLatitude(center.getLatitude().radians - halfDeltaLatRadians), Angle.fromRadiansLatitude(center.getLatitude().radians + halfDeltaLatRadians), Angle.fromRadiansLongitude(center.getLongitude().radians - halfDeltaLonRadians), Angle.fromRadiansLongitude(center.getLongitude().radians + halfDeltaLonRadians)); } /** * Returns an iterable of Sectors encompassing a circle centered at a given position, with a given radius in meters. * If the geometry defined by the circle and radius spans the international dateline, this will return two sectors, * one for each side of the dateline. Otherwise, this will return a single bounding sector. * * @param globe a Globe instance. * @param center the circle center location. * @param radius the circle radius in meters. * @return the circle's bounding sectors. */ public static Sector[] splitBoundingSectors(Globe globe, LatLon center, double radius) { double halfDeltaLatRadians = radius / globe.getRadiusAt(center); double halfDeltaLonRadians = Math.PI * 2; if (center.getLatitude().cos() > 0) halfDeltaLonRadians = halfDeltaLatRadians / center.getLatitude().cos(); LatLon ll = new LatLon( Angle.fromRadiansLatitude(center.getLatitude().radians - halfDeltaLatRadians), Angle.normalizedLongitude(Angle.fromRadians(center.getLongitude().radians - halfDeltaLonRadians))); LatLon ur = new LatLon( Angle.fromRadiansLatitude(center.getLatitude().radians + halfDeltaLatRadians), Angle.normalizedLongitude(Angle.fromRadians(center.getLongitude().radians + halfDeltaLonRadians))); Iterable<? extends LatLon> locations = java.util.Arrays.asList(ll, ur); if (LatLon.positionsCrossDateLine(locations)) { return splitBoundingSectors(locations); } else { return new Sector[] {boundingSector(locations)}; } } /** * Creates a new <code>Sector</code> and initializes it to the specified angles. The angles are assumed to be * normalized to +/- 90 degrees latitude and +/- 180 degrees longitude, but this method does not verify that. * * @param minLatitude the sector's minimum latitude. * @param maxLatitude the sector's maximum latitude. * @param minLongitude the sector's minimum longitude. * @param maxLongitude the sector's maximum longitude. * @throws IllegalArgumentException if any of the angles are null */ public Sector(Angle minLatitude, Angle maxLatitude, Angle minLongitude, Angle maxLongitude) { if (minLatitude == null || maxLatitude == null || minLongitude == null || maxLongitude == null) { String message = Logging.getMessage("nullValue.InputAnglesNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.minLatitude = minLatitude; this.maxLatitude = maxLatitude; this.minLongitude = minLongitude; this.maxLongitude = maxLongitude; this.deltaLat = Angle.fromDegrees(this.maxLatitude.degrees - this.minLatitude.degrees); this.deltaLon = Angle.fromDegrees(this.maxLongitude.degrees - this.minLongitude.degrees); } public Sector(Sector sector) { if (sector == null) { String message = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.minLatitude = new Angle(sector.getMinLatitude()); this.maxLatitude = new Angle(sector.getMaxLatitude()); this.minLongitude = new Angle(sector.getMinLongitude()); this.maxLongitude = new Angle(sector.getMaxLongitude()); this.deltaLat = Angle.fromDegrees(this.maxLatitude.degrees - this.minLatitude.degrees); this.deltaLon = Angle.fromDegrees(this.maxLongitude.degrees - this.minLongitude.degrees); } /** * Returns the sector's minimum latitude. * * @return The sector's minimum latitude. */ public final Angle getMinLatitude() { return minLatitude; } /** * Returns the sector's minimum longitude. * * @return The sector's minimum longitude.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?