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 + -
显示快捷键?