Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
johnvanbreda committed May 15, 2019
2 parents edfcc35 + 37597ad commit b2bb450
Show file tree
Hide file tree
Showing 6 changed files with 350 additions and 161 deletions.
83 changes: 83 additions & 0 deletions js/drivers/georeference/nominatim.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Indicia, the OPAL Online Recording Toolkit.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/gpl.html.
*/

/**
* A driver class to allow the georeference_lookup control to interface with the
* service at nominatim.openstreetmap.org.
*/

(function enclose($) {
window.Georeferencer = function georeferencer(mapdiv, callback) {
var tokens = [];
var near;
this.mapdiv = mapdiv;
// Make the place search near the chosen location.
if (this.mapdiv.georefOpts.georefPreferredArea !== '') {
tokens.push(this.mapdiv.georefOpts.georefPreferredArea.toLowerCase());
}
if (this.mapdiv.georefOpts.georefCountry !== '') {
tokens.push(this.mapdiv.georefOpts.georefCountry.toLowerCase());
}
if (tokens.indexOf('gb') > -1 && tokens.indexOf('united kingdom') > -1) {
// Nominatim has a quirk whereby if both GB and United Kingdom appear in the
// search term, everything is filtered out. If either is used on it's own,
// that's fine. If both are present we retain the more specific GB.
tokens.splice(tokens.indexOf('united kingdom'), 1);
}
near = tokens.join(', ');

this.georeference = function georeference(searchtext) {
var fullsearchtext = near ? searchtext + ', ' + near : searchtext;
var request = indiciaData.proxyUrl +
'?url=https://nominatim.openstreetmap.org?format=json&q=' + fullsearchtext;
$.getJSON(request, function handleResponse(data) {
// an array to store the responses in the required country
var places = [];
var converted = {};
jQuery.each(data, function eachRow(i, place) {
converted = {
name: place.display_name,
display: place.display_name,
centroid: {
x: place.lon,
y: place.lat
},
boundingBox: {
southWest: {
x: place.boundingbox[2],
y: place.boundingbox[1]
},
northEast: {
x: place.boundingbox[3],
y: place.boundingbox[0]
}
},
obj: place
};
places.push(converted);
});
callback(mapdiv, places);
});
};
};
}(jQuery));

