Skip to content

Commit

Permalink
Merge pull request #36 from schorcht-ioer/beta
Browse files Browse the repository at this point in the history
added previewer for shp and geotiff
  • Loading branch information
qqmyers authored Jul 12, 2023
2 parents bb1c6d6 + da79777 commit ab93045
Show file tree
Hide file tree
Showing 5 changed files with 322 additions and 0 deletions.
56 changes: 56 additions & 0 deletions 5.2curlcommands.md
Original file line number Diff line number Diff line change
Expand Up @@ -743,3 +743,59 @@ curl -X POST -H 'Content-type: application/json' http://localhost:8080/api/admin
"contentType":"text/markdown"
}'
```

### ESRI Shape Previewer (beta)

This previewer includes a hard-coded file size limit of a zipped shp file of 20 MB (larger zips will not be loaded). If you want to change this limit you can change the value in "previewers/betatest/js/mapshp.js", but then you have to host the customised previewer yourself (e.g. via github pages). Instructions on how to build external tools yourself can be found here: https://guides.dataverse.org/en/latest/api/external-tools.html.

```bash
curl -X POST -H 'Content-type: application/json' http://localhost:8080/api/admin/externalTools -d \
'{
"displayName":"View Map",
"description":"View a map of the file.",
"toolName":"mapShpPreviewer",
"scope":"file",
"types":["preview"],
"toolUrl":"gdcc.github.io/dataverse-previewers/previewers/betatest/MapShpPreview.html",
"toolParameters": {
"queryParameters":[
{"fileid":"{fileId}"},
{"siteUrl":"{siteUrl}"},
{"key":"{apiToken}"},
{"datasetid":"{datasetId}"},
{"datasetversion":"{datasetVersion}"},
{"locale":"{localeCode}"}
]
},
"contentType":"application/zipped-shapefile"
}'
```

### GeoTIFF Previewer (beta)

Please note that the Geotiff Previewer tries to display ALL image/tiff files in a map (because there is no own mimetype for Geotiffs at the moment). Therefore please only use it if you want to use Geotiffs only. As soon as there is an own mimetype for Geotiffs, this will be updated.

Limits are also defined for previewing raster files. Besides the file size limit (20 MB), a column and row limit (50,000) and a loading timeout (30 seconds) are defined. In case of an unsupported GeoTIFF (e.g. no projection specified), an error message is displayed after 30 seconds stating that the tiff image cannot be loaded. These limits can be adjusted as needed in previewers/betatest/js/mapraster.js, although this adjusted version must then also be hosted by yourself (e.g. via github pages). Instructions on how to build external tools yourself can be found here: https://guides.dataverse.org/en/latest/api/external-tools.html.

```bash
curl -X POST -H 'Content-type: application/json' http://localhost:8080/api/admin/externalTools -d \
'{
"displayName":"View Map",
"description":"View a map of the file.",
"toolName":"mapShpPreviewer",
"scope":"file",
"types":["preview"],
"toolUrl":"gdcc.github.io/dataverse-previewers/previewers/betatest/MapRasterPreview.html",
"toolParameters": {
"queryParameters":[
{"fileid":"{fileId}"},
{"siteUrl":"{siteUrl}"},
{"key":"{apiToken}"},
{"datasetid":"{datasetId}"},
{"datasetversion":"{datasetVersion}"},
{"locale":"{localeCode}"}
]
},
"contentType":"image/tiff"
}'
```
49 changes: 49 additions & 0 deletions previewers/betatest/MapRasterPreview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<html>
<head>
<meta charset="utf-8">
<title class="mapPreviewText">Map Preview</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="js/xss.js"></script>
<script src="lib/jquery.i18n.js"></script>
<script src="lib/jquery.i18n.messagestore.js"></script>
<script src="lib/jquery.i18n.language.js"></script>
<script type="text/javascript" src="js/retriever.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css"
integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
<!-- Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous"/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin="anonymous"></script>
<link type="text/css" rel="stylesheet" href="css/preview.css" />
<!--drawing raster-->
<script src="https://unpkg.com/georaster"
integrity="sha512-EPpN3KleOAW9ST4LCK50R9Fu/UWlB92OSsKiCLUOwX0rpDw7PwdWwzLNerdMxlbLZC+cnxybJMS3jl2I1EdpVQ==" crossorigin="anonymous"></script>
<script src="https://unpkg.com/georaster-layer-for-leaflet"
integrity="sha512-bNJ+bvpXepatbIMeaida52kR2AT5lr6a9dTfb/OB0c/3O2KzUrdUi3Gtri0zvJUbfKgmG+wN3GKTkBi/6OkVVA==" crossorigin="anonymous"></script>
<!-- spinner-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.2/spin.js"
integrity="sha512-C7tgVIfPE0ivBKcs2WstAh5y7Njir2odGBjnuIa64SmVzZIoTb8kRrNursRzEv4bNcesPywtVAXqH1GmqRBmpg==" crossorigin="anonymous"></script>
</head>

<body class="container">
<main>
<img id='logo' alt='Site Logo'>
<h1 class="page-title mapPreviewText">Map Preview</h1>
<div class="alert alert-warning" id="file_error" hidden>
<span class="glyphicon glyphicon-warning-sign"></span>&nbsp;<strong>Drawing Error</strong>
</div>
<div class='preview-container'>
<div class='preview-header'></div>
<div class='preview'>
<div id="map" style="width: 800px; height: 500px;"></div>
</div>
</div>
</main>
<script type="text/javascript" src="js/mapraster.js"></script>
</body>
</html>
50 changes: 50 additions & 0 deletions previewers/betatest/MapShpPreview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<html>
<head>
<meta charset="utf-8">
<title class="mapPreviewText">Map Preview</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="js/xss.js"></script>
<script src="lib/jquery.i18n.js"></script>
<script src="lib/jquery.i18n.messagestore.js"></script>
<script src="lib/jquery.i18n.language.js"></script>
<script type="text/javascript" src="js/retriever.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css"
integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
<!-- Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous"/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin="anonymous"></script>
<link type="text/css" rel="stylesheet" href="css/preview.css" />
<!-- ShapeJS-->
<script src="https://cdn.rawgit.com/calvinmetcalf/shapefile-js/gh-pages/dist/shp.js"
integrity="sha512-RT1pg7PTZ3R8amXsuOV3aJAVjBxenRKgmLg68ZMN6RMeRQWTrbxnPszM9+6/UVkmuRYaM0cg6R5lqwQJfJhVUw==" crossorigin="anonymous"></script>
<script src="https://cdn.rawgit.com/calvinmetcalf/leaflet.shapefile/gh-pages/leaflet.shpfile.js"
integrity="sha512-pZ4bO+wYEIa3xGxktY7N3CDNF4QfBlzmps/cqfOY2SZA7v1kH/y7rxQaqvk1W31NqjVTcyZkV0fPaOBGcCTOgg==" crossorigin="anonymous"></script>
<!-- spinner-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.2/spin.js"
integrity="sha512-C7tgVIfPE0ivBKcs2WstAh5y7Njir2odGBjnuIa64SmVzZIoTb8kRrNursRzEv4bNcesPywtVAXqH1GmqRBmpg==" crossorigin="anonymous"></script>

</head>

<body class="container">
<main>
<img id='logo' alt='Site Logo'>
<h1 class="page-title mapPreviewText">Map Preview</h1>
<div class="alert alert-warning" id="file_error" hidden>
<span class="glyphicon glyphicon-warning-sign"></span>&nbsp;<strong>Drawing Error</strong>
</div>
<div class='preview-container'>
<div class='preview-header'></div>
<div class='preview'>
<div id="map" style="width: 800px; height: 500px;"></div>
</div>
</div>
</main>
<script type="text/javascript" src="js/mapshp.js"></script>
</body>
</html>
90 changes: 90 additions & 0 deletions previewers/betatest/js/mapraster.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
$(document).ready(function() {
startPreview(false);
});

// set limits
const file_size_limit = 15; // in MB
const row_col_limit = 50000; // number of columns or rows
const load_timeout = 30; // in seconds

var raster_loaded = false;

// enable spinner
var target = document.getElementById('map');
var spinner = new Spinner().spin(target);

function translateBaseHtmlPage() {
var mapPreviewText = $.i18n( "mapPreviewText" );
$( '.mapPreviewText' ).text( mapPreviewText );
}

function writeContent(fileUrl, file, title, authors) {
addStandardPreviewHeader(file, title, authors);

//check file size
const url_to_file_info = fileUrl.replace("access/data","").replace("file","files");

$.getJSON(url_to_file_info, function( data ) {
const file_size = data.data.dataFile.filesize/(1024**2);

if (file_size > file_size_limit){
show_error(`The file is too big to be displayed (limit is ${file_size_limit.toString()} MB)`);
}else{
// initialize the map
var map = L.map('map').fitWorld();

// add OpenStreetMap basemap
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

// load the raster
fetch(fileUrl)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
parseGeoraster(arrayBuffer).then(georaster => {
raster_loaded = true;
// check row, col limits
if (georaster.width > row_col_limit || georaster.height > row_col_limit){
show_error(`The number of rows or columns is too high to be displayed (limit is ${row_col_limit.toString()})`);
// draw the raster
}else{
//console.log("georaster:", georaster);

var layer = new GeoRasterLayer({
georaster: georaster,
//debugLevel: 2,
opacity: 1,
resolution: 256
});
layer.addTo(map);
map.fitBounds(layer.getBounds());

// disable spinner
spinner.stop();
}
});
// check if raster is loaded
}).then(checkIfLoaded());
}
})
}

function show_error(error_text){
$('#map').hide();
$('#file_error').show();
$('#file_error').append(error_text);
}

// it is not possible to catch the error of 'parseGeoraster' :\ see: https://github.com/GeoTIFF/georaster/issues/71
// in case of not supported tiffs (e.g. Interleaving type "BSQ" with palette) an error is thrown by 'parseGeoraster', but the promise keeps pending :\
// therefore, after a certain time, it is checked whether the raster has been loaded.
// if the raster is not loaded, an error is shown..
function checkIfLoaded() {
setTimeout(() => {
if(!raster_loaded){
show_error("The raster could not be loaded. This may be because it is not a valid GeoTIFF (e.g. projection information is missing). Or the TIFF has a palette with interleaving type 'BSQ', which is not supported.");
spinner.stop();
}
}, load_timeout * 1000);
}
77 changes: 77 additions & 0 deletions previewers/betatest/js/mapshp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
$(document).ready(function() {
startPreview(false);
});

// initialize the map
var map = L.map('map').fitWorld();

function translateBaseHtmlPage() {
var mapPreviewText = $.i18n( "mapPreviewText" );
$( '.mapPreviewText' ).text( mapPreviewText );
}

// set limits
const file_size_limit = 20; // in MB

// enable spinner
var target = document.getElementById('map');
var spinner = new Spinner().spin(target);

function writeContent(fileUrl, file, title, authors) {
addStandardPreviewHeader(file, title, authors);

//check file size
const url_to_file_info = fileUrl.replace("access/data","").replace("file","files");

$.getJSON(url_to_file_info, function( data ) {
const file_size = data.data.dataFile.filesize/(1024**2);

if (file_size > file_size_limit){
show_error(`The file is too big to be displayed (limit is ${file_size_limit.toString()} MB)`);
}else{
// load a tile layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

// get data
var request = new XMLHttpRequest();
request.open('GET', fileUrl, true);
request.responseType = 'blob';
request.onload = function() {
var reader = new FileReader();
reader.readAsArrayBuffer(request.response);
reader.onload = function(e){
convertToLayer(e.target.result);
};
};
request.send();
}
});
}

function convertToLayer(buffer){
shp(buffer).then(function(shapeData){ //More info: https://github.com/calvinmetcalf/shapefile-js
var shape = L.shapefile(shapeData, {
onEachFeature: function (feature, layer) {
if (feature.properties) {
var popupcontent = [];
for (var propName in feature.properties) {
propValue = feature.properties[propName];
popupcontent.push("<strong>" + propName + "</strong>: " + JSON.stringify(propValue, null, 2));
}
layer.bindPopup(popupcontent.join("<br />"));
}
}
}).addTo(map); //More info: https://github.com/calvinmetcalf/leaflet.shapefile
map.fitBounds(shape.getBounds());
// disable spinner
spinner.stop();
});
}

function show_error(error_text){
$('#map').hide();
$('#file_error').show();
$('#file_error').append(error_text);
}

0 comments on commit ab93045

Please sign in to comment.