Search code examples
javageolocationgeometrygsm

GSM cell (longitude, latitude), it's sector and some object (with longitude, latitude)


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

  1. GSM cell with longitude, latitude, azimuth, max and min distance. With the help of these parameters I can describe a sector (a part of circle)
  2. longitude, latitude and a radious of an object.

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

  1. touch one sector
  2. intercept one sector
  3. intercept several sectors of a given GSM cell

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?


Solution

  • 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.