/**
* Default this.mapdiv.georefOpts for this driver
*/
jQuery.fn.indiciaMapPanel.georeferenceDriverSettings = {
georefPreferredArea: '',
georefCountry: 'UK'
};
3 changes: 1 addition & 2 deletions js/indicia.datacomponents/jquery.idc.leafletMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
if (config.type === 'circle' && typeof metric !== 'undefined') {
config.options.radius = metric;
config.options.fillOpacity = 0.5;
config.options.stroke = false;
}
switch (config.type) {
// Circle markers on layer.
Expand Down Expand Up @@ -279,7 +278,7 @@
// Are there document hits to map?
$.each(response.hits.hits, function eachHit() {
var latlon = this._source.location.point.split(',');
addFeature(el, sourceSettings.id, latlon);
addFeature(el, sourceSettings.id, latlon, this._source.location.coordinate_uncertainty_in_meters);
});
// Are there aggregations to map?
if (typeof response.aggregations !== 'undefined') {
Expand Down
91 changes: 87 additions & 4 deletions js/indicia.datacomponents/jquery.idc.recordDetailsPane.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
'use strict';
var $ = jQuery;

/**
* Currently selected row ID.
*/
var occurrenceId;

/**
* Place to store public methods.
*/
Expand All @@ -48,6 +53,11 @@
var loadedAttrsOcurrenceId = 0;
var loadedExperienceOcurrenceId = 0;

/**
* Popup form validator.
*/
var validator;

function getExperienceCells(buckets, userId, el, filter, yr) {
var total = buckets.C + buckets.V + buckets.R;
var indicatorSize;
Expand Down Expand Up @@ -151,7 +161,7 @@
/**
* Loads and appends comments to the tab.
*/
function loadComments(el, occurrenceId) {
function loadComments(el) {
// Check not already loaded.
if (loadedCommentsOcurrenceId === occurrenceId) {
return;
Expand Down Expand Up @@ -184,7 +194,7 @@
});
}

function loadAttributes(el, occurrenceId) {
function loadAttributes(el) {
// Check not already loaded.
if (loadedAttrsOcurrenceId === occurrenceId) {
return;
Expand Down Expand Up @@ -326,11 +336,11 @@
doc = JSON.parse(selectedTr.attr('data-doc-source'));
switch (activeTab) {
case 0:
loadAttributes(el, doc.id);
loadAttributes(el);
break;

case 1:
loadComments(el, doc.id);
loadComments(el);
break;

case 2:
Expand Down Expand Up @@ -371,6 +381,60 @@
}
}

function redetFormSubmit(e) {
var data;
e.preventDefault();
if ($('#redet-species').val() === '') {
validator.showErrors({ 'redet-species:taxon': 'Please type a few characters then choose a name from the list of suggestions' });
} else if (validator.numberOfInvalids() === 0) {
$.fancybox.close();
data = {
website_id: indiciaData.website_id,
'occurrence:id': occurrenceId,
'occurrence:taxa_taxon_list_id': $('#redet-species').val(),
user_id: indiciaData.userId
};
if ($('#redet-comment').val()) {
data['occurrence_comment:comment'] = $('#redet-comment').val();
}
$.post(
indiciaData.ajaxFormPostRedet,
data,
function (response) {
if (typeof response.error !== 'undefined') {
alert(response.error);
} else {
// reload current tab
/*if (indiciaData.detailsTabs[indiciaFns.activeTab($('#record-details-tabs'))] === 'details' ||
indiciaData.detailsTabs[indiciaFns.activeTab($('#record-details-tabs'))] === 'comments') {
$('#record-details-tabs').tabs('load', indiciaFns.activeTab($('#record-details-tabs')));
}
reloadGrid();*/
}
}
);
// Now post update to Elasticsearch.
data = {
ids: [occurrenceId],
doc: {
metadata: {
website: {
id: 0
}
}
}
};
$.ajax({
url: indiciaData.esProxyAjaxUrl + '/updateids/' + indiciaData.nid,
type: 'post',
data: data,
success: function success(response) {
$(dataGrid).idcDataGrid('hideRowAndMoveNext');
}
});
}
}

/**
* Declare public methods.
*/
Expand Down Expand Up @@ -407,6 +471,10 @@
// Clean tabs
$('.ui-tabs-nav').removeClass('ui-widget-header');
$('.ui-tabs-nav').removeClass('ui-corner-all');
// Form validation for redetermination
if (el.settings.allowRedetermination) {
validator = $('#redet-form').validate();
}
$(dataGrid).idcDataGrid('on', 'rowSelect', function rowSelect(tr) {
var doc;
var rows = [];
Expand All @@ -415,9 +483,15 @@
var key;
var externalMessage;
var msgClass = 'info';
// Reset the redetermination form.
$('#redet-form :input').val('');
if (tr) {
doc = JSON.parse($(tr).attr('data-doc-source'));
occurrenceId = doc.id;
acceptedNameAnnotation = doc.taxon.taxon_name === doc.taxon.accepted_name ? ' (as recorded)' : '';
if (el.settings.allowRedetermination) {
acceptedNameAnnotation += '<span class="fas fa-edit push right" id="popup-redet" title="Redetermine this record"></span>';
}
vernaculardNameAnnotation = doc.taxon.taxon_name === doc.taxon.vernacular_name ? ' (as recorded)' : '';
addRow(rows, doc, 'ID', 'id');
addRow(rows, doc, 'ID in source system', 'occurrence.source_system_key');
Expand Down Expand Up @@ -482,6 +556,15 @@
$(el).find('.empty-message').show();
$(el).find('.tabs').hide();
});
if (el.settings.allowRedetermination) {
indiciaFns.on('click', '#popup-redet', {}, function expandRedet() {
$.fancybox($('#redet-form'));
});
indiciaFns.on('click', '#cancel-redet', {}, function expandRedet() {
$.fancybox.close();
});
$('#redet-form').submit(redetFormSubmit);
}
},

on: function on(event, handler) {
Expand Down
31 changes: 17 additions & 14 deletions js/jquery.indiciaMapPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,7 @@ var destroyAllFeatures;
var minTolerance;
if (geom instanceof OpenLayers.Geometry) {
minTolerance = getMinTolerance(geom, div);
for (var l = 0; l<layers.length; ++l) {
for (var l = 0; l < layers.length; ++l) {
// set defaults
getRadius = null;
getStrokeWidth = null;
Expand All @@ -1291,28 +1291,28 @@ var destroyAllFeatures;
// when testing a click point, use a circle drawn around the click point so the
// click does not have to be exact. At this stage, we just look for the layer default
// pointRadius and strokeWidth, so we can calculate the geom size to test.
if (geom.CLASS_NAME==='OpenLayers.Geometry.Point') {
if (typeof layer.styleMap.styles['default'].defaultStyle.pointRadius !== 'undefined') {
radius = layer.styleMap.styles['default'].defaultStyle.pointRadius;
if (typeof radius === "string") {
if (geom.CLASS_NAME === 'OpenLayers.Geometry.Point') {
if (typeof layer.styleMap.styles.default.defaultStyle.pointRadius !== 'undefined') {
radius = layer.styleMap.styles.default.defaultStyle.pointRadius;
if (typeof radius === 'string') {
// A setting {n} means we use n to get the pointRadius per feature (either a field or a context func)
match = radius.match(/^\${(.+)}/);
if (match !== null && match.length > 1) {
getRadius = layer.styleMap.styles['default'].context[match[1]];
getRadius = layer.styleMap.styles.default.context[match[1]];
if (getRadius === undefined) {
// the context function is missing, so must be a field name
getRadius = match[1];
}
}
}
}
if (typeof layer.styleMap.styles['default'].defaultStyle.strokeWidth !== 'undefined') {
strokeWidth = layer.styleMap.styles['default'].defaultStyle.strokeWidth;
if (typeof layer.styleMap.styles.default.defaultStyle.strokeWidth !== 'undefined') {
strokeWidth = layer.styleMap.styles.default.defaultStyle.strokeWidth;
if (typeof strokeWidth === 'string') {
// A setting {n} means we use n to get the strokeWidth per feature (either a field or a context func)
match = strokeWidth.match(/^\${(.+)}/);
if (match !== null && match.length > 1) {
getStrokeWidth = layer.styleMap.styles['default'].context[match[1]];
getStrokeWidth = layer.styleMap.styles.default.context[match[1]];
if (getStrokeWidth === undefined) {
// the context function is missing, so must be a field name
getStrokeWidth = match[1];
Expand Down Expand Up @@ -1531,16 +1531,19 @@ var destroyAllFeatures;
//Continue with the deactivation.
OpenLayers.Control.prototype.deactivate.call(this);
},
activate: function() {
activate: function activate() {
if (div.settings.selectFeatureBufferProjection) {
if ($('#click-buffer').length === 0) {
$('#map-container').append(
'<label id="click-buffer" class="olButton">Tolerance:<input type="text" value="1000"/>m</label>');
$('#click-buffer').css('right', $('.olControlEditingToolbar').outerWidth() + 10);
$("#click-buffer input").keyup(function () {
$("#click-buffer input").val(this.value.match(/[0-9]*/));
$('#click-buffer').css('right', $('.olControlEditingToolbar').outerWidth() + 10);
$('#click-buffer input').keypress(function (evt) {
// Only accept numeric input.
if (evt.which < 48 || evt.which > 57) {
evt.preventDefault();
}
});
$("#click-buffer input").change(function () {
$('#click-buffer input').change(function () {
bufferRoundSelectedRecord(div, $('#click-buffer input').val());
});
} else {
Expand Down
17 changes: 10 additions & 7 deletions js/reportFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jQuery(document).ready(function ($) {
return origRemove.apply(this, arguments).trigger('remove');
};

indiciaData.filter = {def: {}, id: null, title: null};
indiciaData.filter = { def: {}, id: null, title: null };

function removeSite() {
var idToRemove = $(this).find('input[name="location_list[]"]').val();
Expand Down Expand Up @@ -509,14 +509,17 @@ jQuery(document).ready(function ($) {
}

$.each(indiciaData.mapdiv.map.editLayer.features, function (i, feature) {
var thisGeom;
// ignore features with a special purpose, e.g. the selected record when verifying
if (typeof feature.tag === 'undefined' &&
(typeof feature.attributes.type === 'undefined' ||
(feature.attributes.type !== 'boundary' && feature.attributes.type !== 'ghost'))) {
if (feature.geometry.CLASS_NAME.indexOf('Multi') !== -1) {
geoms = geoms.concat(feature.geometry.components);
(typeof feature.attributes.type === 'undefined' ||
(feature.attributes.type !== 'boundary' && feature.attributes.type !== 'ghost'))) {
// In some cases, custom code adds a buffer to the search area feature.
thisGeom = typeof feature.buffer === 'undefined' ? feature.geometry : feature.buffer.geometry;
if (thisGeom.CLASS_NAME.indexOf('Multi') !== -1) {
geoms = geoms.concat(thisGeom.components);
} else {
geoms.push(feature.geometry);
geoms.push(thisGeom);
}
}
});
Expand Down Expand Up @@ -827,7 +830,7 @@ jQuery(document).ready(function ($) {
}
// Event handler for a draw tool boundary being added which clears the other controls on the map pane.
function addedFeature() {
$('#controls-filter_where').find(':input').not('#imp-sref-system,:checkbox,[type=button],[name="location_list\[\]"]').val('');
$('#controls-filter_where').find(':input').not('.locked-value,#imp-sref-system,:checkbox,[type=button],[name="location_list\[\]"]').val('');
$('#controls-filter_where').find(':checkbox').attr('checked', false);
// If a selected site but switching to freehand, we need to clear the site boundary.
if (siteOrGridRefSelected()) {
Expand Down
Loading

0 comments on commit b2bb450

Please sign in to comment.