Hi Daniel,
Thanks for the prompt reply. Here is the sample code,
I generated 10 million points using mapreduce like this
public void map (LongWritable k1, Text v1, Context context) throws InterruptedException, IOException {
long limit = 0, max = 10000000; // generates uniform dataset of coordinates from 0 to 10,000,000 e.g (0,0) (1,1) ...... (999999,999999)
try {
// construct key
long i,j=limit;
for(i=limit; i<max; i++) {
BitVector bv = HilbertUtils.HilbertConvertor(i, j); // returns BitVector of hilbert mapping of i and j as per the wiki
String rowKey = bv.toString();
long value = Math.abs(System.nanoTime()); // sample value
String svalue = Long.toString(value);
Put put = new Put(Bytes.toBytes(rowKey));
put.add(Bytes.toBytes("location"), Bytes.toBytes("longlat"), Bytes.toBytes(svalue));
context.write(new ImmutableBytesWritable(Bytes.toBytes(rowKey)), put); // put key value into HTable
context.setStatus("Inserting "+rowKey);
j++;
}
for example :
<key> <family:qualifier> <value>
100000001010001010001000100000100000000010100010 longitude:latitude 567777432169954
Now I have to write another mapper function which will execute a range query like this :
take the key
calculate inverse hilbert mapping to get original coordinates
check if its in range (min<x<max) && (min<y<max)
write key-value in another table
public void map (ImmutableBytesWritable rowkey, Result result, Context context) throws InterruptedException, IOException {
// sample Query values
int xmin = 711845 ; // 255000
int ymin = 711845 ;
int xmax = 1711845;
int ymax = 1711845;
// extract key and check for range
String composite = Bytes.toString(rowkey.get());
{
// code to calculate inverse h mapping of String Composite to get x and y
if ((xmin <= x) && ( xmax >= x) && ( ymin <= y) && (ymax >= y)) {
try {
Put put = new Put(rowkey.get());
for (KeyValue kv : result.raw()) {
put.add(kv);
}
context.write(rowkey, put);
} catch (InterruptedException e) {
throw new IOException(e);
}
}
}
--------------------------------------------------------------------------------------------------
I am stuck at this point as to how to modify this code to calculate inverse hilbert mapping :
CompactHilbertCurve chc = new CompactHilbertCurve(new int[] {2, 2});
List<Integer> bitsPerDimension = chc.getSpec().getBitsPerDimension();
BitVector[] p = new BitVector[bitsPerDimension.size()];
for (int i = p.length; --i >= 0;) {
p[i] = BitVectorFactories.OPTIMAL.apply(bitsPerDimension.get(i));
}
p[0].copyFrom(0b10);
p[1].copyFrom(0b11);
BitVector chi = BitVectorFactories.OPTIMAL.apply(chc.getSpec().sumBitsPerDimension());
chc.index(p, 0, chi);
System.out.println(String.format(Locale.ROOT, "index([0b%s, 0b%s])=0b%s", p[0], p[1], chi));
// Next line overwrites whatever is already written in p.
chc.indexInverse(chi, p);
System.out.println(String.format(
Locale.ROOT, "indexInverse(0b%s)=[0b%s, 0b%s]", chi, p[0], p[1]));
kindly let me know if its still not clear. I really appreciate your concern in helping me out in this problem.
Thanks a lot.
take care
-shashank