terriajs
Version:
Geospatial data visualization platform.
247 lines (220 loc) • 12.4 kB
JavaScript
import React from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import defined from 'terriajs-cesium/Source/Core/defined';
import Collapsible from '../Custom/Collapsible/Collapsible';
import DataPreviewSections from './DataPreviewSections';
import DataUri from '../../Core/DataUri';
import MetadataTable from './MetadataTable';
import ObserveModelMixin from '../ObserveModelMixin';
import parseCustomMarkdownToReact from '../Custom/parseCustomMarkdownToReact';
import Styles from './mappable-preview.scss';
/**
* CatalogItem description.
*/
const Description = createReactClass({
displayName: 'Description',
mixins: [ObserveModelMixin],
propTypes: {
item: PropTypes.object.isRequired,
printView: PropTypes.bool
},
render() {
const catalogItem = this.props.item;
const dataUrlType = catalogItem.dataUrlType;
let hasDataUriCapability;
let dataUri;
let dataUriFormat;
if (dataUrlType === 'data-uri' || dataUrlType === 'local') {
hasDataUriCapability = DataUri.checkCompatibility();
if (hasDataUriCapability) {
dataUri = catalogItem.dataUrl;
if (dataUri) {
dataUriFormat = getDataUriFormat(dataUri);
}
}
}
return (
<div className={Styles.description}>
<If condition={catalogItem.description && catalogItem.description.length > 0}>
<div>
<h4 className={Styles.h4}>Description</h4>
{parseCustomMarkdownToReact(catalogItem.description, {catalogItem: catalogItem})}
</div>
</If>
<If condition={catalogItem.dataUrlType === 'local'}>
<p>This file only exists in your browser. To share it, you must load it onto a public web server.</p>
</If>
<If condition={catalogItem.dataUrlType !== 'local' && !catalogItem.hasDescription}>
<p>Please contact the provider of this data for more information, including information about usage rights and constraints.</p>
</If>
<DataPreviewSections metadataItem={catalogItem}/>
<If condition={catalogItem.dataCustodian && catalogItem.dataCustodian.length > 0}>
<div>
<h4 className={Styles.h4}>Data Custodian</h4>
{parseCustomMarkdownToReact(catalogItem.dataCustodian, {catalogItem: catalogItem})}
</div>
</If>
<If condition={!catalogItem.hideSource}>
<If condition={catalogItem.url}>
<h4 className={Styles.h4}>{catalogItem.typeName} URL</h4>
<Choose>
<When condition={catalogItem.type === 'wms'}>
<p key="wms-description">
This is a <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank" rel="noopener noreferrer">WMS
service</a>, which generates map images on request. It can be used in GIS software with this
URL:
</p>
</When>
<When condition={catalogItem.type === 'wfs'}>
<p key="wfs-description">
This is a <a href="https://en.wikipedia.org/wiki/Web_Feature_Service" target="_blank" rel="noopener noreferrer">WFS
service</a>, which transfers raw spatial data on request. It can be used in GIS software with this
URL:
</p>
</When>
</Choose>
<Choose>
<When condition={this.props.printView}>
<code>{catalogItem.url}</code>
</When>
<Otherwise>
<input readOnly
className={Styles.field}
type="text"
value={catalogItem.url}
onClick={e => e.target.select()} />
</Otherwise>
</Choose>
<Choose>
<When condition={catalogItem.type === 'wms' || (catalogItem.type === 'esri-mapServer' && defined(catalogItem.layers))}>
<p key="wms-layers">
Layer name{catalogItem.layers.split(',').length > 1 ? 's' : ''}: {catalogItem.layers}
</p>
</When>
<When condition={catalogItem.type === 'wfs'}>
<p key="wfs-typeNames">
Type name{catalogItem.typeNames.split(',').length > 1 ? 's' : ''}: {catalogItem.typeNames}
</p>
</When>
</Choose>
</If>
<If condition={catalogItem.metadataUrl}>
<h4 className={Styles.h4}>Metadata URL</h4>
<p>
<a href={catalogItem.metadataUrl} target="_blank" rel="noopener noreferrer"
className={Styles.link}>{catalogItem.metadataUrl}</a>
</p>
</If>
<If condition={catalogItem.dataUrlType && catalogItem.dataUrlType !== 'none' && catalogItem.dataUrl}>
<h4 className={Styles.h4}>Data URL</h4>
<p>
<Choose>
<When condition={catalogItem.dataUrlType.indexOf('wfs') === 0 || catalogItem.dataUrlType.indexOf('wcs') === 0}>
Use the link below to download the data. See the{' '}
{catalogItem.dataUrlType.indexOf('wfs') === 0 && <a href="http://docs.geoserver.org/latest/en/user/services/wfs/reference.html" target="_blank" rel="noopener noreferrer" key="wfs">Web Feature Service (WFS) documentation</a>}
{catalogItem.dataUrlType.indexOf('wcs') === 0 && <a href="http://docs.geoserver.org/latest/en/user/services/wcs/reference.html" target="_blank" rel="noopener noreferrer" key="wms">Web Coverage Service (WCS) documentation</a>}
{' '} for more information on customising URL query parameters.
<br/>
<Link url={catalogItem.dataUrl} text={catalogItem.dataUrl}/>
</When>
<When condition={dataUrlType === 'data-uri' || dataUrlType === 'local'}>
<If condition={hasDataUriCapability}>
<Link url={dataUri} text={"Download the currently selected data in " + dataUriFormat.toUpperCase() + " format"} download={getBetterFileName(dataUrlType, catalogItem.name, dataUriFormat)}/>
</If>
<If condition={!hasDataUriCapability}>
Unfortunately your browser does not support the functionality needed to download this data as a file.
Please use Chrome, Firefox or Safari to download this data.
</If>
</When>
<Otherwise>
Use the link below to download the data directly.
<br/>
<Link url={catalogItem.dataUrl} text={catalogItem.dataUrl}/>
</Otherwise>
</Choose>
</p>
</If>
<If condition={!this.props.printView && defined(catalogItem.metadata)}>
{/*
// By default every catalog item has an error message here, so better to ignore it.
<If condition={defined(catalogItem.metadata.dataSourceErrorMessage)}>
<div className={Styles.error}>
Error loading data source details: {catalogItem.metadata.dataSourceErrorMessage}
</div>
</If>
*/}
<If condition={defined(catalogItem.metadata.dataSourceMetadata) && catalogItem.metadata.dataSourceMetadata.items.length > 0}>
<div className={Styles.metadata}>
<Collapsible title="Data Source Details" isInverse={true}>
<MetadataTable metadataItem={catalogItem.metadata.dataSourceMetadata} />
</Collapsible>
</div>
</If>
{/*
<If condition={defined(catalogItem.metadata.serviceErrorMessage)}>
<div className={Styles.error}>
Error loading data service details: {catalogItem.metadata.serviceErrorMessage}
</div>
</If>
*/}
<If condition={defined(catalogItem.metadata.dataSourceMetadata) && catalogItem.metadata.dataSourceMetadata.items.length > 0}>
<div className={Styles.metadata}>
<Collapsible title="Data Service Details" isInverse={true}>
<MetadataTable metadataItem={catalogItem.metadata.serviceMetadata} />
</Collapsible>
</div>
</If>
</If>
</If>
</div>
);
},
});
/**
* Read the format from the start of a data uri, eg. data:attachment/csv,...
* @param {String} dataUri The data URI.
* @return {String} The format string, eg. 'csv', or undefined if none found.
*/
function getDataUriFormat(dataUri) {
if (defined(dataUri)) {
const slashIndex = dataUri.indexOf('/');
const commaIndex = dataUri.indexOf(',');
// Don't look into the data itself. Assume the format is somewhere in the first 40 chars.
if (slashIndex < commaIndex && commaIndex < 40) {
return dataUri.slice(slashIndex + 1, commaIndex);
}
}
}
/**
* Return a nicer filename for this file.
* @private
*/
function getBetterFileName(dataUrlType, itemName, format) {
let name = itemName;
const extension = "." + format;
// Only add the extension if it's not already there.
if (name.indexOf(extension) !== name.length - extension.length) {
name = name + extension;
}
// For local files, the file already exists on the user's computer with the original name, so give it a modified name.
if (dataUrlType === 'local') {
name = "processed " + name;
}
return name;
}
const Link = createReactClass({
displayName: 'Link',
mixins: [ObserveModelMixin],
propTypes: {
url: PropTypes.string.isRequired,
text: PropTypes.string.isRequired,
download: PropTypes.string
},
render() {
return (
<a href={this.props.url} className={Styles.link} download={this.props.download} target="_blank" rel="noopener noreferrer">{this.props.text}</a>
);
},
});
export default Description;