terriajs
Version:
Geospatial data visualization platform.
237 lines (206 loc) • 8.25 kB
JavaScript
'use strict';
/*global require*/
var defined = require('terriajs-cesium/Source/Core/defined');
var defineProperties = require('terriajs-cesium/Source/Core/defineProperties');
var knockout = require('terriajs-cesium/Source/ThirdParty/knockout');
var loadWithXhr = require('../Core/loadWithXhr');
var Uri = require('terriajs-cesium/Source/ThirdParty/Uri');
var when = require('terriajs-cesium/Source/ThirdParty/when');
var CatalogItem = require('./CatalogItem');
var GeoJsonCatalogItem = require('./GeoJsonCatalogItem');
var inherit = require('../Core/inherit');
var Metadata = require('./Metadata');
var TerriaError = require('../Core/TerriaError');
/**
* A {@link CatalogItem} representing ogr2ogr supported data formats.
*
* @alias OgrCatalogItem
* @constructor
* @extends GeoJsonCatalogItem
*
* @param {Terria} terria The Terria instance.
* @param {String} [url] The URL from which to retrieve the OGR data.
*/
var OgrCatalogItem = function(terria, url) {
CatalogItem.call(this, terria);
this._geoJsonItem = undefined;
this.url = url;
/**
* Gets or sets the Ogr data, represented as a binary Blob, DOM Document, or a Promise for one of those things.
* If this property is set, {@link CatalogItem#url} is ignored.
* This property is observable.
* @type {Blob|Document|Promise}
*/
this.data = undefined;
/**
* Gets or sets the URL from which the {@link OgrCatalogItem#data} was obtained. This may be used
* to resolve any resources linked in the Ogr file, if any.
* @type {String}
*/
this.dataSourceUrl = undefined;
knockout.track(this, ['data', 'dataSourceUrl']);
};
inherit(CatalogItem, OgrCatalogItem);
defineProperties(OgrCatalogItem.prototype, {
/**
* Gets the type of data member represented by this instance.
* @memberOf OgrCatalogItem.prototype
* @type {String}
*/
type : {
get : function() {
return 'ogr';
}
},
/**
* Gets a human-readable name for this type of data source.
* @memberOf OgrCatalogItem.prototype
* @type {String}
*/
typeName : {
get : function() {
return 'Unknown / Converted to GeoJSON';
}
},
/**
* Gets the metadata associated with this data source and the server that provided it, if applicable.
* @memberOf OgrCatalogItem.prototype
* @type {Metadata}
*/
metadata : {
get : function() {
var result = new Metadata();
result.isLoading = false;
result.dataSourceErrorMessage = 'This data source does not have any details available.';
result.serviceErrorMessage = 'This service does not have any details available.';
return result;
}
},
/**
* Gets the data source associated with this catalog item.
* @memberOf OgrCatalogItem.prototype
* @type {DataSource}
*/
dataSource : {
get : function() {
return defined(this._geoJsonItem) ? this._geoJsonItem.dataSource : undefined;
}
}
});
OgrCatalogItem.prototype._getValuesThatInfluenceLoad = function() {
return [this.url, this.data];
};
OgrCatalogItem.prototype._load = function() {
if (typeof FormData === 'undefined') {
throw new TerriaError({
sender: this,
title: 'Legacy browser not supported',
message: '\
Your web browser does not support the "FormData" type, which is required by the '+this.terria.appName+' conversion service. \
We recommend you upgrade to the latest version of <a href="http://www.google.com/chrome" target="_blank">Google Chrome</a>, \
<a href="http://www.mozilla.org/firefox" target="_blank">Mozilla Firefox</a>, \
<a href="https://www.apple.com/au/osx/how-to-upgrade/" target="_blank">Apple Safari</a>, or \
<a href="http://www.microsoft.com/ie" target="_blank">Microsoft Internet Explorer</a>.'
});
}
if (this.terria.configParameters.conversionServiceBaseUrl === false) {
// Don't allow conversion service. Duplicated in createCatalogItemFromFileOrUrl.js
throw new TerriaError({
title: 'Unsupported file type',
message: 'This file format is not supported by ' + this.terria.appName + '. Supported file formats include: ' +
'<ul><li>.geojson</li><li>.kml, .kmz</li><li>.csv (in <a href="https://github.com/TerriaJS/nationalmap/wiki/csv-geo-au">csv-geo-au format</a>)</li></ul>'
});
}
this._geoJsonItem = new GeoJsonCatalogItem( this.terria);
var that = this;
if (defined(that.data)) {
return when(that.data, function(data) {
if (!(data instanceof Blob)) {
//create a file blob
data = new Blob([data], {
type : 'application/octet-stream',
name: that.dataSourceUrl,
lastModifiedDate: new Date()
});
}
return loadOgrData(that, data);
});
} else {
return loadOgrData(that, undefined, that.url);
}
};
OgrCatalogItem.prototype._enable = function() {
if (defined(this._geoJsonItem)) {
this._geoJsonItem._enable();
}
};
OgrCatalogItem.prototype._disable = function() {
if (defined(this._geoJsonItem)) {
this._geoJsonItem._disable();
}
};
OgrCatalogItem.prototype._show = function() {
if (defined(this._geoJsonItem)) {
this._geoJsonItem._show();
}
};
OgrCatalogItem.prototype._hide = function() {
if (defined(this._geoJsonItem)) {
this._geoJsonItem._hide();
}
};
OgrCatalogItem.prototype.showOnSeparateMap = function(globeOrMap) {
if (defined(this._geoJsonItem)) {
return this._geoJsonItem.showOnSeparateMap(globeOrMap);
}
};
function loadOgrData(ogrItem, file, url) {
var terria = ogrItem.terria;
// generate form to submit file for conversion
var formData = new FormData();
if (defined(file)) {
var maxConversionSize = 1000000;
if (defined(terria.serverConfig) &&
defined(terria.serverConfig.config) &&
defined(terria.serverConfig.config.maxConversionSize)) {
maxConversionSize = terria.serverConfig.config.maxConversionSize;
}
if (file.size > maxConversionSize) {
var maxConversionSizeMB = maxConversionSize / 1000000;
errorLoading(ogrItem, 'The file size is greater than the '+maxConversionSizeMB+'MB limit of the '+terria.appName+' conversion service.');
return;
}
formData.append('input_file', file);
} else if (defined(url)) {
url = new Uri(url).resolve(new Uri(document.location.href)).toString();
formData.append('input_url', url);
}
console.log('Attempting to convert file via the Terria-Server ogr2ogr web service');
return loadWithXhr({
url : ogrItem.terria.configParameters.conversionServiceBaseUrl,
method : 'POST',
data : formData
}).then(function(response) {
ogrItem._geoJsonItem.data = JSON.parse(response);
return ogrItem._geoJsonItem.load().then(function() {
ogrItem.rectangle = ogrItem._geoJsonItem.rectangle;
ogrItem.clock = ogrItem._geoJsonItem.clock;
});
}).otherwise(function() {
errorLoading(ogrItem);
});
}
function errorLoading(ogrItem, msg) {
var terria = ogrItem.terria;
if (!defined(msg)) {
msg = 'This may indicate that the file is invalid or that it is not supported by the '+terria.appName+' conversion service.';
}
throw new TerriaError({
sender: ogrItem,
title: 'Error converting file to GeoJson',
message: '\
An error occurred while attempting to convert this file to GeoJson. ' + msg + ' If you would like assistance or further information, please email us \
at <a href="mailto:'+terria.supportEmail+'">'+terria.supportEmail+'</a>.'
});
}
module.exports = OgrCatalogItem;