mirror of
https://github.com/NASAWorldWind/WebWorldWind.git
synced 2026-02-01 16:38:15 +00:00
Added support for TIFF tags.
This commit is contained in:
parent
0bf46471c0
commit
a3cb2b8ab0
47
examples/GeoTiff.html
Normal file
47
examples/GeoTiff.html
Normal file
@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<!--@version $Id: Shapefiles.html 3320 2015-07-15 20:53:05Z dcollins $-->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!--NOTE: Most Web World Wind examples use jquery, Bootstrap and requirejs but those technologies are NOT-->
|
||||
<!--required by Web World Wind. See SimplestExample.html for an example of using Web World Wind without them.-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
|
||||
<script data-main="GeoTiff" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.17/require.min.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="jumbotron hidden-xs">
|
||||
<h1 style="text-align:center">World Wind GeoTiff</h1>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<h4>Projection</h4>
|
||||
<div class="dropdown" id="projectionDropdown">
|
||||
</div>
|
||||
<br>
|
||||
<h4>Layers</h4>
|
||||
<div class="list-group" id="layerList">
|
||||
</div>
|
||||
<br>
|
||||
<h4>Destination</h4>
|
||||
<div class="input-group" id="searchBox">
|
||||
<input type="text" class="form-control" placeholder="GoTo" id="searchText"/>
|
||||
<span class="input-group-btn">
|
||||
<button id="searchButton" class="btn btn-primary" type="button">
|
||||
<span class="glyphicon glyphicon-search"></span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9" id="globe">
|
||||
<canvas id="canvasOne" width="1000" height="1000" style="width: 100%; height: auto">
|
||||
Your browser does not support HTML5 Canvas.
|
||||
</canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
49
examples/GeoTiff.js
Normal file
49
examples/GeoTiff.js
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2014 United States Government as represented by the Administrator of the
|
||||
* National Aeronautics and Space Administration. All Rights Reserved.
|
||||
*/
|
||||
|
||||
requirejs(['../src/WorldWind',
|
||||
'./LayerManager'],
|
||||
function (ww,
|
||||
LayerManager) {
|
||||
"use strict";
|
||||
|
||||
WorldWind.Logger.setLoggingLevel(WorldWind.Logger.LEVEL_WARNING);
|
||||
|
||||
var wwd = new WorldWind.WorldWindow("canvasOne");
|
||||
|
||||
var layers = [
|
||||
{layer: new WorldWind.BMNGLayer(), enabled: true},
|
||||
{layer: new WorldWind.CompassLayer(), enabled: true},
|
||||
{layer: new WorldWind.CoordinatesDisplayLayer(wwd), enabled: true},
|
||||
{layer: new WorldWind.ViewControlsLayer(wwd), enabled: true}
|
||||
];
|
||||
|
||||
for (var l = 0; l < layers.length; l++) {
|
||||
layers[l].layer.enabled = layers[l].enabled;
|
||||
wwd.addLayer(layers[l].layer);
|
||||
}
|
||||
|
||||
//var resourcesUrl = "./geotiff_data/world.tiff";
|
||||
//var resourcesUrl = "./geotiff_data/Namib.tiff";
|
||||
var resourcesUrl = "./geotiff_data/GeogToWGS84GeoKey5.tif";
|
||||
|
||||
|
||||
|
||||
var geotiffObject = new WorldWind.GeoTiffReader(resourcesUrl);
|
||||
var geoTiffImage = geotiffObject.readAsImage(function (image) {
|
||||
//console.log(image);
|
||||
var surfaceGeoTiff = new WorldWind.SurfaceImage(
|
||||
new WorldWind.Sector(40, 50, -120, -100),
|
||||
new WorldWind.ImageSource(image));
|
||||
|
||||
// GeoTiff test
|
||||
var geotiffLayer = new WorldWind.RenderableLayer("GeoTiff");
|
||||
geotiffLayer.addRenderable(surfaceGeoTiff);
|
||||
wwd.addLayer(geotiffLayer);
|
||||
|
||||
// Create a layer manager for controlling layer visibility.
|
||||
var layerManger = new LayerManager(wwd);
|
||||
});
|
||||
});
|
||||
BIN
examples/geotiff_data/GeogToWGS84GeoKey5.tif
Normal file
BIN
examples/geotiff_data/GeogToWGS84GeoKey5.tif
Normal file
Binary file not shown.
28
src/formats/geotiff/GeoTiff.js
Normal file
28
src/formats/geotiff/GeoTiff.js
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2014 United States Government as represented by the Administrator of the
|
||||
* National Aeronautics and Space Administration. All Rights Reserved.
|
||||
*/
|
||||
/**
|
||||
* @exports GeoTiff
|
||||
*/
|
||||
define([],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
var GeoTiff = function () {
|
||||
};
|
||||
|
||||
GeoTiff.Tag = {
|
||||
'MODEL_PIXEL_SCALE': 33550,
|
||||
'MODEL_TRANSFORMATION': 34264,
|
||||
'MODEL_TIEPOINT': 33922,
|
||||
'GEO_KEY_DIRECTORY': 34735,
|
||||
'GEO_DOUBLE_PARAMS': 34736,
|
||||
'GEO_ASCII_PARAMS': 34737
|
||||
};
|
||||
|
||||
return GeoTiff;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
463
src/formats/geotiff/GeoTiffReader.js
Normal file
463
src/formats/geotiff/GeoTiffReader.js
Normal file
@ -0,0 +1,463 @@
|
||||
/*
|
||||
* Copyright (C) 2014 United States Government as represented by the Administrator of the
|
||||
* National Aeronautics and Space Administration. All Rights Reserved.
|
||||
*/
|
||||
/**
|
||||
* @exports GeoTiffReader
|
||||
*/
|
||||
define(['../../error/AbstractError',
|
||||
'../../error/ArgumentError',
|
||||
'./GeoTiff',
|
||||
'./GeoTiffUtil',
|
||||
'../../util/Logger',
|
||||
'./Tiff',
|
||||
'./TiffIFDEntry'
|
||||
],
|
||||
function (AbstractError,
|
||||
ArgumentError,
|
||||
GeoTiff,
|
||||
GeoTiffUtil,
|
||||
Logger,
|
||||
Tiff,
|
||||
TiffIFDEntry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
var GeoTiffReader = function (url) {
|
||||
if (!url) {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "GeoTiffReader", "constructor", "missingUrl"));
|
||||
}
|
||||
|
||||
this._isLittleEndian = false;
|
||||
|
||||
this._layer = null;
|
||||
|
||||
this._url = url;
|
||||
|
||||
this._geoTiffData = null;
|
||||
|
||||
this._imageFileDirectories = [];
|
||||
|
||||
this._imageWidth = null;
|
||||
|
||||
this._imageLength = null;
|
||||
|
||||
this._bitsPerSample = null;
|
||||
|
||||
this._compression = null;
|
||||
|
||||
this._photometricInterpretation = null;
|
||||
|
||||
this._samplesPerPixel = null;
|
||||
|
||||
this._planarConfiguration = null;
|
||||
|
||||
this._artist = null;
|
||||
|
||||
this._software = null;
|
||||
|
||||
this._dateTime = null;
|
||||
|
||||
this._xResolution = null;
|
||||
|
||||
this._yResolution = null;
|
||||
|
||||
this._resolutionUnit= null;
|
||||
|
||||
this._orientation = null;
|
||||
|
||||
this._rowsPerStrip = null;
|
||||
|
||||
this._stripByteCounts = null;
|
||||
|
||||
this._stripOffsets = null;
|
||||
|
||||
this._fillOrder = null;
|
||||
|
||||
this._newSubfileType = null;
|
||||
|
||||
this._sampleFormat = null;
|
||||
|
||||
this._colorMap = null;
|
||||
|
||||
};
|
||||
|
||||
Object.defineProperties(GeoTiffReader.prototype, {
|
||||
|
||||
isLittleEndian: {
|
||||
get: function () {
|
||||
return this._isLittleEndian;
|
||||
}
|
||||
},
|
||||
|
||||
layer: {
|
||||
get: function () {
|
||||
return this._layer;
|
||||
}
|
||||
},
|
||||
|
||||
url: {
|
||||
get: function () {
|
||||
return this._url;
|
||||
}
|
||||
},
|
||||
|
||||
geoTiffData: {
|
||||
get: function () {
|
||||
return this._geoTiffData;
|
||||
}
|
||||
},
|
||||
|
||||
imageFileDirectories: {
|
||||
get: function () {
|
||||
return this._imageFileDirectories;
|
||||
}
|
||||
},
|
||||
|
||||
imageWidth: {
|
||||
get: function () {
|
||||
return this._imageWidth;
|
||||
}
|
||||
},
|
||||
|
||||
imageLength: {
|
||||
get: function () {
|
||||
return this._imageLength;
|
||||
}
|
||||
},
|
||||
|
||||
bitsPerSample: {
|
||||
get: function () {
|
||||
return this._bitsPerSample;
|
||||
}
|
||||
},
|
||||
|
||||
compression: {
|
||||
get: function () {
|
||||
return this._compression;
|
||||
}
|
||||
},
|
||||
|
||||
photometricInterpretation: {
|
||||
get: function () {
|
||||
return this._photometricInterpretation;
|
||||
}
|
||||
},
|
||||
|
||||
samplesPerPixel: {
|
||||
get: function () {
|
||||
return this._samplesPerPixel;
|
||||
}
|
||||
},
|
||||
|
||||
planarConfiguration: {
|
||||
get: function () {
|
||||
return this._planarConfiguration;
|
||||
}
|
||||
},
|
||||
|
||||
artist: {
|
||||
get: function () {
|
||||
return this._artist;
|
||||
}
|
||||
},
|
||||
|
||||
software: {
|
||||
get: function () {
|
||||
return this._software;
|
||||
}
|
||||
},
|
||||
|
||||
dateTime: {
|
||||
get: function () {
|
||||
return this._dateTime;
|
||||
}
|
||||
},
|
||||
|
||||
xResolution: {
|
||||
get: function () {
|
||||
return this._xResolution;
|
||||
}
|
||||
},
|
||||
|
||||
yResolution: {
|
||||
get: function () {
|
||||
return this._yResolution;
|
||||
}
|
||||
},
|
||||
|
||||
resolutionUnit: {
|
||||
get: function () {
|
||||
return this._resolutionUnit;
|
||||
}
|
||||
},
|
||||
|
||||
orientation: {
|
||||
get: function () {
|
||||
return this._orientation;
|
||||
}
|
||||
},
|
||||
|
||||
rowsPerStrip: {
|
||||
get: function () {
|
||||
return this._rowsPerStrip;
|
||||
}
|
||||
},
|
||||
|
||||
stripByteCounts: {
|
||||
get: function () {
|
||||
return this._stripByteCounts;
|
||||
}
|
||||
},
|
||||
|
||||
stripOffsets: {
|
||||
get: function () {
|
||||
return this._stripOffsets;
|
||||
}
|
||||
},
|
||||
|
||||
fillOrder: {
|
||||
get: function () {
|
||||
return this._fillOrder;
|
||||
}
|
||||
},
|
||||
|
||||
newSubfileType: {
|
||||
get: function () {
|
||||
return this._newSubfileType;
|
||||
}
|
||||
},
|
||||
|
||||
sampleFormat: {
|
||||
get: function () {
|
||||
return this._sampleFormat;
|
||||
}
|
||||
},
|
||||
|
||||
colorMap: {
|
||||
get: function () {
|
||||
return this._colorMap;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
GeoTiffReader.prototype.readAsImage = function (callback) {
|
||||
this.requestUrl(this.url, (function(){
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = this.imageWidth[0];
|
||||
canvas.height = this.imageLength[0];
|
||||
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.rect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle="red";
|
||||
ctx.fill();
|
||||
|
||||
callback(GeoTiffUtil.canvasToTiffImage(canvas));
|
||||
}).bind(this));
|
||||
};
|
||||
|
||||
GeoTiffReader.prototype.readAsData = function () {
|
||||
this.requestUrl(this.url);
|
||||
};
|
||||
|
||||
//GeoTiffReader.prototype.load = function (layer) {
|
||||
// this._layer = layer || new RenderableLayer();
|
||||
// this.requestUrl(this.url);
|
||||
//};
|
||||
|
||||
GeoTiffReader.prototype.requestUrl = function (url, callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open("GET", url, true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onreadystatechange = (function () {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
var arrayBuffer = xhr.response;
|
||||
if(arrayBuffer){
|
||||
this.parse(arrayBuffer);
|
||||
callback();
|
||||
}
|
||||
}
|
||||
else {
|
||||
Logger.log(Logger.LEVEL_WARNING,
|
||||
"GeoTiff retrieval failed (" + xhr.statusText + "): " + url);
|
||||
}
|
||||
}
|
||||
}).bind(this);
|
||||
|
||||
xhr.onerror = function () {
|
||||
Logger.log(Logger.LEVEL_WARNING, "GeoTiff retrieval failed: " + url);
|
||||
};
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
Logger.log(Logger.LEVEL_WARNING, "GeoTiff retrieval timed out: " + url);
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
};
|
||||
|
||||
GeoTiffReader.prototype.parse = function (arrayBuffer) {
|
||||
this._geoTiffData = new DataView(arrayBuffer);
|
||||
this.setEndianness();
|
||||
//console.log("Is little endian:" + this.isLittleEndian);
|
||||
|
||||
if (!this.isTiffFileType()){
|
||||
throw new AbstractError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "GeoTiffReader", "parse", "invalidTiffFileType"));
|
||||
}
|
||||
|
||||
var firstIFDOffset = GeoTiffUtil.getBytes(this.geoTiffData, 4, 4, this.isLittleEndian);
|
||||
//console.log("First IFD offset: " + firstIFDOffset);
|
||||
|
||||
this.parseImageFileDirectory(firstIFDOffset);
|
||||
|
||||
console.log("*****")
|
||||
console.log("Is GeoTiff: " + this.isGeoTiff());
|
||||
|
||||
|
||||
this._imageWidth = this.getIFDByTag(Tiff.Tag.IMAGE_WIDTH).getIFDEntryValue(this.isLittleEndian);
|
||||
this._imageLength = this.getIFDByTag(Tiff.Tag.IMAGE_LENGTH).getIFDEntryValue(this.isLittleEndian);
|
||||
this._bitsPerSample = this.getIFDByTag(Tiff.Tag.BITS_PER_SAMPLE).getIFDEntryValue(this.isLittleEndian);
|
||||
this._compression = this.getIFDByTag(Tiff.Tag.COMPRESSION).getIFDEntryValue(this.isLittleEndian);
|
||||
this._photometricInterpretation = this.getIFDByTag(Tiff.Tag.PHOTOMETRIC_INTERPRETATION).getIFDEntryValue(this.isLittleEndian);
|
||||
this._samplesPerPixel = this.getIFDByTag(Tiff.Tag.SAMPLES_PER_PIXEL).getIFDEntryValue(this.isLittleEndian);
|
||||
this._planarConfiguration = this.getIFDByTag(Tiff.Tag.PLANAR_CONFIGURATION).getIFDEntryValue(this.isLittleEndian);
|
||||
this._artist = this.getIFDByTag(Tiff.Tag.ARTIST).getIFDEntryValue(this.isLittleEndian);
|
||||
this._software = this.getIFDByTag(Tiff.Tag.SOFTWARE).getIFDEntryValue(this.isLittleEndian);
|
||||
this._dateTime = this.getIFDByTag(Tiff.Tag.DATE_TIME).getIFDEntryValue(this.isLittleEndian);
|
||||
this._xResolution = this.getIFDByTag(Tiff.Tag.X_RESOLUTION).getIFDEntryValue(this.isLittleEndian);
|
||||
this._yResolution = this.getIFDByTag(Tiff.Tag.Y_RESOLUTION).getIFDEntryValue(this.isLittleEndian);
|
||||
this._resolutionUnit = this.getIFDByTag(Tiff.Tag.RESOLUTION_UNIT).getIFDEntryValue(this.isLittleEndian);
|
||||
this._orientation = this.getIFDByTag(Tiff.Tag.ORIENTATION).getIFDEntryValue(this.isLittleEndian);
|
||||
this._rowsPerStrip = this.getIFDByTag(Tiff.Tag.ROWS_PER_STRIP).getIFDEntryValue(this.isLittleEndian);
|
||||
this._stripByteCounts = this.getIFDByTag(Tiff.Tag.STRIP_BYTE_COUNTS).getIFDEntryValue(this.isLittleEndian);
|
||||
this._stripOffsets = this.getIFDByTag(Tiff.Tag.STRIP_OFFSETS).getIFDEntryValue(this.isLittleEndian);
|
||||
this._fillOrder = this.getIFDByTag(Tiff.Tag.FILL_ORDER).getIFDEntryValue(this.isLittleEndian);
|
||||
this._newSubfileType = this.getIFDByTag(Tiff.Tag.NEW_SUBFILE_TYPE).getIFDEntryValue(this.isLittleEndian);
|
||||
|
||||
if (this.getIFDByTag(Tiff.Tag.SAMPLE_FORMAT)){
|
||||
this._sampleFormat = this.getIFDByTag(Tiff.Tag.SAMPLE_FORMAT).getIFDEntryValue(this.isLittleEndian);
|
||||
}
|
||||
else{
|
||||
this._sampleFormat = Tiff.SampleFormat.DEFAULT;
|
||||
}
|
||||
|
||||
this._colorMap = this.getIFDByTag(Tiff.Tag.COLOR_MAP).getIFDEntryValue(this.isLittleEndian);
|
||||
|
||||
console.log("Image width: " + this.imageWidth);
|
||||
console.log("Image length: " + this.imageLength);
|
||||
console.log("Bits per sample: " + this.bitsPerSample);
|
||||
console.log("Compression: " + Tiff.getTagValueAsString(Tiff.Compression, this.compression[0]));
|
||||
console.log("Photometric interpretation: " + Tiff.getTagValueAsString(Tiff.PhotometricInterpretation, this.photometricInterpretation[0]));
|
||||
console.log("Samples per pixel: " + this.samplesPerPixel);
|
||||
console.log("Planar configuration: " + Tiff.getTagValueAsString(Tiff.PlanarConfiguration, this.planarConfiguration[0]));
|
||||
console.log("Artist: " + this.artist);
|
||||
console.log("Software: " + this.software);
|
||||
console.log("Date time: " + this.dateTime);
|
||||
console.log("X resolution: " + this.xResolution);
|
||||
console.log("Y resolution: " + this.yResolution);
|
||||
console.log("Resolution unit: " + Tiff.getTagValueAsString(Tiff.ResolutionUnit, this.resolutionUnit[0]));
|
||||
console.log("Orientation: " + Tiff.getTagValueAsString(Tiff.Orientation, this.orientation[0]));
|
||||
console.log("Rows per strip: " + this.rowsPerStrip);
|
||||
console.log("Strip byte counts:");
|
||||
console.log(this.stripByteCounts);
|
||||
console.log("Strip offsets:");
|
||||
console.log(this.stripOffsets);
|
||||
console.log("Fill order: " + this.fillOrder);
|
||||
console.log("New subfile type: " + this.newSubfileType);
|
||||
console.log("Sample format: " + this.sampleFormat);
|
||||
console.log("Color map:");
|
||||
console.log(this.colorMap);
|
||||
};
|
||||
|
||||
GeoTiffReader.prototype.setEndianness = function () {
|
||||
var byteOrderValue = GeoTiffUtil.getBytes(this.geoTiffData, 0, 2, this.isLittleEndian);
|
||||
if (byteOrderValue === 0x4949){
|
||||
this._isLittleEndian = true;
|
||||
}
|
||||
else if (byteOrderValue === 0x4D4D){
|
||||
this._isLittleEndian = false;
|
||||
}
|
||||
else{
|
||||
throw new AbstractError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "GeoTiffReader", "setEndianness", "invalidByteOrderValue"));
|
||||
}
|
||||
};
|
||||
|
||||
GeoTiffReader.prototype.isTiffFileType = function () {
|
||||
var fileTypeValue = GeoTiffUtil.getBytes(this.geoTiffData, 2, 2, this.isLittleEndian);
|
||||
if (fileTypeValue === 42){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
GeoTiffReader.prototype.isGeoTiff = function () {
|
||||
if(this.getIFDByTag(GeoTiff.Tag.GEO_KEY_DIRECTORY)){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
GeoTiffReader.prototype.parseImageFileDirectory = function (offset) {
|
||||
if (!offset) {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "GeoTiffReader", "parseImageFileDirectory", "missingOffset"));
|
||||
}
|
||||
|
||||
var noOfDirectoryEntries = GeoTiffUtil.getBytes(this.geoTiffData, offset, 2, this.isLittleEndian);
|
||||
//console.log("No of directory entries: " + noOfDirectoryEntries);
|
||||
|
||||
var directoryEntries = [];
|
||||
|
||||
for (var i = offset + 2, directoryEntryCounter = 0; directoryEntryCounter < noOfDirectoryEntries; i += 12, directoryEntryCounter++){
|
||||
var tag = GeoTiffUtil.getBytes(this.geoTiffData, i, 2, this.isLittleEndian);
|
||||
var type = GeoTiffUtil.getBytes(this.geoTiffData, i + 2, 2, this.isLittleEndian);
|
||||
var count = GeoTiffUtil.getBytes(this.geoTiffData, i + 4, 4, this.isLittleEndian);
|
||||
var valueOffset = GeoTiffUtil.getBytes(this.geoTiffData, i + 8, 4, this.isLittleEndian);
|
||||
|
||||
//console.log("Tag: " + Tiff.getTagString(tag));
|
||||
//console.log("Type: " + type);
|
||||
//console.log("Count: " + count);
|
||||
//console.log("Value Offset:" + valueOffset);
|
||||
|
||||
directoryEntries.push(new TiffIFDEntry(tag, type, count, valueOffset, this.geoTiffData, this.isLittleEndian));
|
||||
}
|
||||
|
||||
this._imageFileDirectories.push(directoryEntries);
|
||||
|
||||
var nextIFDOffset = GeoTiffUtil.getBytes(this.geoTiffData, i, 4, this.isLittleEndian);
|
||||
|
||||
if (nextIFDOffset === 0){
|
||||
return;
|
||||
}
|
||||
else{
|
||||
this.parseImageFileDirectory(nextIFDOffset);
|
||||
}
|
||||
};
|
||||
|
||||
GeoTiffReader.prototype.getIFDByTag = function(tag){
|
||||
if (!tag) {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "GeoTiffReader", "getIFDByTag", "missingTag"));
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.imageFileDirectories[0].length; i++){
|
||||
if (this.imageFileDirectories[0][i].tag === tag){
|
||||
return this.imageFileDirectories[0][i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return GeoTiffReader;
|
||||
}
|
||||
);
|
||||
48
src/formats/geotiff/GeoTiffUtil.js
Normal file
48
src/formats/geotiff/GeoTiffUtil.js
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2014 United States Government as represented by the Administrator of the
|
||||
* National Aeronautics and Space Administration. All Rights Reserved.
|
||||
*/
|
||||
/**
|
||||
* @exports GeoTiffUtil
|
||||
*/
|
||||
define(['../../error/ArgumentError'
|
||||
],
|
||||
function (ArgumentError) {
|
||||
"use strict";
|
||||
|
||||
var GeoTiffUtil = {
|
||||
|
||||
getBytes: function (geoTiffData, byteOffset, numOfBytes, isLittleEndian) {
|
||||
if (numOfBytes <= 0) {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "GeoTiffReader", "getBytes", "noBytesRequested"));
|
||||
} else if (numOfBytes <= 1) {
|
||||
return geoTiffData.getUint8(byteOffset, isLittleEndian);
|
||||
} else if (numOfBytes <= 2) {
|
||||
return geoTiffData.getUint16(byteOffset, isLittleEndian);
|
||||
} else if (numOfBytes <= 3) {
|
||||
return geoTiffData.getUint32(byteOffset, isLittleEndian) >>> 8;
|
||||
} else if (numOfBytes <= 4) {
|
||||
return geoTiffData.getUint32(byteOffset, isLittleEndian);
|
||||
} else if (numOfBytes <= 8) {
|
||||
return geoTiffData.getFloat64(byteOffset, isLittleEndian);
|
||||
} else {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "GeoTiffReader", "getBytes", "tooManyBytesRequested"));
|
||||
}
|
||||
},
|
||||
|
||||
// Converts canvas to an image
|
||||
canvasToTiffImage: function (canvas) {
|
||||
var image = new Image();
|
||||
image.src = canvas.toDataURL();
|
||||
|
||||
return image;
|
||||
}
|
||||
};
|
||||
|
||||
return GeoTiffUtil;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
179
src/formats/geotiff/Tiff.js
Normal file
179
src/formats/geotiff/Tiff.js
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2014 United States Government as represented by the Administrator of the
|
||||
* National Aeronautics and Space Administration. All Rights Reserved.
|
||||
*/
|
||||
/**
|
||||
* @exports Tiff
|
||||
*/
|
||||
define([],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
var Tiff = {
|
||||
Type: {
|
||||
'BYTE': 1,
|
||||
'ASCII': 2,
|
||||
'SHORT': 3,
|
||||
'LONG': 4,
|
||||
'RATIONAL': 5,
|
||||
'SBYTE': 6,
|
||||
'UNDEFINED': 7,
|
||||
'SSHORT': 8,
|
||||
'SLONG': 9,
|
||||
'SRATIONAL': 10,
|
||||
'FLOAT': 11,
|
||||
'DOUBLE': 12
|
||||
},
|
||||
|
||||
Tag: {
|
||||
'NEW_SUBFILE_TYPE': 254,
|
||||
'SUBFILE_TYPE': 255,
|
||||
'IMAGE_WIDTH': 256,
|
||||
'IMAGE_LENGTH': 257,
|
||||
'BITS_PER_SAMPLE': 258,
|
||||
'COMPRESSION': 259,
|
||||
'PHOTOMETRIC_INTERPRETATION': 262,
|
||||
'THRESHHOLDING': 263,
|
||||
'CELL_WIDTH': 264,
|
||||
'CELL_LENGTH': 265,
|
||||
'FILL_ORDER': 266,
|
||||
'DOCUMENT_NAME': 269,
|
||||
'IMAGE_DESCRIPTION': 270,
|
||||
'MAKE': 271,
|
||||
'MODEL': 272,
|
||||
'STRIP_OFFSETS': 273,
|
||||
'ORIENTATION': 274,
|
||||
'SAMPLES_PER_PIXEL': 277,
|
||||
'ROWS_PER_STRIP': 278,
|
||||
'STRIP_BYTE_COUNTS': 279,
|
||||
'MIN_SAMPLE_VALUE': 280,
|
||||
'MAX_SAMPLE_VALUE': 281,
|
||||
'X_RESOLUTION': 282,
|
||||
'Y_RESOLUTION': 283,
|
||||
'PLANAR_CONFIGURATION': 284,
|
||||
'PAGE_NAME': 285,
|
||||
'X_POSITION': 286,
|
||||
'Y_POSITION': 287,
|
||||
'FREE_OFFSETS': 288,
|
||||
'FREE_BYTE_COUNTS': 289,
|
||||
'GRAY_RESPONSE_UNIT': 290,
|
||||
'GRAY_RESPONSE_CURVE': 291,
|
||||
'T4_OPTIONS': 292,
|
||||
'T6_PTIONS': 293,
|
||||
'RESOLUTION_UNIT': 296,
|
||||
'PAGE_NUMBER': 297,
|
||||
'TRANSFER_FUNCTION': 301,
|
||||
'SOFTWARE': 305,
|
||||
'DATE_TIME': 306,
|
||||
'ARTIST': 315,
|
||||
'HOST_COMPUTER': 316,
|
||||
'PREDICTOR': 317,
|
||||
'WHITE_POINT': 318,
|
||||
'PRIMARY_CHROMATICITIES': 319,
|
||||
'COLOR_MAP': 320,
|
||||
'HALFTONE_HINTS': 321,
|
||||
'TILE_WIDTH': 322,
|
||||
'TILE_LENGTH': 323,
|
||||
'TILE_OFFSETS': 324,
|
||||
'TILE_BYTE_COUNTS': 325,
|
||||
'INK_SET': 332,
|
||||
'INK_NAMES': 333,
|
||||
'NUMBER_OF_INKS': 334,
|
||||
'DOT_RANGE': 336,
|
||||
'TARGET_PRINTER': 337,
|
||||
'EXTRA_SAMPLES': 338,
|
||||
'SAMPLE_FORMAT': 339,
|
||||
'S_MIN_SAMPLE_VALUE': 340,
|
||||
'S_MAX_SAMPLE_VALUE': 341,
|
||||
'TRANSFER_RANGE': 342,
|
||||
'JPEG_PROC': 512,
|
||||
'JPEG_INTERCHANGE_FORMAT': 513,
|
||||
'JPEG_INTERCHANGE_FORMAT_LENGTH': 514,
|
||||
'JPEG_RESTART_INTERVAL': 515,
|
||||
'JPEG_LOSSLESS_PREDICTORS': 517,
|
||||
'JPEG_POINT_TRANSFORMS': 518,
|
||||
'JPEG_Q_TABLES': 519,
|
||||
'JPEG_DC_TABLES': 520,
|
||||
'JPEG_AC_TABLES': 521,
|
||||
'Y_Cb_Cr_COEFFICIENTS': 529,
|
||||
'Y_Cb_Cr_SUB_SAMPLING': 530,
|
||||
'Y_Cb_Cr_POSITIONING': 531,
|
||||
'REFERENCE_BLACK_WHITE': 532,
|
||||
'COPYRIGHT': 33432
|
||||
},
|
||||
|
||||
Orientation: {
|
||||
'Row0_IS_TOP__Col0_IS_LHS': 1,
|
||||
'Row0_IS_TOP__Col0_IS_RHS': 2,
|
||||
'Row0_IS_BOTTOM__Col0_IS_RHS': 3,
|
||||
'Row0_IS_BOTTOM__Col0_IS_LHS': 4,
|
||||
'Row0_IS_LHS__Col0_IS_TOP': 5,
|
||||
'Row0_IS_RHS__Col0_IS_TOP': 6,
|
||||
'Row0_IS_RHS__Col0_IS_BOTTOM': 7,
|
||||
'Row0_IS_LHS__Col0_IS_BOTTOM': 8
|
||||
},
|
||||
|
||||
Compression: {
|
||||
'UNCOMPRESSED': 1,
|
||||
'CCITT_1D': 2,
|
||||
'GROUP_3_FAX': 3,
|
||||
'GROUP_4_FAX': 4,
|
||||
'LZW': 5,
|
||||
'JPEG': 6,
|
||||
'PACK_BITS': 32773
|
||||
},
|
||||
|
||||
PhotometricInterpretation: {
|
||||
'WHITE_IS_ZERO': 0,
|
||||
'BLACK_IS_ZERO': 1,
|
||||
'RGB': 2,
|
||||
'RGB_PALETTE': 3,
|
||||
'TRANSPARENCY_MASK': 4,
|
||||
'CMYK': 5,
|
||||
'Y_Cb_Cr': 6,
|
||||
'CIE_LAB': 7
|
||||
},
|
||||
|
||||
SampleFormat: {
|
||||
'UNSIGNED': 1,
|
||||
'SIGNED': 2,
|
||||
'IEEE_FLOAT': 3,
|
||||
'UNDEFINED': 4,
|
||||
'DEFAULT': 1
|
||||
},
|
||||
|
||||
ResolutionUnit: {
|
||||
'NONE': 1,
|
||||
'INCH': 2,
|
||||
'CENTIMETER': 3
|
||||
},
|
||||
|
||||
PlanarConfiguration: {
|
||||
'CHUNKY': 1,
|
||||
'PLANAR': 2
|
||||
},
|
||||
|
||||
getTagValueAsString: function (tagName, tagValue) {
|
||||
for (var property in tagName) {
|
||||
if (tagName[property] === tagValue) {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getTagString: function (tagValue) {
|
||||
for (var tagEntry in this.Tag) {
|
||||
if (this.Tag[tagEntry] === tagValue) {
|
||||
return tagEntry;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
return Tiff;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
176
src/formats/geotiff/TiffIFDEntry.js
Normal file
176
src/formats/geotiff/TiffIFDEntry.js
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2014 United States Government as represented by the Administrator of the
|
||||
* National Aeronautics and Space Administration. All Rights Reserved.
|
||||
*/
|
||||
/**
|
||||
* @exports TiffIFDEntry
|
||||
*/
|
||||
define(['../../error/AbstractError',
|
||||
'../../error/ArgumentError',
|
||||
'./GeoTiffUtil',
|
||||
'../../util/Logger',
|
||||
'./Tiff'
|
||||
],
|
||||
function (AbstractError,
|
||||
ArgumentError,
|
||||
GeoTiffUtil,
|
||||
Logger,
|
||||
Tiff) {
|
||||
"use strict";
|
||||
|
||||
var TiffIFDEntry = function (tag, type, count, valueOffset, geoTiffData, isLittleEndian) {
|
||||
if (!tag) {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "TiffIFDEntry", "constructor", "missingTag"));
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "TiffIFDEntry", "constructor", "missingType"));
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "TiffIFDEntry", "constructor", "missingCount"));
|
||||
}
|
||||
|
||||
//if (!valueOffset) {
|
||||
// throw new ArgumentError(
|
||||
// Logger.logMessage(Logger.LEVEL_SEVERE, "TiffIFDEntry", "constructor", "missingValueOffset"));
|
||||
//}
|
||||
|
||||
if (!geoTiffData) {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "TiffIFDEntry", "constructor", "missingGeoTiffData"));
|
||||
}
|
||||
|
||||
if (!isLittleEndian) {
|
||||
throw new ArgumentError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "TiffIFDEntry", "constructor", "missingIsLittleEndian"));
|
||||
}
|
||||
|
||||
this._tag = tag;
|
||||
|
||||
this._type = type;
|
||||
|
||||
this._count = count;
|
||||
|
||||
this._valueOffset = valueOffset;
|
||||
|
||||
this._geoTiffData = geoTiffData;
|
||||
|
||||
this._isLittleEndian = isLittleEndian;
|
||||
};
|
||||
|
||||
Object.defineProperties(TiffIFDEntry.prototype, {
|
||||
|
||||
tag: {
|
||||
get: function () {
|
||||
return this._tag;
|
||||
}
|
||||
},
|
||||
|
||||
type: {
|
||||
get: function () {
|
||||
return this._type;
|
||||
}
|
||||
},
|
||||
|
||||
count: {
|
||||
get: function () {
|
||||
return this._count;
|
||||
}
|
||||
},
|
||||
|
||||
valueOffset: {
|
||||
get: function () {
|
||||
return this._valueOffset;
|
||||
}
|
||||
},
|
||||
|
||||
geoTiffData: {
|
||||
get: function () {
|
||||
return this._geoTiffData;
|
||||
}
|
||||
},
|
||||
|
||||
isLittleEndian: {
|
||||
get: function () {
|
||||
return this._isLittleEndian;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
TiffIFDEntry.prototype.getIFDTypeLength = function (fieldTypeName) {
|
||||
switch(this.type){
|
||||
case Tiff.Type.BYTE:
|
||||
case Tiff.Type.ASCII:
|
||||
case Tiff.Type.SBYTE:
|
||||
case Tiff.Type.UNDEFINED:
|
||||
return 1;
|
||||
case Tiff.Type.SHORT:
|
||||
case Tiff.Type.SSHORT:
|
||||
return 2;
|
||||
case Tiff.Type.LONG:
|
||||
case Tiff.Type.SLONG:
|
||||
case Tiff.Type.FLOAT:
|
||||
return 4;
|
||||
case Tiff.Type.RATIONAL:
|
||||
case Tiff.Type.SRATIONAL:
|
||||
case Tiff.Type.DOUBLE:
|
||||
return 8;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
TiffIFDEntry.prototype.getIFDEntryValue = function (isLittleEndian) {
|
||||
var ifdValues = [];
|
||||
var value = null;
|
||||
var ifdTypeLength = this.getIFDTypeLength(this.type);
|
||||
var ifdValueSize = ifdTypeLength * this.count;
|
||||
|
||||
if (ifdValueSize <= 4) {
|
||||
if (isLittleEndian === false) {
|
||||
value = this.valueOffset >>> ((4 - ifdTypeLength) * 8);
|
||||
} else {
|
||||
value = this.valueOffset;
|
||||
}
|
||||
ifdValues.push(value);
|
||||
} else {
|
||||
for (var i = 0; i < this.count; i++) {
|
||||
var indexOffset = ifdTypeLength * i;
|
||||
|
||||
if (ifdTypeLength >= 8) {
|
||||
if (this.type === Tiff.Type.RATIONAL || this.type === Tiff.Type.SRATIONAL) {
|
||||
// Numerator
|
||||
ifdValues.push(GeoTiffUtil.getBytes(this.geoTiffData, this.valueOffset + indexOffset, 4, this.isLittleEndian));
|
||||
// Denominator
|
||||
ifdValues.push(GeoTiffUtil.getBytes(this.geoTiffData, this.valueOffset + indexOffset + 4, 4, this.isLittleEndian));
|
||||
} else if (this.type === Tiff.Type.DOUBLE) {
|
||||
ifdValues.push(GeoTiffUtil.getBytes(this.geoTiffData, this.valueOffset + indexOffset, 8, this.isLittleEndian));
|
||||
} else {
|
||||
throw new AbstractError(
|
||||
Logger.logMessage(Logger.LEVEL_SEVERE, "TiffIFDEntry", "parse", "invalidTypeOfIFD"));
|
||||
}
|
||||
} else {
|
||||
ifdValues.push(GeoTiffUtil.getBytes(this.geoTiffData, this.valueOffset + indexOffset, ifdTypeLength, this.isLittleEndian));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.type === Tiff.Type.ASCII) {
|
||||
ifdValues.forEach(function (element, index, array) {
|
||||
array[index] = String.fromCharCode(element);
|
||||
});
|
||||
|
||||
return ifdValues.join("");
|
||||
}
|
||||
|
||||
return ifdValues;
|
||||
|
||||
};
|
||||
|
||||
return TiffIFDEntry;
|
||||
}
|
||||
);
|
||||
Loading…
x
Reference in New Issue
Block a user