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
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.
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)
User contributions licensed under CC BY-SA 3.0