Unique Number generation based on latitude and longitude in Java and Python

2

I am trying to implement unique number generation based on latitude and longitude such that for same latitude and longitude pair the number generated should be same.

Other than that generated number should not exceed the maximum value of Integer in Java, which is 2147483647

Following python function is working fine

def get_unique_number(lat, lon):
  try:
    lat_double = None
    lon_double = None
    if isinstance(lat, str):
        lat_double = float(lat)
    else:
        lat_double = lat
    if isinstance(lon, str):
        lon_double = float(lon)
    else:
        lon_double = lon

    lat_int = int((lat_double * 1e7))
    lon_int = int((lon_double * 1e7))
    val = abs(lat_int << 16 & 0xffff0000 | lon_int & 0x0000ffff)
    val = val % 2147483647
    return val
except Exception as e:
    print("marking OD_LOC_ID as -1 getting exception inside get_unique_number function")
    print("Exception while generating od loc id")
    print(traceback.format_exc())
    return None

I need an equivalent Java implementation.

I have come up with a Java implementation of above function but that is not working for some of the latitude/longitude pair

public static int getUniqueId(double lat,double lon) {
    int lat_int = (int) (lat * 10000000);
    int lon_int = (int) (lon *  10000000);
    int val=Math.abs(lat_int << 16 & 0xffff0000 | lon_int & 0x0000ffff);
    val = val % Integer.MAX_VALUE;
    System.out.println(val);
    return val;
}

Some of the latitude/longitude pairs for which the two implementations are not returning same results are

  1. 44.6212179,-75.6963195
  2. 40.2318791,-78.9155315

How can I get same results from both python and Java implementation. It would really help if the implementation for Java is corrected as python implementation is working in Production environment.

java
python
latitude-longitude
asked on Stack Overflow Jun 11, 2020 by Amit Dube

1 Answer

3

Possibly, you should be using long type for Java implementation (because Python int is not as limited by length as its Java counterparts):

public static long getUniqueId(double lat,double lon) {
    long lat_int = (long) (lat * 10000000);
    long lon_int = (long) (lon * 10000000);
    long latMask = lat_int > 0x7FFF0000L ? 0x1ffff0000L : 0xffff0000L;
    long val=Math.abs(lat_int << 16 &  latMask | lon_int & 0x0000ffff);
    val = val % Integer.MAX_VALUE;
    System.out.println(val);
    return val;
}

Then for the given inputs the outputs will be:

44.6212179,-75.6963195 -> OLD: 676584886  -> 676571270
40.2318791,-78.9155315 -> OLD: 1707581954 -> 1707569678

Update Fixed the constant to allow one extra bit in the mask 0x1ffff0000L

Tested with additional data close to max/min limits of latitude and longitude -- the results are the same as for Python code.

getUniqueId( 179.8213878,  179.6963195);  // 284588923
getUniqueId( 179.8213878, -179.6963195);  // 284591239
getUniqueId(-179.6963195,  179.8213878);  //  75927799
getUniqueId(-179.6963195, -179.8213878);  //  75919115

Update 2

For the example in comments (44.6212179,-75.696319):

New example: (44.3252130,-79.6794917)

answered on Stack Overflow Jun 11, 2020 by Alex Rudenko • edited Jun 12, 2020 by Alex Rudenko

User contributions licensed under CC BY-SA 3.0