MapArea.java
- /*
- * *************************************************************************************************************************************************************
- *
- * MapView: a JavaFX map renderer for tile-based servers
- * http://tidalwave.it/projects/mapview
- *
- * Copyright (C) 2024 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
- *
- * *************************************************************************************************************************************************************
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- *
- * *************************************************************************************************************************************************************
- *
- * git clone https://bitbucket.org/tidalwave/mapview-src
- * git clone https://github.com/tidalwave-it/mapview-src
- *
- * *************************************************************************************************************************************************************
- */
- package it.tidalwave.mapviewer;
- import jakarta.annotation.Nonnull;
- import lombok.EqualsAndHashCode;
- import lombok.Getter;
- import lombok.RequiredArgsConstructor;
- import static lombok.AccessLevel.PRIVATE;
- /***************************************************************************************************************************************************************
- *
- * A rectangular area on the map.
- *
- * @author Fabrizio Giudici
- *
- **************************************************************************************************************************************************************/
- @RequiredArgsConstructor(access = PRIVATE) @Getter @EqualsAndHashCode
- public class MapArea
- {
- private final double north;
- private final double east;
- private final double south;
- private final double west;
- /***********************************************************************************************************************************************************
- * {@return a new area}.
- * @param north the north limit
- * @param east the east limit
- * @param south the south limit
- * @param west the west limit
- * @throws IllegalArgumentException when the values are unfeasible
- **********************************************************************************************************************************************************/
- public static MapArea of (final double north, final double east, final double south, final double west)
- {
- checkLatitude(north, "north");
- checkLatitude(south, "south");
- checkLongitude(east, "east");
- checkLongitude(west, "west");
- if (north < south)
- {
- throw new IllegalArgumentException(String.format("north (%f) must be greater on equal than south (%f)", north, south));
- }
- return new MapArea(north, east, south, west);
- }
- /***********************************************************************************************************************************************************
- * {@return the center of this area}.
- **********************************************************************************************************************************************************/
- @Nonnull
- public MapCoordinates getCenter()
- {
- var longitudeCenter = (west + east) / 2;
- if (isAcrossGreenwichAntimeridian())
- {
- longitudeCenter = longitudeCenter - 180;
- if (longitudeCenter <= -180)
- {
- longitudeCenter = 360 + longitudeCenter;
- }
- }
- return MapCoordinates.of((north + south) / 2, longitudeCenter);
- }
- /***********************************************************************************************************************************************************
- * {@return {@code true} if this area spans across the Greenwich antimeridian (180° W)}.
- **********************************************************************************************************************************************************/
- public boolean isAcrossGreenwichAntimeridian()
- {
- return east < west;
- }
- /***********************************************************************************************************************************************************
- * {@return {@code true} if this area contains the given coordinates}.
- * @param coordinates the coordinates
- **********************************************************************************************************************************************************/
- public boolean contains (@Nonnull final MapCoordinates coordinates)
- {
- return coordinates.latitude() <= north && coordinates.latitude() >= south
- && isAcrossGreenwichAntimeridian() ? coordinates.longitude() >= west && coordinates.longitude() <= east
- : coordinates.longitude() >= east && coordinates.longitude() <= west;
- }
- /***********************************************************************************************************************************************************
- * {@return {@code true} if this area contains the given area}.
- * @param that the area to compare
- **********************************************************************************************************************************************************/
- public boolean contains (@Nonnull final MapArea that)
- {
- return north >= that.north && south <= that.south && west <= that.west && east >= that.east;
- }
- /***********************************************************************************************************************************************************
- * {@inheritDoc}
- **********************************************************************************************************************************************************/
- @Override @Nonnull
- public String toString()
- {
- return String.format("(n=%.6f, e=%.6f, s=%.6f, w=%.6f)", north, east, south, west);
- }
- /***********************************************************************************************************************************************************
- *
- **********************************************************************************************************************************************************/
- private static void checkLatitude (final double latitude, @Nonnull final String name)
- {
- if (latitude < -90 || latitude > 90)
- {
- throw new IllegalStateException("Latitude must be in range [-90, 90]: " + name + "=" + latitude);
- }
- }
- /***********************************************************************************************************************************************************
- *
- **********************************************************************************************************************************************************/
- private static void checkLongitude (final double longitude, @Nonnull final String name)
- {
- if (longitude <= -180 || longitude > 180)
- {
- throw new IllegalStateException("Longitude must be in range (-180, 180]: " + name + "=" + longitude);
- }
- }
- }