I have rather simple task and I would like to ask you for recommendation. I hope there is a Java library which can help me.
Description
Given
Meaning
Each GSM cell consists of several sectors (they start from one point). Each object is represented as a circle (longitude, latitude, radius). A circle can
Task: I get a list of GSM cells and an object. I need to find all iterceptions/touches of an object with some sectors. I need to order by resulting list of interceptions by square of interception.
Look like typical math/geometry task. Is there any library in Java which can help me?
So here is my solution. We deciced that "center" of 2D projection should be relative. It does fit our task. Here are some code samples:
public final class GeometryUtil {
/**
https://www.cfa.harvard.edu/~dfabricant/huchra/ay145/constants.html
1 Earth Radius = 6.37814x108 cm = 6.37814x10^6 m (Equatorial)
*/
public static final double EARTH_RADIUS_IN_METERS = 6.37814e+6;
private GeometryUtil(){}
/**
* @param geoPoint is a point of some object you want to translate to Cartesian.
* @param geoPointRelative is a point of relative center.
* We suppose that this relative GeoPoint is a center for the first parameter.
* */
public static Coordinate toCoordinate(GeoPoint geoPoint, GeoPoint geoPointRelative){
return new Coordinate(toX(geoPoint, geoPointRelative.getLongitude()),
toY(geoPoint, geoPointRelative.getLatitude()));
}
public static double toX(GeoPoint geoPoint, double relativeLongitude){
return EARTH_RADIUS_IN_METERS *
cos(toRadians(geoPoint.getLatitude())) *
toRadians(geoPoint.getLongitude()- relativeLongitude);
}
public static double toY(GeoPoint geoPoint, double relativeLatitude){
return EARTH_RADIUS_IN_METERS * toRadians(geoPoint.getLatitude() - relativeLatitude);
}
}
Here is a builder for Geometry figures:
public final class GeometryBuilder {
private static final int DIAMETER_MULTIPLIER = 2;
private static final int TURN_LEFT = 90; //We should start to roll to the right from "North"/"Up"/12 o'clock
private GeometryBuilder(){}
public static Circle buildCirlce(GeoPoint centerOfCircle, GeoPoint relativeCenter, Distance radiusDistance){
GeometricShapeFactory geometricShapeFactory = new GeometricShapeFactory();
geometricShapeFactory.setCentre(GeometryUtil.toCoordinate(centerOfCircle, relativeCenter));
geometricShapeFactory.setSize(radiusDistance.getMeters() * DIAMETER_MULTIPLIER);
return new Circle(geometricShapeFactory.createEllipse());
}
public static Sector buildGSMCellSector(GSMCellLocation gsmCellLocation, GeoPoint relativeCenter){
GeometricShapeFactory geometricShapeFactory = new GeometricShapeFactory();
geometricShapeFactory.setCentre(GeometryUtil.toCoordinate(gsmCellLocation.getGeoPoint(), relativeCenter));
geometricShapeFactory.setSize(gsmCellLocation.getMidDist() * DIAMETER_MULTIPLIER);
return new Sector(geometricShapeFactory.createArcPolygon(-toRadians(gsmCellLocation.getEndAngle()- TURN_LEFT),
toRadians(gsmCellLocation.getAngleWidth())));
}
}
I should mention that TURN_LEFT is specific. Angles of my object starts at 12 o'clock. Geometry library starts to count from 3 o'clock. That it why I have to turn it 3 hours (90 degrees) back.
The problem is solved. I've also used LiteShape to draw some images to PNG file. Everythng is ok.