com.mapcode.Boundary Maven / Gradle / Ivy
/*
* Copyright (C) 2014-2019, Stichting Mapcode Foundation (http://www.mapcode.com)
*
* 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.
*/
package com.mapcode;
import javax.annotation.Nonnull;
// ----------------------------------------------------------------------------------------------
// Package private implementation class. For internal use within the mapcode implementation only.
//----------------------------------------------------------------------------------------------
/**
* This class handles territory rectangles for mapcodes.
*/
final class Boundary {
private int latMicroDegMin; // Minimum latitude (in microdegrees). Inclusive.
private int lonMicroDegMin; // Minimum longitude (in microdegrees). Inclusive.
private int latMicroDegMax; // Minimum latitude (in microdegrees). Exclusive.
private int lonMicroDegMax; // Maximum longitude (in microdegrees). Exclusive.
// Get the singleton for the data model.
private static final DataModel DATA_MODEL = DataModel.getInstance();
private Boundary(final int latMicroDegMin, final int lonMicroDegMin, final int latMicroDegMax, final int lonMicroDegMax) {
this.lonMicroDegMin = lonMicroDegMin;
this.latMicroDegMin = latMicroDegMin;
this.latMicroDegMax = latMicroDegMax;
this.lonMicroDegMax = lonMicroDegMax;
}
// You have to use this factory method instead of a ctor.
@Nonnull
static Boundary createBoundaryForTerritoryRecord(final int territoryRecord) {
return new Boundary(
DATA_MODEL.getLatMicroDegMin(territoryRecord), DATA_MODEL.getLonMicroDegMin(territoryRecord),
DATA_MODEL.getLatMicroDegMax(territoryRecord), DATA_MODEL.getLonMicroDegMax(territoryRecord)
);
}
int getLonMicroDegMin() {
return lonMicroDegMin;
}
int getLonMicroDegMax() {
return lonMicroDegMax;
}
int getLatMicroDegMin() {
return latMicroDegMin;
}
int getLatMicroDegMax() {
return latMicroDegMax;
}
@Nonnull
Boundary extendBoundary(final int latMicroDegExtension, final int lonMicroDegExtension) {
lonMicroDegMin -= lonMicroDegExtension;
latMicroDegMin -= latMicroDegExtension;
lonMicroDegMax += lonMicroDegExtension;
latMicroDegMax += latMicroDegExtension;
return this;
}
/**
* Check if a point falls within a boundary. Note that the "min" values are inclusive for a boundary and
* the "max" values are exclusive.\
*
* Note: Points at the exact North pole with latitude 90 are never part of a boundary.
*
* @param p Point to check.
* @return True if the points falls within the boundary.
*/
boolean containsPoint(@Nonnull final Point p) {
if (!p.isDefined()) {
return false;
}
final int latMicroDeg = p.getLatMicroDeg();
if ((latMicroDegMin > latMicroDeg) || (latMicroDeg >= latMicroDegMax)) {
return false;
}
final int lonMicroDeg = p.getLonMicroDeg();
// Longitude boundaries can extend (slightly) outside the [-180,180) range.
if (lonMicroDeg < lonMicroDegMin) {
return (lonMicroDegMin <= (lonMicroDeg + Point.MICRO_DEG_360)) && ((lonMicroDeg + Point.MICRO_DEG_360) < lonMicroDegMax);
} else if (lonMicroDeg >= lonMicroDegMax) {
return (lonMicroDegMin <= (lonMicroDeg - Point.MICRO_DEG_360)) && ((lonMicroDeg - Point.MICRO_DEG_360) < lonMicroDegMax);
} else {
return true;
}
}
@Nonnull
public String toString() {
return "[" + (latMicroDegMin / Point.DEG_TO_MICRO_DEG) + ", " + (latMicroDegMax / Point.DEG_TO_MICRO_DEG) +
"), [" + (lonMicroDegMin / Point.DEG_TO_MICRO_DEG) + ", " + (lonMicroDegMax / Point.DEG_TO_MICRO_DEG) + ')';
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy