Commit e26e0f33 authored by Stefan Funk's avatar Stefan Funk
Browse files

Merge branch '50-geocompletion-by-getty-id' into 'develop'

Fix issue #50 by providing an option to geocode by GettyID

See merge request !5
parents 817b1bdd 7822e2f1
......@@ -138,7 +138,12 @@
<div id="content" class="primary-area">
<div id="tgnArea" class="well span6">
<h3>Place selection &nbsp; <img id="spinningGeolocationCompletionFlower" class="hide" src="https://res.de.dariah.eu/dhrep/img/spinning-flower_slow.gif" alt="Geolocation completion running" width="22" /></h3>
<p>The coordinates for the first place found in the TGN are automatically added to the sheet, you may have to adjust the places below!</p>
<label for="geolocationSource">Geolocation can be based either on column <i>Address</i> or on column <i>GettyID</i> in your datasheet. Existing entries will not be overwritten. Choose which one to use: </label>
<select name="geolocationSource" id="geolocationSource">
<option value="Address">Address</option>
<option value="GettyID">GettyID</option>
</select>
<p>The coordinates for the first place found in the TGN are automatically added to the sheet, you may have to adjust the places below!</p>
<p><i class="icon-pencil"></i>&nbsp; sets all places in the sheet with the highlighted address to the coordinates of the chosen place.<br/>
<i class="icon-eye-open"></i>&nbsp; shows the chosen place in the <i>Map selection</i> and allows you to correct and refine coordinates or set unrecognized places.</p><br/>
<div id="tgnList"></div>
......@@ -155,8 +160,10 @@
<input id="osmPlaceName" style="width:77%;" type="text" class="input-large" placeholder="Enter exact place name as in “Address“ field..."/>
<button id="setAllPlacesOSMButton" class="btn" style="width:18%;" onClick="setAllPlacesOSM()" title="Sets all places with this name to the chosen coordinates."><i id='setAllPlacesIcon' class="icon-pencil"></i>&nbsp;Set</button>
</div>
<i>Note: 'Set' will set coordinates for <b>all</b> table rows with this address unless you only select specific rows or cells first.</i>
<br/><br/>
<div>
<i>Note: 'Set' will overwrite coordinates for <b>all</b> table rows matching this place unless you only select specific rows or cells first.</i>
<br/>
</div>
<div id="editMap" class="osmMap"></div>
<br/>
<h3>Map search</h3>
......
......@@ -31,7 +31,8 @@ var ownStorageElementListSize = 25;
/*
* Configuration for geographic checks & maps.
*/
var tgnURL = 'https://ref.de.dariah.eu/tgn/v1/exact-match';
var tgnBaseURL = 'https://ref.de.dariah.eu/tgn/v1/';
var tgnMatchURL = 'https://ref.de.dariah.eu/tgn/v1/exact-match';
var ognURL = 'https://ref.de.dariah.eu/geonames/postalCodeSearchJSON';
var ognUsername = 'dariahde';
var osmSearchUrl = 'https://nominatim.openstreetmap.org/search';
......
......@@ -17,6 +17,24 @@ function initMap() {
});
}
function startTGN() {
$('#tgnArea').show();
// do nothing if there are columns missing
if (!checkColumnHeadersGeolocation()) {
return;
}
var arr = tableInstance.getData();
$('#tgnList').empty();
var source = $('#geolocationSource').val();
if (source === 'GettyID') {
tgnByGettyID(arr);
} else {
tgnByAddress(arr);
}
}
function getUniqueColumnValues(columnName){
// somehow sort() & $.unique() failed on chromium, this solution using underscore.js works:
//http://stackoverflow.com/questions/4833651/javascript-array-sort-and-unique
......@@ -38,17 +56,79 @@ function getUniqueColumnValues(columnName){
})
return sortUnique(selectedValues);
}
function startTGN() {
$('#tgnArea').show();
// do nothing if there are columns missing
if (!checkColumnHeadersGeolocation()) {
return;
}
function tgnByGettyID(){
var gettyIds = getUniqueColumnValues('GettyID');
var numberOfCallsToDo = gettyIds.length;
if (numberOfCallsToDo === 0){
var selection = tableInstance.getSelectedLast();
if (selection){
newAlert('error', 'No GettyID values in current selection!', '<p>No GettyID column values found in selected cells. If you want to process the whole data set, click on <button class="btn btn-small btn-primary" onclick="clearTableSelection();$(\'.geocodeAlert\').alert(\'close\');" title="Clear selection">Clear selection</button> first. <br> ' +
'Otherwise, select non-empty values in the <i>GettyID</i> column.</p>', 'geocodeAlert');
} else newAlert('error', 'No data available for Geolocation!', '<p>No values found in column <i>GettyID</i>.' + '</p>', 'geocodeAlert');
} else $(".geocodeAlert").alert('close');
var arr = tableInstance.getData();
var numberOfCallsCompleted = 0;
$.each(gettyIds, function(index, id) {
if (index == 0 ) {
geolocationCompletionStart();
}
$.get(tgnBaseURL + id + '.json').success(function (json) {
var results = json.results.bindings;
var lat, long, label;
results.forEach(function (obj) {
var pred = obj.Predicate.value;
if (pred === "http://www.w3.org/2000/01/rdf-schema#label") {
if (!label) label = obj.Object.value;
} else if (pred === "http://schema.org/latitude"){
lat = obj.Object.value;
} else if (pred === "http://schema.org/longitude"){
long = obj.Object.value;
}
})
var elemId = 'tgn_' + getBase64Without(id);
var elem = '<div class="input-append">'
+ '<h4 style="margin-bottom:3px;">' + id + '</h4>'
+ '<p><select style="width:64%;" id="' + elemId + '"></select>'
+ '<button class="btn" style="width:18%;" id="pick-' + elemId + '" id="' + id + '" title="Show this place in the map selection on the right."><i class="icon-eye-open"></i>&nbsp;Map</button>'
+ '<button class="btn" style="width:18%;" id="setAll-' + elemId + '" title="Set the coordinates of all places with TGN ID =' + id + ' to the coordinates of the chosen place."><i class="icon-pencil"></i>&nbsp;Set</button>'
+ '</p></div>';
$('#tgnList').empty();
$('#tgnList').append(elem);
// Bind function to change event.
$('#' + elemId).change(placeChanged);
$('#pick-' + elemId).bind('click', pickPlace);
$('#setAll-' + elemId).bind('click', setAllPlacesTGN);
// add disabled and hidden option for storing the original place name!
$('#' + elemId).append('<option id="tgnOrigPlace-' + elemId + '" disabled="disabled" class="hide" value="' + label + '">' + label + '</option>');
$('#' + elemId).append('<option value="' + label + '|' + id + '|' + lat + '|' + long + '">' + label + '</option>');
if (label && lat && long) updateCoordinates(label, lat, long, id, false);
numberOfCallsCompleted++;
if (numberOfCallsToDo === numberOfCallsCompleted) {
geolocationCompletionComplete();
}
/// Use additional text for empty TGN result.
if (!label) {
$('#' + elemId).append('<option value="' + noResults + '">' + noResults + '</option>');
$('#setAll-' + elemId).addClass('disabled');
$('#setAll-' + elemId).attr('disabled', true);
}
}).fail(function() {
numberOfCallsCompleted++;
if (numberOfCallsToDo === numberOfCallsCompleted) {
geolocationCompletionComplete();
}
var elem = '<div><h4 style="margin-bottom:3px;">' + id + '</h4>'
+ '<p>Error when trying to resolve '+id+'.</p></div>';
$('#tgnList').append(elem);
});
});
}
function tgnByAddress(){
var places = getUniqueColumnValues('Address');
// count number of TGN calls to do
......@@ -64,12 +144,12 @@ function startTGN() {
$.each(places, function(index, place) {
// disable Geolocation completion button before first Getty GET!
if (index == 0 ) {
if (index === 0 ) {
geolocationCompletionStart();
}
// query TGN
var placeAlreadySetInTable = false;
$.get(tgnURL, {q : place, georef : 'true'})
$.get(tgnMatchURL, {q : place, georef : 'true'})
.success(function(xml){
var elemId = 'tgn_' + getBase64Without(place);
var titlePlace = place;
......@@ -277,31 +357,53 @@ function setAllPlacesOSM() {
var lat = $('#osmLat').val();
var long = $('#osmLong').val();
// Saveguard that empty fields are NOT filled with coords :-)
if (name != null && name != "") {
updateCoordinates(name, lat, long, gettyId, true);
}
updateCoordinates(name, lat, long, gettyId, true);
}
/*
*
*/
function tgnSearch() {
var place = $('#search').val();
var searchString = '<p></p><p>Searching for "' + place + '" in Getty Thesaurus of Goegraphical Names...</p>';
var foundString = '<p></p><p>Places found for "' + place + '" in Getty Thesaurus of Goegraphical Names:</p>';
$('#tgnOsmList').html(searchString);
var place = $('#search').val().trim();
var isNum = /^\d+$/.test(place);
if (place.length === 7 && isNum) {
var searchString = '<p></p><p>Searching for TGN ID "' + place + '" in Getty Thesaurus of Geographical Names...</p>';
$('#tgnOsmList').html(searchString);
$.get(tgnBaseURL + place + '.json').success(function (json) {
var results = json.results.bindings;
var value = "";
results.forEach(function (obj) {
var pred = obj.Predicate.value;
if (pred === "http://www.w3.org/2000/01/rdf-schema#label") {
value = obj.Object.value;
}
})
place = value;
tgnAddressSearch(place);
}).fail(function() {
$('#tgnOsmList').html('<p></p><p><strong>No results</strong> found for TGN ID "' + place + '" in Getty Thesaurus of Geographical Names...</p>');
});
} else {
tgnAddressSearch(place);
}
}
function tgnAddressSearch(place){
var searchString = '<p></p><p>Searching for "' + place + '" in Getty Thesaurus of Geographical Names...</p>';
var foundString = '<p></p><p>Places found for "' + place + '" in Getty Thesaurus of Geographical Names:</p>';
$('#tgnOsmList').html(searchString);
$.get(tgnURL, {q : place, georef : 'true'}).success(function(xml) {
$.get(tgnMatchURL, {q : place, georef : 'true'}).success(function(xml) {
var datasets = $(xml).find('term');
if ($(datasets).length < 1) {
$('#tgnOsmList').html('<p></p><p><strong>No results</strong> found for "' + place + '" found in Getty Thesaurus of Goegraphical Names.</p>');
$('#tgnOsmList').html('<p></p><p><strong>No results</strong> found for "' + place + '" in Getty Thesaurus of Geographical Names.</p>');
return;
}
else {
$('#tgnOsmList').html(foundString);
}
else {
$('#tgnOsmList').html(foundString);
}
var elemId = 'tgnosm_' + getBase64Without(place);
var elem = '<p></p><div>'
......
......@@ -233,18 +233,31 @@ function isSelected (row, col){
var endCol = selected[3];
return row >= startRow && row <= endRow && col >= startCol && col <= endCol;
}
/**
* Write value to table cell.
* @param forceOverwrite -- whether the current table value should be overwritten
* @param columnValue -- current column value
* @param row -- current row
* @param column -- column index
* @param newValue -- value to write
*/
function writeTableCell(forceOverwrite, columnValue, row, column, newValue){
if ((forceOverwrite || isEmptyString(columnValue)) && isSelected(row, column)) {
if (!isEmptyString(newValue)) tableInstance.setDataAtCell(row, column, newValue);
}
}
/**
* Table is filled with coords and Getty IDs only if address is contained in table's address field
* or address field is empty AND (if given) address field content is contained in variant string.
*
* Getty ID is only overwritten if also not existing!
* or address field is empty AND (if given) address field content is contained in variant string, or matching GettyID is given.
* Address values can be set by Map selection if address field is empty and matching GettyID available.
* Existing GettyIDs cannot be overwritten by geolocation, but by Map selection. No values can be overwritten by empty values.
*/
function updateCoordinates(address, lat, long, gettyId, forceOverwrite, variant) {
// In case variant is not existing or given.
if (!variant) {
variant = "";
}
var arr = tableInstance.getData();
var addressColumn = findColumn(arr, 'Address');
var longColumn = findColumn(arr, 'Longitude');
......@@ -253,17 +266,15 @@ function updateCoordinates(address, lat, long, gettyId, forceOverwrite, variant)
var save = false;
$(arr).each(function(index, val) {
if ($.trim(val[addressColumn]) === $.trim(address) || ($.trim(val[addressColumn]) !== "" && variant.includes($.trim(val[addressColumn])))) {
if ((forceOverwrite || isEmptyString(val[gettyColumn])) && isSelected(index, gettyColumn)){
if (!isEmptyString(gettyId)) tableInstance.setDataAtCell(index, gettyColumn, gettyId);
}
if ((forceOverwrite || isEmptyString(val[longColumn])) && isSelected(index, longColumn)){
if (!isEmptyString(long)) tableInstance.setDataAtCell(index, longColumn, long);
}
if ((forceOverwrite || isEmptyString(val[latColumn])) && isSelected(index, latColumn)){
if (!isEmptyString(lat)) tableInstance.setDataAtCell(index, latColumn, lat);
}
if (!isEmptyString(address) && $.trim(val[addressColumn]) === $.trim(address) || ($.trim(val[addressColumn]) !== "" && variant.includes($.trim(val[addressColumn])))) {
writeTableCell(forceOverwrite, val[gettyColumn], index, gettyColumn, gettyId);
writeTableCell(forceOverwrite, val[longColumn], index, longColumn, long);
writeTableCell(forceOverwrite, val[latColumn], index, latColumn, lat);
save = true;
} else if (!isEmptyString(gettyId) && $.trim(val[gettyColumn]) === $.trim(gettyId)){ //update by GettyID
writeTableCell(forceOverwrite, val[longColumn], index, longColumn, long);
writeTableCell(forceOverwrite, val[latColumn], index, latColumn, lat);
writeTableCell(false, val[addressColumn], index, addressColumn, address);
save = true;
}
});
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment