forked from community/device-mgt-core
parent
d3eb32b5cc
commit
c74a56cb45
@ -0,0 +1,28 @@
|
|||||||
|
package org.wso2.carbon.device.mgt.core.geo;
|
||||||
|
|
||||||
|
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
|
||||||
|
|
||||||
|
public class GeoCluster {
|
||||||
|
private GeoCoordinate coordinates;
|
||||||
|
private long count;
|
||||||
|
private String geohashPrefix;
|
||||||
|
private String deviceId;
|
||||||
|
|
||||||
|
public GeoCluster(GeoCoordinate coordinates,long count,String geohashPrefix){
|
||||||
|
this.coordinates=coordinates;
|
||||||
|
this.count=count;
|
||||||
|
this.geohashPrefix=geohashPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceId(String deviceId) {
|
||||||
|
this.deviceId = deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceId() {
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package org.wso2.carbon.device.mgt.core.geo.geoHash;
|
||||||
|
|
||||||
|
public class GeoCoordinate {
|
||||||
|
private double latitude;
|
||||||
|
private double longitude;
|
||||||
|
|
||||||
|
public GeoCoordinate(double latitude, double longitude){
|
||||||
|
this.latitude=latitude;
|
||||||
|
this.longitude=longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLatitude() {
|
||||||
|
return latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLongitude() {
|
||||||
|
return longitude;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
package org.wso2.carbon.device.mgt.core.geo.geoHash;
|
||||||
|
|
||||||
|
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class GeoHashGenerator {
|
||||||
|
private static final String BASE_32 = "0123456789bcdefghjkmnpqrstuvwxyz";
|
||||||
|
private static final int GEOHASH_LENGTH = 16;
|
||||||
|
|
||||||
|
private GeoHashGenerator(){};
|
||||||
|
|
||||||
|
private static int divideRangeByValue(double value, double[] range) {
|
||||||
|
double mid = middle(range);
|
||||||
|
if (value >= mid) {
|
||||||
|
range[0] = mid;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
range[1] = mid;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void divideRangeByBit(int bit, double[] range) {
|
||||||
|
double mid = middle(range);
|
||||||
|
if (bit > 0) {
|
||||||
|
range[0] = mid;
|
||||||
|
} else {
|
||||||
|
range[1] = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double middle(double[] range) {
|
||||||
|
return (range[0] + range[1]) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encodeGeohash(double latitude, double longitude) {
|
||||||
|
int geohashLength=GEOHASH_LENGTH;
|
||||||
|
double[] latRange = new double[]{-90.0, 90.0};
|
||||||
|
double[] lonRange = new double[]{-180.0, 180.0};
|
||||||
|
boolean isEven = true;
|
||||||
|
int bit = 0;
|
||||||
|
int base32CharIndex = 0;
|
||||||
|
StringBuilder geohash = new StringBuilder();
|
||||||
|
|
||||||
|
while (geohash.length() < geohashLength) {
|
||||||
|
if (isEven) {
|
||||||
|
base32CharIndex = (base32CharIndex << 1) | divideRangeByValue(longitude, lonRange);
|
||||||
|
} else {
|
||||||
|
base32CharIndex = (base32CharIndex << 1) | divideRangeByValue(latitude, latRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
isEven = !isEven;
|
||||||
|
|
||||||
|
if (bit < 4) {
|
||||||
|
bit++;
|
||||||
|
} else {
|
||||||
|
geohash.append(BASE_32.charAt(base32CharIndex));
|
||||||
|
bit = 0;
|
||||||
|
base32CharIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return geohash.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encodeGeohash(DeviceLocation deviceLocation) {
|
||||||
|
return encodeGeohash(deviceLocation.getLatitude(), deviceLocation.getLongitude());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GeoCoordinate decodeGeohash(String geohash) {
|
||||||
|
double[] latRange = new double[]{-90.0, 90.0};
|
||||||
|
double[] lonRange = new double[]{-180.0, 180.0};
|
||||||
|
boolean isEvenBit = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < geohash.length(); i++) {
|
||||||
|
int base32CharIndex = BASE_32.indexOf(geohash.charAt(i));
|
||||||
|
for (int j = 4; j >= 0; j--) {
|
||||||
|
if (isEvenBit) {
|
||||||
|
divideRangeByBit((base32CharIndex >> j) & 1, lonRange);
|
||||||
|
} else {
|
||||||
|
divideRangeByBit((base32CharIndex >> j) & 1, latRange);
|
||||||
|
}
|
||||||
|
isEvenBit = !isEvenBit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GeoCoordinate coordinates = new GeoCoordinate(middle(latRange),middle(lonRange));
|
||||||
|
return coordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy;
|
||||||
|
|
||||||
|
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
|
||||||
|
|
||||||
|
public interface GeoHashLengthStrategy {
|
||||||
|
int getGeohashLength(GeoCoordinate southWest, GeoCoordinate northEast, int zoom);
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy;
|
||||||
|
|
||||||
|
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
|
||||||
|
|
||||||
|
public class ZoomGeoHashLengthStrategy implements GeoHashLengthStrategy{
|
||||||
|
|
||||||
|
private int minGeohashLength = 1;
|
||||||
|
private int maxGeohashLength = 16;
|
||||||
|
private int minZoom = 1;
|
||||||
|
private int maxZoom = 17;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGeohashLength(GeoCoordinate southWest, GeoCoordinate northEast, int zoom) {
|
||||||
|
double a = minGeohashLength / Math.exp(minZoom / (maxZoom - minZoom) * Math.log(maxGeohashLength / minGeohashLength));
|
||||||
|
double b = Math.log(maxGeohashLength / minGeohashLength) / (maxZoom - minZoom);
|
||||||
|
return (int) Math.max(minGeohashLength, Math.min(a * Math.exp(b * zoom), maxGeohashLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinGeohashLength(int minGeohashLength) {
|
||||||
|
this.minGeohashLength = minGeohashLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxGeohashLength(int maxGeohashLength) {
|
||||||
|
this.maxGeohashLength = maxGeohashLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinZoom(int minZoom) {
|
||||||
|
this.minZoom = minZoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxZoom(int maxZoom) {
|
||||||
|
this.maxZoom = maxZoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinGeohashLength() {
|
||||||
|
return minGeohashLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxGeohashLength() {
|
||||||
|
return maxGeohashLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinZoom() {
|
||||||
|
return minZoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxZoom() {
|
||||||
|
return maxZoom;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue