Skip to content

Commit

Permalink
implementing tiler interface
Browse files Browse the repository at this point in the history
  • Loading branch information
SignpostMarv committed Jul 13, 2015
1 parent ab0a15d commit d51e1ad
Show file tree
Hide file tree
Showing 4 changed files with 465 additions and 137 deletions.
256 changes: 119 additions & 137 deletions Utilities/FetchTileFromRawHeightmap.js
@@ -1,9 +1,14 @@
import applyDefaultPropsSpecToObject from './applyDefaultPropsSpecToObject.js';
import FetchTileFromUtils from './FetchTileFromUtils.js';
import GetTile from './GetTile.js';

export default (function(){
'use strict';
var
props = Symbol('props'),
fetchMethod = Symbol('fetchMethod'),
hasFetch = typeof(fetch) === 'function'
hasFetch = typeof(fetch) === 'function',
cachedHeightmaps = {}
;

function endianness(){
Expand All @@ -20,51 +25,92 @@ export default (function(){
throw new Error('unknown endianness');
}

class FetchTileFromRawHeightmap{
constructor(source, type, sourceEndianness){
class FetchTileFromRawHeightmap extends FetchTileFromUtils{
constructor(expectedWidth, expectedHeight, source, type, sourceEndianness){
if(
typeof(expectedWidth) !== 'number' ||
typeof(expectedHeight) !== 'number' ||
isNaN(expectedWidth) ||
isNaN(expectedHeight) ||
!isFinite(expectedWidth) ||
!isFinite(expectedHeight)
){
throw new Error('Expected dimensions must passed as numbers!');
}
expectedHeight = expectedHeight|0;
expectedWidth = expectedWidth|0;
super();
sourceEndianness = sourceEndianness || endianness();
this[props].sourceProp = source;
this[props].typeProp = type;
this[props].TypedArrayProp = null;
this[props].maxValProp = null;
this[props].minValProp = null;
this[props].rangeValProp = null;
this[props].endiannessProp = sourceEndianness;
applyDefaultPropsSpecToObject(this, props, {
width: expectedWidth,
height: expectedHeight,
sourceProp: source,
typeProp: function(){
return type;
},
TypedArrayProp: null,
endiannessProp: sourceEndianness,
pendingArrayBuffer: null,
pendingTypedArray: null,
pendingFetch: null,
});
}

get width(){
return this[props].width;
}

get height(){
return this[props].height;
}

ArrayBuffer(){
var
self = this
;
return new Promise(function(resolve, reject){
if(!self[props].pendingArrayBuffer){
self[props].pendingArrayBuffer = new Promise(function(resolve, reject){
self[fetchMethod]().then(function(response){
response.arrayBuffer().then(function(buffer){
response.clone().arrayBuffer().then(function(buffer){
if(
(Math.sqrt(
buffer.byteLength / self[props].typeProp.BYTES_PER_ELEMENT
) % 1) !== 0
buffer.byteLength !== (
(self.width * self.height) *
self[props].typeProp.BYTES_PER_ELEMENT
)
){
throw new Error(
'array buffer does not match expected resolution!'
);
reject(new Error(
'array buffer does not match expected resolution!' +
' expecting: ' + buffer.byteLength + ', received ' +
(
(self.width * self.height) *
self[props].typeProp.BYTES_PER_ELEMENT
)
));
return;
}
resolve(buffer);
}, reject);
}, reject);
});
}
return self[props].pendingArrayBuffer;
}

TypedArray(){
var
self = this
;
return new Promise(function(resolve, reject){
if(!self[props].pendingTypedArray){
self[props].pendingTypedArray = new Promise(function(resolve, reject){
if(self[props].TypedArrayProp){
resolve(self[props].TypedArrayProp);
}else{
self.ArrayBuffer().then(function(buffer){
if(self[props].endiannessProp !== endianness()){
console.warn('endianness does not match', self[props].endiannessProp);
console.warn(
'endianness does not match',
self[props].endiannessProp
);
var
u8a = new Uint8Array(buffer),
u8b = new Uint8Array(u8a.length),
Expand All @@ -77,117 +123,19 @@ export default (function(){
u8b[i + (bpel - 1 - j)] = u8a[i + j];
}
}
resolve(new self[props].typeProp(u8b.buffer));
self[props].TypedArrayProp =
new self[props].typeProp(u8b.buffer)
;
}else{
console.log('endianness matches');
resolve(new self[props].typeProp(buffer));
self[props].TypedArrayProp = new self[props].typeProp(buffer);
}
resolve(self[props].TypedArrayProp);
}, reject);
}
});
}

maxVal(){
var
self = this
;

return new Promise(function(resolve, reject){
if(self[props].maxValProp !== null){
resolve(self[props].maxValProp);
}else{
self.TypedArray().then(function(typedArray){
var
max = -Infinity
;
for(var val of typedArray){
max = Math.max(max, val);
}
self[props].maxValProp = max;
resolve(max);
}, reject);
}
});
}

minVal(){
var
self = this
;

return new Promise(function(resolve, reject){
if(self[props].minValProp !== null){
resolve(self[props].minValProp);
}else{
self.TypedArray().then(function(typedArray){
var
min = Infinity
;
for(var val of typedArray){
min = Math.min(min, val);
}
self[props].minValProp = min;
resolve(min);
}, reject);
}
});
}

rangeVal(){
var
self = this
;

return new Promise(function(resolve, reject){
if(self[props].rangeValProp !== null){
resolve(self[props].rangeValProp);
}else{
self.minVal().then(function(minVal){
self.maxVal().then(function(maxVal){
self[props].rangeValProp = maxVal - minVal;
resolve(self[props].rangeValProp);
}, reject);
}, reject);
}
});
}

Canvas(){
var
self = this
;
return new Promise(function(resolve, reject){
self.TypedArray().then(function(arr){
self.rangeVal().then(function(range){
self.minVal().then(function(minVal){
var
dim = Math.sqrt(arr.length),
canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
i = 0|0,
x = 0|0,
y = 0|0,
grey = 0|0,
imageData
;
canvas.width = dim;
canvas.height = dim;
imageData = ctx.getImageData(0, 0, dim, dim);
for(i=0;i<imageData.data.length;i+=4){
y = Math.floor(i / dim);
x = i - (y * dim);
grey = Math.round(((arr[i / 4] - minVal) / range) * 0xff);
imageData.data[i + 0] = grey;
imageData.data[i + 1] = grey;
imageData.data[i + 2] = grey;
imageData.data[i + 3] = 0xff;
}
ctx.putImageData(imageData, 0, 0);
resolve(canvas);
});
}, reject);
}, reject);
});
}
return self[props].pendingTypedArray;
}

Heights(resolution){
Expand Down Expand Up @@ -229,23 +177,57 @@ export default (function(){
}, reject);
});
}
}

FetchTileFromRawHeightmap.prototype[props] = {};
GetTile(sx, sz, sw, sh){
return GetTile.call(this, sx, sz, sw, sh);
}

static Get(expectedWidth, expectedHeight, source, type, sourceEndianness){
var
cacheKey = JSON.stringify([
expectedWidth,
expectedHeight,
source,
type,
sourceEndianness
])
;
if(!(cacheKey in cachedHeightmaps)){
cachedHeightmaps[cacheKey] = new FetchTileFromRawHeightmap(
expectedWidth,
expectedHeight,
source,
type,
sourceEndianness
);
}else{
console.log('reusing heightmap obj');
}
return cachedHeightmaps[cacheKey];
}
}

FetchTileFromRawHeightmap.prototype[fetchMethod] = function(){
var
self = this
self = this,
url = self[props].sourceProp
;
return new Promise(function(resolve, reject){
if(!hasFetch){
reject('fetch api not available!');
}else{
fetch(self[props].sourceProp).then(function(response){
resolve(response.clone());
}, reject);
}
});
if(!self[props].pendingFetch){
self[props].pendingFetch = new Promise(function(resolve, reject){
if(!hasFetch){
reject('fetch api not available!');
return;
}
fetch(url).then(function(response){
console.log('fresh fetch', url);
resolve(response);
}, function(failure){
self[props].pendingFetch = null;
reject(failure);
});
});
}
return self[props].pendingFetch;
};

return FetchTileFromRawHeightmap;
Expand Down

0 comments on commit d51e1ad

Please sign in to comment.