From ee543df158f6b5edb0805ce3b3aa574706979149 Mon Sep 17 00:00:00 2001 From: David Read Date: Tue, 30 Oct 2012 09:34:40 +0000 Subject: [PATCH 001/114] Added useful logging to the validation report. Useful to have the date (i.e. version) in the name of the Eden schema. --- ckanext/spatial/lib/reports.py | 12 ++++++++++-- ckanext/spatial/validation/validation.py | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ckanext/spatial/lib/reports.py b/ckanext/spatial/lib/reports.py index b66e276..a112cf6 100644 --- a/ckanext/spatial/lib/reports.py +++ b/ckanext/spatial/lib/reports.py @@ -7,8 +7,6 @@ from ckanext.spatial.lib.report import ReportTable from ckan import model from ckanext.harvest.model import HarvestObject -log = logging.getLogger(__name__) - def validation_report(package_id=None): ''' Looks at every harvested metadata record and compares the @@ -17,6 +15,7 @@ def validation_report(package_id=None): Returns a ReportTable. ''' + log = logging.getLogger(__name__ + '.validation_report') validators = SpatialHarvester()._get_validator() log.debug('Validators: %r', validators.profiles) @@ -38,18 +37,25 @@ def validation_report(package_id=None): 'Old validation errors', 'New validation errors']) + old_validation_failure_count = 0 + new_validation_failure_count = 0 + for harvest_object in query: validation_errors = [] for err in harvest_object.errors: if 'not a valid Gemini' in err.message or \ 'Validating against' in err.message: validation_errors.append(err.message) + if validation_errors: + old_validation_failure_count += 1 groups = harvest_object.package.get_groups() publisher = groups[0].title if groups else '(none)' xml = etree.fromstring(harvest_object.content.encode("utf-8")) valid, errors = validators.is_valid(xml) + if not valid: + new_validation_failure_count += 1 report.add_row_dict({ 'Harvest Object id': harvest_object.id, @@ -63,4 +69,6 @@ def validation_report(package_id=None): }) log.debug('%i results', query.count()) + log.debug('%i failed old validation', old_validation_failure_count) + log.debug('%i failed new validation', new_validation_failure_count) return report diff --git a/ckanext/spatial/validation/validation.py b/ckanext/spatial/validation/validation.py index c7e95d7..9bba5e3 100644 --- a/ckanext/spatial/validation/validation.py +++ b/ckanext/spatial/validation/validation.py @@ -67,7 +67,7 @@ class ISO19139Schema(XsdValidator): class ISO19139EdenSchema(XsdValidator): name = 'iso19139eden' - title = 'ISO19139 XSD Schema (EDEN)' + title = 'ISO19139 XSD Schema (EDEN 2009-03-16)' @classmethod def is_valid(cls, xml): From ccbac9c3c59ef69e1d774044a57e9c59065c1e57 Mon Sep 17 00:00:00 2001 From: David Read Date: Wed, 7 Nov 2012 16:23:27 +0000 Subject: [PATCH 002/114] Get the validation XML to be included in the distribution. --- MANIFEST.in | 1 + ckanext/spatial/validation/validation.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index aa83cc5..3d4f670 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ recursive-include ckanext/spatial/templates * recursive-include ckanext/spatial/public * +recursive-include ckanext/spatial/validation/xml * recursive-include ckanext/spatial/public/ckanext/spatial/js/openlayers/ *.js recursive-include ckanext/spatial/public/ckanext/spatial/js/openlayers/ *.txt diff --git a/ckanext/spatial/validation/validation.py b/ckanext/spatial/validation/validation.py index b0e7ab9..8ee6679 100644 --- a/ckanext/spatial/validation/validation.py +++ b/ckanext/spatial/validation/validation.py @@ -171,7 +171,7 @@ class SchematronValidator(BaseValidator): class ConstraintsSchematron(SchematronValidator): name = 'constraints' - title = 'ISO19139 Table A.1 Constraints Schematron 1.3' + title = 'ISO19139 Table A.1 Constraints Schematron (Medin 1.3)' @classmethod def get_schematrons(cls): From 20e1a59227d2dbc196bbb7e72ff4bbedc2e6deb1 Mon Sep 17 00:00:00 2001 From: David Read Date: Wed, 5 Dec 2012 11:42:57 +0000 Subject: [PATCH 003/114] Added new Parslow Constraints Schematron to test. Added command to validate on the command-line. --- ckanext/spatial/commands/validation.py | 34 +++++++++++++++++++++++- ckanext/spatial/harvesters.py | 15 ++++++++--- ckanext/spatial/tests/test_validation.py | 10 +++---- ckanext/spatial/validation/validation.py | 11 ++++++++ 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/ckanext/spatial/commands/validation.py b/ckanext/spatial/commands/validation.py index ac81c7d..dc506eb 100644 --- a/ckanext/spatial/commands/validation.py +++ b/ckanext/spatial/commands/validation.py @@ -1,5 +1,6 @@ import sys import re +import os from pprint import pprint import logging @@ -15,10 +16,14 @@ class Validation(CkanCommand): Usage: validation report [package-name] Performs validation on the harvested metadata, either for all - packages or one specified. + packages or the one specified. validation report-csv .csv + Performs validation on all the harvested metadata in the db and + writes a report in CSV format to the given filepath. + validation file .xml + Performs validation on the given metadata file. ''' summary = __doc__.split('\n')[0] usage = __doc__ @@ -37,6 +42,8 @@ class Validation(CkanCommand): self.report() elif cmd == 'report-csv': self.report_csv() + elif cmd == 'file': + self.validate_file() else: print 'Command %s not recognized' % cmd @@ -60,6 +67,31 @@ class Validation(CkanCommand): for i, col_name in enumerate(report.column_names): print ' %s: %s' % (col_name, row[i]) + def validate_file(self): + from ckanext.spatial.harvesters import SpatialHarvester + + if len(self.args) > 2: + print 'Too many parameters %i' % len(self.args) + sys.exit(1) + if len(self.args) < 2: + print 'Not enough parameters %i' % len(self.args) + sys.exit(1) + metadata_filepath = self.args[1] + if not os.path.exists(metadata_filepath): + print 'Filepath %s not found' % metadata_filepath + sys.exit(1) + with open(metadata_filepath, 'rb') as f: + metadata_xml = f.read() + + validators = SpatialHarvester()._get_validator() + print 'Validators: %r' % validators.profiles + xml = etree.fromstring(metadata_xml.encode("utf-8")) + valid, errors = validators.is_valid(xml) + print 'Valid: %s' % valid + if not valid: + print 'Errors:' + print pprint(errors) + def report_csv(self): from ckanext.spatial.lib.reports import validation_report if len(self.args) != 2: diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 4393c11..47e9b12 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -267,11 +267,16 @@ class GeminiHarvester(SpatialHarvester): ]: extras[name] = gemini_values[name] + # Use-constraints can contain values which are: + # * free text + # * licence URL + # Store all values in extra['licence'] and if there is a + # URL in there, store that in extra['licence-url'] extras['licence'] = gemini_values.get('use-constraints', '') if len(extras['licence']): - license_url_extracted = self._extract_first_license_url(extras['licence']) - if license_url_extracted: - extras['licence_url'] = license_url_extracted + licence_url_extracted = self._extract_first_licence_url(extras['licence']) + if licence_url_extracted: + extras['licence_url'] = licence_url_extracted extras['access_constraints'] = gemini_values.get('limitations-on-public-access','') if gemini_values.has_key('temporal-extent-begin'): @@ -450,7 +455,9 @@ class GeminiHarvester(SpatialHarvester): counter = counter + 1 return None - def _extract_first_license_url(self,licences): + def _extract_first_licence_url(self, licences): + '''Given a list of pieces of licence info, hunt for the first one + which looks like a URL and return it. Otherwise returns None.''' for licence in licences: o = urlparse(licence) if o.scheme and o.netloc: diff --git a/ckanext/spatial/tests/test_validation.py b/ckanext/spatial/tests/test_validation.py index d437878..6a94cd0 100644 --- a/ckanext/spatial/tests/test_validation.py +++ b/ckanext/spatial/tests/test_validation.py @@ -42,7 +42,7 @@ class TestValidation: assert_in('\'{http://www.isotc211.org/2005/gmd}nosuchelement\': This element is not expected.', errors) def test_02_dataset_fail_constraints_schematron(self): - errors = self.get_validation_errors(validation.ConstraintsSchematron, + errors = self.get_validation_errors(validation.ConstraintsSchematron14, 'gemini2.1/validation/02_Dataset_Invalid_19139_Missing_Data_Format.xml') assert len(errors) > 0 assert_in('MD_Distribution / MD_Format: count(distributionFormat + distributorFormat) > 0', errors) @@ -57,9 +57,9 @@ class TestValidation: errs = self.get_validation_errors(validation.ISO19139EdenSchema, xml_filepath) assert not errs, 'ISO19139EdenSchema: ' + errs - errs = self.get_validation_errors(validation.ConstraintsSchematron, + errs = self.get_validation_errors(validation.ConstraintsSchematron14, xml_filepath) - assert not errs, 'ConstraintsSchematron: ' + errs + assert not errs, 'ConstraintsSchematron14: ' + errs errs = self.get_validation_errors(validation.Gemini2Schematron, xml_filepath) assert not errs, 'Gemini2Schematron: ' + errs @@ -75,7 +75,7 @@ class TestValidation: assert_in('\'{http://www.isotc211.org/2005/gmd}nosuchelement\': This element is not expected.', errors) def test_06_series_fail_constraints_schematron(self): - errors = self.get_validation_errors(validation.ConstraintsSchematron, + errors = self.get_validation_errors(validation.ConstraintsSchematron14, 'gemini2.1/validation/06_Series_Invalid_19139_Missing_Data_Format.xml') assert len(errors) > 0 assert_in('MD_Distribution / MD_Format: count(distributionFormat + distributorFormat) > 0', errors) @@ -97,7 +97,7 @@ class TestValidation: assert_in('\'{http://www.isotc211.org/2005/gmd}nosuchelement\': This element is not expected.', errors) def test_10_service_fail_constraints_schematron(self): - errors = self.get_validation_errors(validation.ConstraintsSchematron, + errors = self.get_validation_errors(validation.ConstraintsSchematron14, 'gemini2.1/validation/10_Service_Invalid_19139_Level_Description.xml') assert len(errors) > 0 assert_in("DQ_Scope: 'levelDescription' is mandatory if 'level' notEqual 'dataset' or 'series'.", errors) diff --git a/ckanext/spatial/validation/validation.py b/ckanext/spatial/validation/validation.py index 8ee6679..d89ec8e 100644 --- a/ckanext/spatial/validation/validation.py +++ b/ckanext/spatial/validation/validation.py @@ -179,6 +179,16 @@ class ConstraintsSchematron(SchematronValidator): "validation/xml/medin/ISOTS19139A1Constraints_v1.3.sch") as schema: return [cls.schematron(schema)] +class ConstraintsSchematron14(SchematronValidator): + name = 'constraints-1.4' + title = 'ISO19139 Table A.1 Constraints Schematron (Medin/Parslow 1.4)' + + @classmethod + def get_schematrons(cls): + with resource_stream("ckanext.spatial", + "validation/xml/medin/ISOTS19139A1Constraints_v1.4.sch") as schema: + return [cls.schematron(schema)] + class Gemini2Schematron(SchematronValidator): name = 'gemini2' @@ -193,6 +203,7 @@ class Gemini2Schematron(SchematronValidator): all_validators = (ISO19139Schema, ISO19139EdenSchema, ConstraintsSchematron, + ConstraintsSchematron14, Gemini2Schematron) From df884bdd3df7dea2a0863ac102fb49d509104ff4 Mon Sep 17 00:00:00 2001 From: David Read Date: Wed, 5 Dec 2012 12:05:45 +0000 Subject: [PATCH 004/114] Comments about on cardinality/multiplicity. --- ckanext/spatial/model/harvested_metadata.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index f6350c6..2942283 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -104,26 +104,40 @@ class MappedXmlElement(MappedXmlObject): return etree.tostring(element, pretty_print=False) def fix_multiplicity(self, values): + ''' + When a field contains multiple values, yet the spec says + it should contain only one, then return just the first value, + rather than a list. + + In the ISO19115 specification, multiplicity relates to: + * 'Association Cardinality' + * 'Obligation/Condition' & 'Maximum Occurence' + ''' if self.multiplicity == "0": + # 0 = None if values: raise Exception( "Values found for element '%s': %s" % (self.name, values)) else: return "" elif self.multiplicity == "1": + # 1 = Mandatory, maximum 1 = Exactly one if values: return values[0] else: raise Exception( "Value not found for element '%s'" % self.name) elif self.multiplicity == "*": + # * = 0..* = zero or more return values elif self.multiplicity == "0..1": + # 0..1 = Mandatory, maximum 1 = optional (zero or one) if values: return values[0] else: return "" elif self.multiplicity == "1..*": + # 1..* = one or more return values else: raise Exception( From 68f22147bc77c9826a98955d581f4defe091b072 Mon Sep 17 00:00:00 2001 From: David Read Date: Wed, 5 Dec 2012 15:01:16 +0000 Subject: [PATCH 005/114] Added lower level tests for bbox search (at the lib level), complementing the API level ones. --- ckanext/spatial/lib/__init__.py | 24 ++++++++ ckanext/spatial/plugin.py | 5 +- ckanext/spatial/tests/lib/test_spatial.py | 75 +++++++++++++++++++++++ ckanext/spatial/tests/scripts/postgis.sql | 2 +- 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 ckanext/spatial/tests/lib/test_spatial.py diff --git a/ckanext/spatial/lib/__init__.py b/ckanext/spatial/lib/__init__.py index 359f6ac..7701de2 100644 --- a/ckanext/spatial/lib/__init__.py +++ b/ckanext/spatial/lib/__init__.py @@ -38,6 +38,8 @@ def save_package_extent(package_id, geometry = None, srid = None): Will throw ValueError if the geometry object does not provide a geo interface. + The responsibility for calling model.Session.commit() is left to the + caller. ''' db_srid = int(config.get('ckan.spatial.srid', '4326')) @@ -74,6 +76,21 @@ def save_package_extent(package_id, geometry = None, srid = None): log.debug('Created new extent for package %s' % package_id) def validate_bbox(bbox_values): + ''' + Ensures a bbox is expressed in a standard dict. + + bbox_values may be: + a string: "-4.96,55.70,-3.78,56.43" + or a list [-4.96, 55.70, -3.78, 56.43] + or a list of strings ["-4.96", "55.70", "-3.78", "56.43"] + and returns a dict: + {'minx': -4.96, + 'miny': 55.70, + 'maxx': -3.78, + 'maxy': 56.43} + + Any problems and it returns None. + ''' if isinstance(bbox_values,basestring): bbox_values = bbox_values.split(',') @@ -93,6 +110,13 @@ def validate_bbox(bbox_values): return bbox def bbox_query(bbox,srid=None): + ''' + Performs a spatial query of a bounding box. + + bbox - bounding box dict + + Returns a list of package IDs. + ''' db_srid = int(config.get('ckan.spatial.srid', '4326')) diff --git a/ckanext/spatial/plugin.py b/ckanext/spatial/plugin.py index 7186828..c768a7e 100644 --- a/ckanext/spatial/plugin.py +++ b/ckanext/spatial/plugin.py @@ -55,7 +55,6 @@ class SpatialMetadata(SingletonPlugin): implements(IConfigurable, inherit=True) def configure(self, config): - if not config.get('ckan.spatial.testing',False): setup_model() @@ -67,6 +66,10 @@ class SpatialMetadata(SingletonPlugin): self.check_spatial_extra(package) def check_spatial_extra(self,package): + ''' + For a given package, looks at the spatial extent (as given in the + extra "spatial" in GeoJSON format) and records it in PostGIS. + ''' if not package.id: log.warning('Couldn\'t store spatial extent because no id was provided for the package') return diff --git a/ckanext/spatial/tests/lib/test_spatial.py b/ckanext/spatial/tests/lib/test_spatial.py new file mode 100644 index 0000000..4e530bf --- /dev/null +++ b/ckanext/spatial/tests/lib/test_spatial.py @@ -0,0 +1,75 @@ +from nose.tools import assert_equal + +from ckan import model +from ckan.lib.helpers import json +from ckan.logic.schema import default_create_package_schema +from ckan.logic.action.create import package_create +from ckan.lib.munge import munge_title_to_name +from ckanext.spatial.lib import validate_bbox, bbox_query, save_package_extent +from ckanext.spatial.tests.base import SpatialTestBase + +class TestValidateBbox: + bbox_dict = {'minx': -4.96, + 'miny': 55.70, + 'maxx': -3.78, + 'maxy': 56.43} + + def test_string(self): + res = validate_bbox("-4.96,55.70,-3.78,56.43") + assert_equal(res, self.bbox_dict) + + def test_list(self): + res = validate_bbox([-4.96, 55.70, -3.78, 56.43]) + assert_equal(res, self.bbox_dict) + + def test_bad(self): + res = validate_bbox([-4.96, 55.70, -3.78]) + assert_equal(res, None) + + def test_bad_2(self): + res = validate_bbox('random') + assert_equal(res, None) + +def bbox_2_geojson(bbox_dict): + return '{"type":"Polygon","coordinates":[[[%(minx)s, %(miny)s],[%(minx)s, %(maxy)s], [%(maxx)s, %(maxy)s], [%(maxx)s, %(miny)s], [%(minx)s, %(miny)s]]]}' % bbox_dict + +class TestBboxQuery(SpatialTestBase): + # fixtures and search have same y values + miny = 1 + maxy = 2 + # x values for the fixtures + fixtures_x = [(0, 1), (0, 3), (0, 4), (4, 5), (6, 7)] + + @classmethod + def setup_class(cls): + SpatialTestBase.setup_class() + for fixture_x in cls.fixtures_x: + bbox = cls.x_values_to_bbox(fixture_x) + bbox_geojson = bbox_2_geojson(bbox) + cls.create_package(name=munge_title_to_name(str(fixture_x)), + title=str(fixture_x), + extras=[{'key': 'spatial', + 'value': bbox_geojson}]) + + @classmethod + def create_package(cls, **package_dict): + context = {'model': model, + 'session': model.Session, + 'user': 'tester', + 'extras_as_string': True, + 'schema': default_create_package_schema(), + 'api_version': 2} + package_dict = package_create(context, package_dict) + return context.get('id') + + @classmethod + def x_values_to_bbox(cls, x_tuple): + return {'minx': x_tuple[0], 'maxx': x_tuple[1], + 'miny': cls.miny, 'maxy': cls.maxy} + + def test_query(self): + bbox_dict = self.x_values_to_bbox((2, 5)) + package_ids = [res.package_id for res in bbox_query(bbox_dict)] + package_titles = [model.Package.get(id_).title for id_ in package_ids] + assert_equal(set(package_titles), + set(('(0, 3)', '(0, 4)', '(4, 5)'))) diff --git a/ckanext/spatial/tests/scripts/postgis.sql b/ckanext/spatial/tests/scripts/postgis.sql index dfdedf5..b9ea072 100644 --- a/ckanext/spatial/tests/scripts/postgis.sql +++ b/ckanext/spatial/tests/scripts/postgis.sql @@ -1,5 +1,5 @@ ------------------------------------------------------------------- --- WARNING: This is probably the file you are looking for. +-- WARNING: This is probably NOT the file you are looking for. -- This file is intended to be used only during tests, you won't -- get a functional PostGIS database executing it. Please install -- PostGIS as described in the README. From 36905eed177c45ade560faec45a4b7a55f1059a1 Mon Sep 17 00:00:00 2001 From: David Read Date: Wed, 5 Dec 2012 15:02:27 +0000 Subject: [PATCH 006/114] Adding Parslow constraints schema previously missed. --- .../validation/xml/iso19139/readme.rst | 5 + .../validation/xml/iso19139eden/readme.rst | 12 + .../medin/ISOTS19139A1Constraints_v1.4.sch | 648 ++++++++++++++++++ 3 files changed, 665 insertions(+) create mode 100644 ckanext/spatial/validation/xml/iso19139/readme.rst create mode 100644 ckanext/spatial/validation/xml/iso19139eden/readme.rst create mode 100644 ckanext/spatial/validation/xml/medin/ISOTS19139A1Constraints_v1.4.sch diff --git a/ckanext/spatial/validation/xml/iso19139/readme.rst b/ckanext/spatial/validation/xml/iso19139/readme.rst new file mode 100644 index 0000000..0bcbe79 --- /dev/null +++ b/ckanext/spatial/validation/xml/iso19139/readme.rst @@ -0,0 +1,5 @@ +This is the ISO 19139 XSD Schema, for validating spatial metadata. It was downloaded from:: + + http://www.isotc211.org/2005/ + +It is assumed that copyright for the rest of the files in this directory and sub directories rests with ISO. diff --git a/ckanext/spatial/validation/xml/iso19139eden/readme.rst b/ckanext/spatial/validation/xml/iso19139eden/readme.rst new file mode 100644 index 0000000..532ef53 --- /dev/null +++ b/ckanext/spatial/validation/xml/iso19139eden/readme.rst @@ -0,0 +1,12 @@ +This is the EDEN version of the ISO 19139 XSD Schema, for validating spatial metadata. It was downloaded from:: + + http://eden.ign.fr/xsd/isotc211/isofull/20090316 + http://eden.ign.fr/xsd/isotc211/iso19119/20090316/ISO19139schemas-20090316.zip/view + +It is assumed that copyright for the rest of the files in this directory and sub directories rests with ISO and EDEN. + +Notes about this release from EDEN web page: + + ISO/TS 19139 based XML Schemas, i.e. consistent grouping of ISO/TS 19139 based XML Schema implementations of the ISO/TC 211 standards. + + 2009-03-16 release includes the XML Schema implementation of ISO 19115 (2009-03-16), ISO 19119 (2009-03-16), ISO 19115-2 (2009-03-16) and ISO 19110 (2009-03-16). It does not include ISO 19126 XML Schema Implementation. Note that all 2009-03-16 releases are conformant with OGC published GML 3.2.1 schemas from OGC 07-036 (schemas repository http://schemas.opengis.net/). diff --git a/ckanext/spatial/validation/xml/medin/ISOTS19139A1Constraints_v1.4.sch b/ckanext/spatial/validation/xml/medin/ISOTS19139A1Constraints_v1.4.sch new file mode 100644 index 0000000..526ab82 --- /dev/null +++ b/ckanext/spatial/validation/xml/medin/ISOTS19139A1Constraints_v1.4.sch @@ -0,0 +1,648 @@ + + + + + + + + + + + ISO / TS 19139 Table A.1 Constraints + + + This Schematron schema is designed to test the constraints presented in ISO / TS 19139 Table A.1. + + + + + + + + + + + + + + + + + + + + + ISO / TS 19139 Table A.1 Row 1 + language: documented if not defined by the encoding standard + + + + + + + ISO / TS 19139 Table A.1 Row 2 + + characterSet: documented if ISO/IEC 10646 not used and not defined by the encoding standard + + + + + + + + ISO / TS 19139 Table A.1 Row 3 + + characterSet: documented if ISO/IEC 10646 is not used + + + + + + + + ISO / TS 19139 Table A.1 Row 4 + + MD_Metadata.hierarchyLevel = 'dataset' implies count (extent.geographicElement.EX_GeograpicBoundingBox) + + count(extent.geographicElement.EX_GeographicDescription) >= 1 + + + + MD_DataIdentification: MD_Metadata.hierarchyLevel = 'dataset' implies count (extent.geographicElement.EX_GeographicBoundingBox) + + count (extent.geographicElement.EX_GeographicDescription) >=1 + + + + + + + + + ISO / TS 19139 Table A.1 Row 5 + + MD_Metadata.hierarchyLevel notEqual 'dataset' implies topicCategory is not mandatory + + + + MD_DataIdentification: The topicCategory element is mandatory if hierarchyLevel is dataset. + + + + + + + + + ISO / TS 19139 Table A.1 Row 6 + + Either 'aggregateDataSetName' or 'aggregateDataSetIdentifier' must be documented + + + + MD_AggregateInformation: Either 'aggregateDataSetName' or 'aggregateDataSetIdentifier' must be documented. + + + + + + + + + ISO / TS 19139 Table A.1 Row 7 + + otherConstraints: documented if accessConstraints = 'otherRestrictions' + + + + MD_LegalConstraints: otherConstraints: documented if accessConstraints = 'otherRestrictions'. + + + MD_LegalConstraints: otherConstraints: documented if useConstraints = 'otherRestrictions' + + + + + + + + + + + + + + ISO / TS 19139 Table A.1 Row 8 + + 'report' or 'lineage' role is mandatory if scope.DQ_Scope.level = 'dataset' + + + + DQ_DataQuality: 'report' or 'lineage' role is mandatory if scope.DQ_Scope.level = 'dataset' + + + + + + + + + ISO / TS 19139 Table A.1 Row 9 + + 'levelDescription' is mandatory if 'level' notEqual 'dataset' or 'series' + + + + DQ_Scope: 'levelDescription' is mandatory if 'level' notEqual 'dataset' or 'series'. + + + + + + + + + ISO / TS 19139 Table A.1 Row 10 + + If (count(source) + count(processStep) = 0) and (DQ_DataQuality.scope.level = 'dataset' + or 'series') then statement is mandatory + + + + LI_Lineage: If (count(source) + count(processStep) = 0) and (DQ_DataQuality.scope.level = 'dataset' + or 'series') then statement is mandatory. + + + + + + + + + ISO / TS 19139 Table A.1 Rows 11 and 12 + + Row 11 - 'source' role is mandatory if LI_Lineage.statement and 'processStep' role are not documented + + + Row 12 - 'processStep' role is mandatory if LI_Lineage.statement and 'source' role are not documented + + + + LI_Lineage: 'source' role is mandatory if LI_Lineage.statement and 'processStep' role are not documented. + LI_Lineage: 'processStep' role is mandatory if LI_Lineage.statement and 'source' role are not documented. + + + + + + + + + ISO / TS 19139 Table A.1 Row 13 + + 'description' is mandatory if 'sourceExtent' is not documented + + + + LI_Source: 'description' is mandatory if 'sourceExtent' is not documented. + + + + + + + + + ISO / TS 19139 Table A.1 Row 14 + + 'sourceExtent' is mandatory if 'description' is not documented + + + + LI_Source: 'sourceExtent' is mandatory if 'description' is not documented. + + + + + + + + + ISO / TS 19139 Table A.1 Row 15 + + 'checkPointDescription' is mandatory if 'checkPointAvailability' = 1 + + + + MD_Georectified: 'checkPointDescription' is mandatory if 'checkPointAvailability' = 1 + + + + + + + + + ISO / TS 19139 Table A.1 Row 16 + + 'units' is mandatory if 'maxValue' or 'minValue' are provided + + + + MD_Band: 'units' is mandatory if 'maxValue' or 'minValue' are provided. + + + + + + + + + ISO / TS 19139 Table A.1 Row 17 + + 'densityUnits' is mandatory if 'density' is provided + + + + MD_Medium: 'densityUnits' is mandatory if 'density' is provided. + + + + + + + + + ISO / TS 19139 Table A.1 Row 18 + + count(distributionFormat + distributorFormat) > 0 + + + + MD_Distribution / MD_Format: count(distributionFormat + distributorFormat) > 0. + + + + + + + + + ISO / TS 19139 Table A.1 Row 19 + + if 'dataType' notEqual 'codelist', 'enumeration' or 'codeListElement' then 'obligation', + 'maximumOccurrence' and 'domainValue' are mandatory + + + + MD_ExtendedElementInformation: if 'dataType' notEqual 'codelist', + 'enumeration' or 'codelistElement' then 'obligation' is mandatory. + + + MD_ExtendedElementInformation: if 'dataType' notEqual 'codelist', + 'enumeration' or 'codelistElement' then 'maximumOccurence' is mandatory. + + + MD_ExtendedElementInformation: if 'dataType' notEqual 'codelist', + 'enumeration' or 'codelistElement' then 'domainValue' is mandatory. + + + + + + + + + + + + + + + + + + + + + + ISO / TS 19139 Table A.1 Row 20 + + if 'obligation' = 'conditional' then 'condition' is mandatory + + + + MD_ExtendedElementInformation: if 'obligation' = 'conditional' then 'condition' is mandatory + + + + + + + + + + + + + ISO / TS 19139 Table A.1 Row 21 + + if 'dataType' = 'codeListElement' then 'domainCode' is mandatory + + + + MD_ExtendedElementInformation: if 'dataType' = 'codeListElement' then 'domainCode' is mandatory. + + + + + + + + + + + + + ISO / TS 19139 Table A.1 Row 22 + + if 'dataType' notEqual 'codeListElement' then 'shortName' is mandatory + + + + MD_ExtendedElementInformation: if 'dataType' notEqual 'codeListElement' then 'shortName' is mandatory. + + + + + + + + + + + + + ISO / TS 19139 Table A.1 Row 23 + + count(description + geographicElement + temporalElement + verticalElement) > 0 + + + + EX_Extent: count(description + geographicElement + temporalExtent + verticalElement) > 0 + + + + + + + + + ISO / TS 19139 Table A.1 Row 24 + + count(individualName + organisationName + positionName) > 0 + + + + count(individualName + organisationName + positionName) > 0 + + + + + + + + + ISO / TS 19139 Table A.1 Row 25 + + Distance: the UoM element of the Distance Type must be instantiated using the UomLength_PropertyType + + + + + + + + + + + + ISO / TS 19139 Table A.1 Row 26 + + Length: The UoM element of the Length Type must be instantiated using the UomLength_PropertyType + + + + + + + + + + + + ISO / TS 19139 Table A.1 Row 27 + + Scale: The UoM element of the Scale Type must be instantiated using the UomScale_PropertyType + + + + + + + + + + + + ISO / TS 19139 Table A.1 Row 28 + + Angle: The UoM element of the Angle Type must be instantiated using the UomAngle_PropertyType + + + + + + + + + + + + Element Values or Nil Reason Attributes + + + The '' element has no child elements. + + + + + + + + + + + + + The element must have a value or a Nil Reason. + + + + + + + + + + The '//' element must have a uom attribute. + + + + + + + + + The '' element should have a value. + + + + + + + + + + At least organisation name or individual name must be provided. + + + + + One or more email addresses must be supplied. + + + + + From 6fcbf878c2a4f5170c457539a9b53deb1d27d076 Mon Sep 17 00:00:00 2001 From: David Read Date: Thu, 6 Dec 2012 18:17:45 +0000 Subject: [PATCH 007/114] Spatial query can now be ordered. Does not play nicely with SOLR options - just uses that to get the facets counts and return each result. Have added performance tests for two alternative queries. --- ckanext/spatial/lib/__init__.py | 57 ++++++++++++++++++--- ckanext/spatial/plugin.py | 47 +++++++++++++++--- ckanext/spatial/tests/lib/test_spatial.py | 60 +++++++++++++++++++---- 3 files changed, 142 insertions(+), 22 deletions(-) diff --git a/ckanext/spatial/lib/__init__.py b/ckanext/spatial/lib/__init__.py index 7701de2..05b0c79 100644 --- a/ckanext/spatial/lib/__init__.py +++ b/ckanext/spatial/lib/__init__.py @@ -109,15 +109,13 @@ def validate_bbox(bbox_values): return bbox -def bbox_query(bbox,srid=None): +def _bbox_2_wkt(bbox, srid): ''' - Performs a spatial query of a bounding box. + Given a bbox dictionary, return a WKTSpatialElement, transformed + into the database\'s CRS if necessary. - bbox - bounding box dict - - Returns a list of package IDs. + returns e.g. WKTSpatialElement("POLYGON ((2 0, 2 1, 7 1, 7 0, 2 0))", 4326) ''' - db_srid = int(config.get('ckan.spatial.srid', '4326')) bbox_template = Template('POLYGON (($minx $miny, $minx $maxy, $maxx $maxy, $maxx $miny, $minx $miny))') @@ -132,11 +130,56 @@ def bbox_query(bbox,srid=None): input_geometry = functions.transform(WKTSpatialElement(wkt,srid),db_srid) else: input_geometry = WKTSpatialElement(wkt,db_srid) + return input_geometry + +def bbox_query(bbox,srid=None): + ''' + Performs a spatial query of a bounding box. + + bbox - bounding box dict + + Returns a query object of PackageExtents, which each reference a package + by ID. + ''' + + input_geometry = _bbox_2_wkt(bbox, srid) extents = Session.query(PackageExtent) \ .filter(PackageExtent.package_id==Package.id) \ .filter(PackageExtent.the_geom.intersects(input_geometry)) \ .filter(Package.state==u'active') - return extents +def bbox_query_ordered(bbox, srid=None): + ''' + Performs a spatial query of a bounding box. Returns packages in order + of how similar the data\'s bounding box is to the search box (best first). + + bbox - bounding box dict + + Returns a query object of PackageExtents, which each reference a package + by ID. + ''' + + input_geometry = _bbox_2_wkt(bbox, srid) + + params = {'query_bbox': str(input_geometry), + 'query_srid': input_geometry.srid} + + # First get the area of the query box + sql = "SELECT ST_Area(GeomFromText(:query_bbox, :query_srid));" + params['search_area'] = Session.execute(sql, params).fetchone()[0] + + # Uses spatial ranking method from "USGS - 2006-1279" (Lanfear) + sql = """SELECT ST_AsBinary(package_extent.the_geom) AS package_extent_the_geom, + POWER(ST_Area(ST_Intersection(package_extent.the_geom, GeomFromText(:query_bbox, :query_srid))),2)/ST_Area(package_extent.the_geom)/:search_area as spatial_ranking, + package_extent.package_id AS package_id + FROM package_extent, package + WHERE package_extent.package_id = package.id + AND ST_Intersects(package_extent.the_geom, GeomFromText(:query_bbox, :query_srid)) + AND package.state = 'active' + ORDER BY spatial_ranking desc""" + extents = Session.execute(sql, params).fetchall() + log.debug('Spatial results: %r', + [('%.2f' % extent.spatial_ranking, extent.package_id) for extent in extents[:20]]) + return extents diff --git a/ckanext/spatial/plugin.py b/ckanext/spatial/plugin.py index c768a7e..c190f52 100644 --- a/ckanext/spatial/plugin.py +++ b/ckanext/spatial/plugin.py @@ -8,7 +8,7 @@ from genshi.filters import Transformer import ckan.lib.helpers as h -from ckan.lib.search import SearchError +from ckan.lib.search import SearchError, PackageSearchQuery from ckan.lib.helpers import json from ckan import model @@ -23,10 +23,9 @@ from ckan.logic import ValidationError import html -from ckanext.spatial.lib import save_package_extent,validate_bbox, bbox_query +from ckanext.spatial.lib import save_package_extent,validate_bbox, bbox_query, bbox_query_ordered from ckanext.spatial.model.package_extent import setup as setup_model - log = getLogger(__name__) def package_error_summary(error_dict): @@ -130,9 +129,33 @@ class SpatialQuery(SingletonPlugin): if not bbox: raise SearchError('Wrong bounding box provided') - extents = bbox_query(bbox) + if search_params['sort'] == 'spatial desc': + if search_params['q'] or search_params['fq']: + raise SearchError('Spatial ranking cannot be mixed with other search parameters') + # ...because it is too inefficient to use SOLR to filter + # results and return the entire set to this class and + # after_search do the sorting and paging. + extents = bbox_query_ordered(bbox) + are_no_results = not extents + search_params['extras']['ext_rows'] = search_params['rows'] + search_params['extras']['ext_start'] = search_params['start'] + # this SOLR query needs to return no actual results since + # they are in the wrong order anyway. We just need this SOLR + # query to get the count and facet counts. + rows = 0 + search_params['sort'] = None # SOLR should not sort. + # Store the rankings of the results for this page, so for + # after_search to construct the correctly sorted results + rows = search_params['extras']['ext_rows'] = search_params['rows'] + start = search_params['extras']['ext_start'] = search_params['start'] + search_params['extras']['ext_spatial'] = [ + (extent.package_id, extent.spatial_ranking) \ + for extent in extents[start:start+rows]] + else: + extents = bbox_query(bbox) + are_no_results = extents.count() == 0 - if extents.count() == 0: + if are_no_results: # We don't need to perform the search search_params['abort_search'] = True else: @@ -140,7 +163,7 @@ class SpatialQuery(SingletonPlugin): # of datasets within the bbox bbox_query_ids = [extent.package_id for extent in extents] - q = search_params.get('q','') + q = search_params.get('q','').strip() or '""' new_q = '%s AND ' % q if q else '' new_q += '(%s)' % ' OR '.join(['id:%s' % id for id in bbox_query_ids]) @@ -148,6 +171,18 @@ class SpatialQuery(SingletonPlugin): return search_params + def after_search(self, search_results, search_params): + if search_params.get('extras', {}).get('ext_spatial'): + # Apply the spatial sort + querier = PackageSearchQuery() + pkgs = [] + for package_id, spatial_ranking in search_params['extras']['ext_spatial']: + # get package from SOLR + pkg = querier.get_index(package_id)['data_dict'] + pkgs.append(json.loads(pkg)) + search_results['results'] = pkgs + return search_results + class SpatialQueryWidget(SingletonPlugin): implements(IGenshiStreamFilter) diff --git a/ckanext/spatial/tests/lib/test_spatial.py b/ckanext/spatial/tests/lib/test_spatial.py index 4e530bf..d694877 100644 --- a/ckanext/spatial/tests/lib/test_spatial.py +++ b/ckanext/spatial/tests/lib/test_spatial.py @@ -1,3 +1,6 @@ +import time +import random + from nose.tools import assert_equal from ckan import model @@ -5,7 +8,7 @@ from ckan.lib.helpers import json from ckan.logic.schema import default_create_package_schema from ckan.logic.action.create import package_create from ckan.lib.munge import munge_title_to_name -from ckanext.spatial.lib import validate_bbox, bbox_query, save_package_extent +from ckanext.spatial.lib import validate_bbox, bbox_query, bbox_query_ordered, bbox_query_ordered_2 from ckanext.spatial.tests.base import SpatialTestBase class TestValidateBbox: @@ -33,12 +36,10 @@ class TestValidateBbox: def bbox_2_geojson(bbox_dict): return '{"type":"Polygon","coordinates":[[[%(minx)s, %(miny)s],[%(minx)s, %(maxy)s], [%(maxx)s, %(maxy)s], [%(maxx)s, %(miny)s], [%(minx)s, %(miny)s]]]}' % bbox_dict -class TestBboxQuery(SpatialTestBase): - # fixtures and search have same y values - miny = 1 - maxy = 2 - # x values for the fixtures - fixtures_x = [(0, 1), (0, 3), (0, 4), (4, 5), (6, 7)] +class SpatialQueryTestBase(SpatialTestBase): + '''Base class for tests of spatial queries''' + miny = 0 + maxy = 1 @classmethod def setup_class(cls): @@ -61,15 +62,56 @@ class TestBboxQuery(SpatialTestBase): 'api_version': 2} package_dict = package_create(context, package_dict) return context.get('id') - + @classmethod def x_values_to_bbox(cls, x_tuple): return {'minx': x_tuple[0], 'maxx': x_tuple[1], 'miny': cls.miny, 'maxy': cls.maxy} - + +class TestBboxQuery(SpatialQueryTestBase): + # x values for the fixtures + fixtures_x = [(0, 1), (0, 3), (0, 4), (4, 5), (6, 7)] + def test_query(self): bbox_dict = self.x_values_to_bbox((2, 5)) package_ids = [res.package_id for res in bbox_query(bbox_dict)] package_titles = [model.Package.get(id_).title for id_ in package_ids] assert_equal(set(package_titles), set(('(0, 3)', '(0, 4)', '(4, 5)'))) + +class TestBboxQueryOrdered(SpatialQueryTestBase): + # x values for the fixtures + fixtures_x = [(0, 9), (1, 8), (2, 7), (3, 6), (4, 5), + (8, 9)] + + def test_query(self): + bbox_dict = self.x_values_to_bbox((2, 7)) + q = bbox_query_ordered(bbox_dict) + package_ids = [res.package_id for res in q] + package_titles = [model.Package.get(id_).title for id_ in package_ids] + # check the right items are returned + assert_equal(set(package_titles), + set(('(0, 9)', '(1, 8)', '(2, 7)', '(3, 6)', '(4, 5)'))) + # check the order is good + assert_equal(package_titles, + ['(2, 7)', '(1, 8)', '(3, 6)', '(0, 9)', '(4, 5)']) + + +class TestBboxQueryPerformance(SpatialQueryTestBase): + # x values for the fixtures + fixtures_x = [(random.uniform(0, 3), random.uniform(3,9)) \ + for x in xrange(10)] # increase the number to 1000 say + + def test_query(self): + bbox_dict = self.x_values_to_bbox((2, 7)) + t0 = time.time() + q = bbox_query(bbox_dict) + t1 = time.time() + print 'bbox_query took: ', t1-t0 + + def test_query_ordered(self): + bbox_dict = self.x_values_to_bbox((2, 7)) + t0 = time.time() + q = bbox_query_ordered(bbox_dict) + t1 = time.time() + print 'bbox_query_ordered took: ', t1-t0 From 348c1c4dc13494b54a9742cf160b8b3905609641 Mon Sep 17 00:00:00 2001 From: David Read Date: Wed, 16 Jan 2013 13:08:28 +0000 Subject: [PATCH 008/114] Add XSL for converting Gemini XML to nice HTML, used in controllers/api.py. --- ckanext/spatial/controllers/api.py | 4 +- .../spatial/gemini2-html-stylesheet.xsl | 406 ++++++++++++++++++ 2 files changed, 408 insertions(+), 2 deletions(-) create mode 100644 ckanext/spatial/templates/ckanext/spatial/gemini2-html-stylesheet.xsl diff --git a/ckanext/spatial/controllers/api.py b/ckanext/spatial/controllers/api.py index 692bc1c..5b7973d 100644 --- a/ckanext/spatial/controllers/api.py +++ b/ckanext/spatial/controllers/api.py @@ -68,8 +68,8 @@ class HarvestMetadataApiController(BaseApiController): abort(404) ## optimise -- read transform only once and compile rather ## than at each request - with resource_stream("ckanext.inspire", - "xml/gemini2-html-stylesheet.xsl") as style: + with resource_stream("ckanext.spatial", + "templates/ckanext/spatial/gemini2-html-stylesheet.xsl") as style: style_xml = etree.parse(style) transformer = etree.XSLT(style_xml) xml = etree.parse(StringIO(obj.content.encode("utf-8"))) diff --git a/ckanext/spatial/templates/ckanext/spatial/gemini2-html-stylesheet.xsl b/ckanext/spatial/templates/ckanext/spatial/gemini2-html-stylesheet.xsl new file mode 100644 index 0000000..771bd24 --- /dev/null +++ b/ckanext/spatial/templates/ckanext/spatial/gemini2-html-stylesheet.xsl @@ -0,0 +1,406 @@ + + + + + + + + + GEMINI record about <xsl:value-of select="gmd:MD_Metadata/gmd:identificationInfo/*/gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString"/> + + + GEMINI metadata record with GUID: + + + + + + + + + + + + + + + + + + + + + +

Identification

+

Title

+

+ +

+ +

Alternative title(s)

+ +

+ +

+
+
+

Abstract

+

+ +

+

Resource type

+

+ +

+ +

Resource locator

+

+ +

+ +

Unique resource identifier

+

code

+

+ +

+

codeSpace

+

+ +

+ +

Coupled resource

+ +

+ +

+
+
+

Dataset language

+

+ +

+

Spatial reference system

+ +

authority code

+

+ +

+
+

code identifying the spatial reference system

+

+ +

+ +

Additional information source

+

+ +

+
+ +

Classification of spatial data and services

+

Topic category

+ +

+ +

+
+ +

Spatial data service type

+

+ +

+
+ +

Keywords

+ +

Keyword set

+

keyword value

+ +

+ +

+
+ +

originating controlled vocabulary

+ +
+
+ +

Geographic location

+

+

West bounding longitude

+

+ +

+

East bounding longitude

+

+ +

+

North bounding latitude

+

+ +

+

South bounding latitude

+

+ +

+ +

Extent

+ +

Extent group

+

authority code

+

+ +

+

code identifying the extent

+

+ +

+
+
+ +

Vertical extent information

+

Minimum value

+

+ +

+

Maximum value

+

+ +

+

Coordinate reference system

+ +

authority code

+

+ +

+

code identifying the coordinate reference system

+

+ +

+
+ +

Temporal reference

+

Temporal extent

+

Begin position

+

+ +

+

End position

+

+ +

+

Dataset reference date

+ +

Frequency of update

+

+ +

+ + + +

Quality and validity

+

Lineage

+

+ +

+ +

Spatial resolution

+

+ metres

+
+ +

Equivalent scale

+

1: +

+
+
+ +

Conformity

+ +

Conformity report

+

specification

+

+ +

+

degree

+

+ +

+

explanation

+

+ +

+
+

Data format

+

name of format

+

+ +

+

version of format

+

+ +

+ +

Constraints related to access and use

+ +

Constraint set

+ +

Use constraints

+

+ +

+
+ +

Limitations on public access

+

+ +

+
+
+ +

Responsible organisations

+ +

Responsible party

+ +
+ +

Metadata on metadata

+

Metadata point of contact

+

+ +

+

Metadata date

+

+ +

+

Metadata language

+ +
+ + + +

title

+ +

reference date

+ +
+ + +
date type
+

+ +

+
effective date
+

+ +

+
+ + + +

+ + + + +

+ + +

protocol: +

+
+ +

applicationProfile: +

+
+ +

name: +

+
+ +

description: +

+
+ +

function: +

+
+
+ + + + + + + +
contact position
+

+ +

+
+
organisation name
+

+ +

+ + +
full postal address
+ +
+ +
telephone number
+

+ +

+
+ +
facsimile number
+

+ +

+
+
email address
+ +

+ + mailto: + + +

+ +
web address
+ + + +
+
responsible party role
+

+ +

+
+ + + + + + +

+ +

+
+
From 7841691fc3ec61a02d7902e7c2c59db4d85d610a Mon Sep 17 00:00:00 2001 From: David Read Date: Wed, 16 Jan 2013 13:10:32 +0000 Subject: [PATCH 009/114] More debug logging added to WAF harvester. --- .gitignore | 1 + README.rst | 2 +- ckanext/spatial/harvesters.py | 16 +++++++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 11e5c7f..39f7065 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ syntax: glob *.egg-info *.swp *~ +dist diff --git a/README.rst b/README.rst index 0a82c83..7e1db6f 100644 --- a/README.rst +++ b/README.rst @@ -12,7 +12,7 @@ The following plugins are currently available: * WMS Preview - a Web Map Service (WMS) previewer (`wms_preview`). * CSW Server - a basic CSW server - to server metadata from the CKAN instance (`cswserver`) * GEMINI Harvesters - for importing INSPIRE-style metadata into CKAN (`gemini_csw_harvester`, `gemini_doc_harvester`, `gemini_waf_harvester`) -* Harvest Metadata API - a way for a user to view the harvested metadata XML, either as a raw file or styled to view in a web browser. (`inspire_api`) +* Harvest Metadata API - a way for a user to view the harvested metadata XML, either as a raw file or styled to view in a web browser. (`spatial_harvest_metadata_api`) These libraries: * CSW Client - a basic client for accessing a CSW server diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 47e9b12..3f16542 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -21,6 +21,7 @@ import sys import uuid import os import logging +import difflib from lxml import etree from pylons import config @@ -232,7 +233,11 @@ class GeminiHarvester(SpatialHarvester): else: if last_harvested_object.content != self.obj.content and \ last_harvested_object.metadata_modified_date == self.obj.metadata_modified_date: - raise Exception('The contents of document with GUID %s changed, but the metadata date has not been updated' % gemini_guid) + diff_generator = difflib.HtmlDiff().make_table( + last_harvested_object.content.split('\n'), + self.obj.content.split('\n')) + diff = '\n'.join([line for line in diff_generator]) + raise Exception('The contents of document with GUID %s changed, but the metadata date has not been updated.\nDiff:\n%s' % (gemini_guid, diff)) else: # The content hasn't changed, no need to update the package log.info('Document with GUID %s unchanged, skipping...' % (gemini_guid)) @@ -241,7 +246,6 @@ class GeminiHarvester(SpatialHarvester): log.info('No package with GEMINI guid %s found, let''s create one' % gemini_guid) extras = { - 'published_by': self.obj.source.publisher_id or '', 'UKLP': 'True', 'harvest_object_id': self.obj.id } @@ -783,7 +787,7 @@ class GeminiWafHarvester(GeminiHarvester, SingletonPlugin): if len(ids) > 0: return ids else: - self._save_gather_error('Couldn''t find any links to metadata files', + self._save_gather_error('Couldn\'t find any links to metadata files', harvest_job) return None @@ -809,19 +813,25 @@ class GeminiWafHarvester(GeminiHarvester, SingletonPlugin): if not url: continue if '?' in url: + log.debug('Ignoring link in WAF because it has "?": %s', url) continue if '/' in url: + log.debug('Ignoring link in WAF because it has "/": %s', url) continue if '#' in url: + log.debug('Ignoring link in WAF because it has "#": %s', url) continue if 'mailto:' in url: + log.debug('Ignoring link in WAF because it has "mailto:": %s', url) continue + log.debug('WAF contains file: %s', url) urls.append(url) base_url = base_url.rstrip('/').split('/') if 'index' in base_url[-1]: base_url.pop() base_url = '/'.join(base_url) base_url += '/' + log.debug('WAF base URL: %s', base_url) return [base_url + i for i in urls] From 1622223a38cede807c9ec496df9e7f4ffba72aa5 Mon Sep 17 00:00:00 2001 From: David Read Date: Wed, 16 Jan 2013 22:22:39 +0000 Subject: [PATCH 010/114] [xs] Improve docstrings and error messages. --- ckanext/spatial/harvesters.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 3f16542..7170b2e 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -243,7 +243,7 @@ class GeminiHarvester(SpatialHarvester): log.info('Document with GUID %s unchanged, skipping...' % (gemini_guid)) return None else: - log.info('No package with GEMINI guid %s found, let''s create one' % gemini_guid) + log.info('No package with GEMINI guid %s found, let\'s create one' % gemini_guid) extras = { 'UKLP': 'True', @@ -525,9 +525,21 @@ class GeminiHarvester(SpatialHarvester): return package_dict def get_gemini_string_and_guid(self,content,url=None): + '''From a string buffer containing Gemini XML, return the tree + under gmd:MD_Metadata and the GUID for it. + + During the process it does validation: + * XML validation which may cause it to store gather_errors + * GeminiDocument multiplicity checks which may raise Exception. + + :param content: string containing Gemini XML + :param url: string giving info about the location of the XML to be + used only in validation errors + :returns: (gemini_string, gemini_guid) + ''' xml = etree.fromstring(content) - # The validator and GeminiDocument don't like the container + # The validator and GeminiDocument don\'t like the container metadata_tag = '{http://www.isotc211.org/2005/gmd}MD_Metadata' if xml.tag == metadata_tag: gemini_xml = xml @@ -804,7 +816,7 @@ class GeminiWafHarvester(GeminiHarvester, SingletonPlugin): parser = etree.HTMLParser() tree = etree.fromstring(content, parser=parser) except Exception, inst: - msg = 'Couldn''t parse content into a tree: %s: %s' \ + msg = 'Couldn\'t parse content into a tree: %s: %s' \ % (inst, content) raise Exception(msg) urls = [] From 70c3eccdf519213004c9bbe5efe3f4b6ba48ad4e Mon Sep 17 00:00:00 2001 From: David Read Date: Mon, 21 Jan 2013 17:22:24 +0000 Subject: [PATCH 011/114] Relaxed "Multiplicity Check" so that it does not raise Exceptions any more - just log errors. This is because they are simply duplicates of the Gemini Schematron. Adria agreed these will be deleted anyway in 2.0. --- ckanext/spatial/commands/validation.py | 27 +- ckanext/spatial/model/harvested_metadata.py | 21 +- ckanext/spatial/tests/model/__init__.py | 7 + .../tests/model/test_harvested_metadata.py | 34 ++ .../test_package_extent.py} | 0 .../model/xml/FCSConservancyPolygons.xml | 524 ++++++++++++++++++ .../tests/model/xml/gemini_dataset.xml | 498 +++++++++++++++++ 7 files changed, 1098 insertions(+), 13 deletions(-) create mode 100644 ckanext/spatial/tests/model/__init__.py create mode 100644 ckanext/spatial/tests/model/test_harvested_metadata.py rename ckanext/spatial/tests/{test_model.py => model/test_package_extent.py} (100%) create mode 100644 ckanext/spatial/tests/model/xml/FCSConservancyPolygons.xml create mode 100644 ckanext/spatial/tests/model/xml/gemini_dataset.xml diff --git a/ckanext/spatial/commands/validation.py b/ckanext/spatial/commands/validation.py index dc506eb..6d561b0 100644 --- a/ckanext/spatial/commands/validation.py +++ b/ckanext/spatial/commands/validation.py @@ -69,6 +69,7 @@ class Validation(CkanCommand): def validate_file(self): from ckanext.spatial.harvesters import SpatialHarvester + from ckanext.spatial.model import GeminiDocument if len(self.args) > 2: print 'Too many parameters %i' % len(self.args) @@ -85,12 +86,36 @@ class Validation(CkanCommand): validators = SpatialHarvester()._get_validator() print 'Validators: %r' % validators.profiles - xml = etree.fromstring(metadata_xml.encode("utf-8")) + try: + xml_string = metadata_xml.encode("utf-8") + except UnicodeDecodeError, e: + print 'ERROR: Unicode Error reading file \'%s\': %s' % \ + (metadata_filepath, e) + sys.exit(1) + #import pdb; pdb.set_trace() + xml = etree.fromstring(xml_string) + + # XML validation valid, errors = validators.is_valid(xml) + + # CKAN read of values + if valid: + try: + gemini_document = GeminiDocument(xml_string) + gemini_values = gemini_document.read_values() + except Exception, e: + valid = False + errors.append('CKAN exception reading values from GeminiDocument: %s' % e) + + print '***************' + print 'Summary' + print '***************' + print 'File: \'%s\'' % metadata_filepath print 'Valid: %s' % valid if not valid: print 'Errors:' print pprint(errors) + print '***************' def report_csv(self): from ckanext.spatial.lib.reports import validation_report diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index 2942283..6ce0928 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -116,17 +116,14 @@ class MappedXmlElement(MappedXmlObject): if self.multiplicity == "0": # 0 = None if values: - raise Exception( - "Values found for element '%s': %s" % (self.name, values)) - else: - return "" + log.warn("Values found for element '%s' when multiplicity should be 0: %s", self.name, values) + return "" elif self.multiplicity == "1": # 1 = Mandatory, maximum 1 = Exactly one - if values: - return values[0] - else: - raise Exception( - "Value not found for element '%s'" % self.name) + if not values: + log.warn("Value not found for element '%s'" % self.name) + return '' + return values[0] elif self.multiplicity == "*": # * = 0..* = zero or more return values @@ -140,9 +137,9 @@ class MappedXmlElement(MappedXmlObject): # 1..* = one or more return values else: - raise Exception( - "Can't fix element values for multiplicity '%s'." % \ - self.multiplicity) + log.warning('Multiplicity not specified for element: %s', + self.name) + return values class GeminiElement(MappedXmlElement): diff --git a/ckanext/spatial/tests/model/__init__.py b/ckanext/spatial/tests/model/__init__.py new file mode 100644 index 0000000..2e2033b --- /dev/null +++ b/ckanext/spatial/tests/model/__init__.py @@ -0,0 +1,7 @@ +# this is a namespace package +try: + import pkg_resources + pkg_resources.declare_namespace(__name__) +except ImportError: + import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/ckanext/spatial/tests/model/test_harvested_metadata.py b/ckanext/spatial/tests/model/test_harvested_metadata.py new file mode 100644 index 0000000..04063c2 --- /dev/null +++ b/ckanext/spatial/tests/model/test_harvested_metadata.py @@ -0,0 +1,34 @@ +import os + +from nose.tools import assert_equal + +from ckanext.spatial.model import GeminiDocument + +def open_xml_fixture(xml_filename): + xml_filepath = os.path.join(os.path.dirname(__file__), + 'xml', + xml_filename) + with open(xml_filepath, 'rb') as f: + xml_string_raw = f.read() + + try: + xml_string = xml_string_raw.encode("utf-8") + except UnicodeDecodeError, e: + assert 0, 'ERROR: Unicode Error reading file \'%s\': %s' % \ + (metadata_filepath, e) + return xml_string + +def test_simple(): + xml_string = open_xml_fixture('gemini_dataset.xml') + gemini_document = GeminiDocument(xml_string) + gemini_values = gemini_document.read_values() + assert_equal(gemini_values['guid'], 'test-dataset-1') + assert_equal(gemini_values['metadata-date'], '2011-09-23T10:06:08') + +def test_multiplicity_warning(): + # This dataset lacks a value for Metadata Date and should + # produce a log.warning, but not raise an exception. + xml_string = open_xml_fixture('FCSConservancyPolygons.xml') + gemini_document = GeminiDocument(xml_string) + gemini_values = gemini_document.read_values() + assert_equal(gemini_values['guid'], 'B8A22DF4-B0DC-4F0B-A713-0CF5F8784A28') diff --git a/ckanext/spatial/tests/test_model.py b/ckanext/spatial/tests/model/test_package_extent.py similarity index 100% rename from ckanext/spatial/tests/test_model.py rename to ckanext/spatial/tests/model/test_package_extent.py diff --git a/ckanext/spatial/tests/model/xml/FCSConservancyPolygons.xml b/ckanext/spatial/tests/model/xml/FCSConservancyPolygons.xml new file mode 100644 index 0000000..a34f8aa --- /dev/null +++ b/ckanext/spatial/tests/model/xml/FCSConservancyPolygons.xml @@ -0,0 +1,524 @@ + + + + B8A22DF4-B0DC-4F0B-A713-0CF5F8784A28 + + + utf8 + + + dataset + + + + + Geo-Information Services + + + Forestry Commission Scotland + + + Geo-Information Services Delivery Manager + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + geoinformationservices.scotland@forestry.gsi.gov.uk + + + + + + + pointOfContact + + + + + 2012-11-30T10:51:36 + + + + + + + urn:ogc:def:crs:EPSG::27700 + + + + + + + + + + + FCS Conservancy Polygons + + + s_cons_pol + + + fc.s_cons_pol + + + + + 2004-06-06 + + + creation + + + + + + + 2010-03-16 + + + revision + + + + + + + Geo_Information Services + + + + + + + + + + Description: + +This dataset depicts the five Forestry Commission Scotland Conservancy boundaries. + + + +Attributes: + +NAME : Conservancy Name +ADDRESS_1 : Address +ADDRESS_2 : Address +ADDRESS_3 : Address +ADDRESS_4 : Address +POSTCODE : Postcode +PHONE_NO : Telephone Number +EMAIL : Email Address + + + + + Head of Grants & Licences + + + Forestry Commission Scotland + + + Head of Grants & Licences + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + cgis.scotland@forestry.gsi.gov.uk + + + + + + + owner + + + + + + + Geo-Information Services + + + Forestry Commission Scotland + + + Geo-Information Services Delivery Manager + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + geoinformationservices.scotland@forestry.gsi.gov.uk + + + + + + + custodian + + + + + + + Geo-Information Services + + + Forestry Commission Scotland + + + Geo-Information Services Delivery Manager + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + geoinformationservices.scotland@forestry.gsi.gov.uk + + + + + + + distributor + + + + + + + asNeeded + + + + + + + SDE Feature Class + + + + + + + + + + administrative + + + regional + + + + + + + copyright + + + license + + + otherRestrictions + + + copyright + + + license + + + None + + + + + + + Copyright (Copyright Forestry Commission Scotland) + + + + + + + + + + + + 10000 + + + + + + + eng + + + boundaries + + + economy + + + + + + + + + Scotland + + + + + + + + + -9.229868 + + + -0.705137 + + + 54.513338 + + + 60.866111 + + + + + + + + + + + + + + + + + + + + + + + Unknown + + + Unknown + + + + + + + + + Geo-Information Services + + + Forestry Commission Scotland + + + Geo-Information Services Delivery Manager + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + geoinformationservices.scotland@forestry.gsi.gov.uk + + + + + + + distributor + + + + + + + SDE Feature Class + + + + + + + + + + + + Server=fcspatialsv5; Service=5151; User=fcproduct; Version=SDE.DEFAULT + + + + + + + + + + + + + http://www.forestry.gov.uk/datadownload + + + + + + + + + + + + + dataset + + + + + + + This dataset was derived by merging OS Boundary Line polygons together (with the exception of the boundary between north and south Fife, which was digitised by Geo-Information Services). Boundary Line is based on 1:10,000 scale mapping. + + + + + + \ No newline at end of file diff --git a/ckanext/spatial/tests/model/xml/gemini_dataset.xml b/ckanext/spatial/tests/model/xml/gemini_dataset.xml new file mode 100644 index 0000000..3f58f0e --- /dev/null +++ b/ckanext/spatial/tests/model/xml/gemini_dataset.xml @@ -0,0 +1,498 @@ + + + + test-dataset-1 + + + eng + + + dataset + + + + + Lachlan Renwick + + + Scottish Natural Heritage + + + Geographic Systems and Data Coordinator + + + + + + + 01463 725000 + + + + + + + Great Glen House, Leachkin Road + + + INVERNESS + + + IV3 8NW + + + United Kingdom + + + data_supply@snh.gov.uk + + + + + + + pointOfContact + + + + + 2011-09-23T10:06:08 + + + + + + + urn:ogc:def:crs:EPSG::27700 + + + + + + + + + + + Country Parks (Scotland) + + + + + 2004-02 + + + creation + + + + + + + 2006-07-03 + + + revision + + + + + + + CPK + + + + + + + + + + Parks are set up by Local Authorities to provide open-air recreation facilities close to towns and cities. [edited] + + + + + Lachlan Renwick + + + Scottish Natural Heritage + + + Geographic Systems & Data Coordinator + + + + + + + 01463 725000 + + + + + + + Great Glen House, Leachkin Road + + + INVERNESS + + + IV3 8NW + + + United Kingdom + + + data_supply@snh.gov.uk + + + + + + + custodian + + + + + + + Lachlan Renwick + + + Scottish Natural Heritage + + + Geographic Systems & Data Coordinator + + + + + + + 01463 725000 + + + + + + + Great Glen House, Leachkin Road + + + INVERNESS + + + IV3 8NW + + + United Kingdom + + + data_supply@snh.gov.uk + + + + + + + distributor + + + + + + + irregular + + + + + + + SDE Feature Class + + + + + + + + + + Nature conservation + + + + + Government Category List + + + + + 2004-07-15 + + + revision + + + + + + + + + + + copyright + + + otherRestrictions + + + copyright + + + otherRestrictions + + + Copyright Scottish Natural Heritage + + + + + + + Reference and PSMA Only + + + http://www.test.gov.uk/licenseurl + + + + + + + + + + 5 + + + + + eng + + + environment + + + + + + + + + + + ISO 3166 + + + + + 2007-09-02 + + + revision + + + + + + + GB-SCT + + + + + + + + + -8.97114288 + + + 0.205857204 + + + 54.529947158 + + + 61.06066944 + + + + + + + + 1998 + 2010 + + + + + + + + + + + + + + ESRI Shapefile + + + Unknown + + + + + + + KML + + + 2.1 + + + + + + + GML + + + 3.1.1 + + + + + + + + + Lachlan Renwick + + + Scottish Natural Heritage + + + Geographic Systems & Data Coordinator + + + + + + + 01463 725000 + + + + + + + Great Glen House, Leachkin Road + + + INVERNESS + + + IV3 8NW + + + United Kingdom + + + data_supply@snh.gov.uk + + + + + + + distributor + + + + + + + SDE Feature Class + + + + + + + + + + + + http://www.snh.org.uk/snhi + + + + + + + + + + + + + https://gateway.snh.gov.uk/pls/apex_ddtdb2/f?p=101 + + + Test Resource Name + + + Test Resource Description + + + test-protocol + + + download + + + + + + + + + + + + + dataset + + + + + + + Country Park is not a statutory designation. Countryside (Scotland) Act 1967 Section 48 gives local authorities power to assess and review the need for Country Parks in consultation with SNH. + + + + + + From 775a57d1f5fb7581453166b59b32f9cf971d798f Mon Sep 17 00:00:00 2001 From: David Read Date: Thu, 24 Jan 2013 11:30:23 +0000 Subject: [PATCH 012/114] Latest schematron added. FCSC is a good test of it. --- .../xml/gemini2.1/FCSConservancyPolygons.xml | 524 ++++++++++++ ckanext/spatial/validation/validation.py | 13 +- .../validation/xml/gemini2/Gemini2_R1r3a.sch | 792 ++++++++++++++++++ 3 files changed, 1328 insertions(+), 1 deletion(-) create mode 100644 ckanext/spatial/tests/xml/gemini2.1/FCSConservancyPolygons.xml create mode 100644 ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3a.sch diff --git a/ckanext/spatial/tests/xml/gemini2.1/FCSConservancyPolygons.xml b/ckanext/spatial/tests/xml/gemini2.1/FCSConservancyPolygons.xml new file mode 100644 index 0000000..a34f8aa --- /dev/null +++ b/ckanext/spatial/tests/xml/gemini2.1/FCSConservancyPolygons.xml @@ -0,0 +1,524 @@ + + + + B8A22DF4-B0DC-4F0B-A713-0CF5F8784A28 + + + utf8 + + + dataset + + + + + Geo-Information Services + + + Forestry Commission Scotland + + + Geo-Information Services Delivery Manager + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + geoinformationservices.scotland@forestry.gsi.gov.uk + + + + + + + pointOfContact + + + + + 2012-11-30T10:51:36 + + + + + + + urn:ogc:def:crs:EPSG::27700 + + + + + + + + + + + FCS Conservancy Polygons + + + s_cons_pol + + + fc.s_cons_pol + + + + + 2004-06-06 + + + creation + + + + + + + 2010-03-16 + + + revision + + + + + + + Geo_Information Services + + + + + + + + + + Description: + +This dataset depicts the five Forestry Commission Scotland Conservancy boundaries. + + + +Attributes: + +NAME : Conservancy Name +ADDRESS_1 : Address +ADDRESS_2 : Address +ADDRESS_3 : Address +ADDRESS_4 : Address +POSTCODE : Postcode +PHONE_NO : Telephone Number +EMAIL : Email Address + + + + + Head of Grants & Licences + + + Forestry Commission Scotland + + + Head of Grants & Licences + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + cgis.scotland@forestry.gsi.gov.uk + + + + + + + owner + + + + + + + Geo-Information Services + + + Forestry Commission Scotland + + + Geo-Information Services Delivery Manager + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + geoinformationservices.scotland@forestry.gsi.gov.uk + + + + + + + custodian + + + + + + + Geo-Information Services + + + Forestry Commission Scotland + + + Geo-Information Services Delivery Manager + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + geoinformationservices.scotland@forestry.gsi.gov.uk + + + + + + + distributor + + + + + + + asNeeded + + + + + + + SDE Feature Class + + + + + + + + + + administrative + + + regional + + + + + + + copyright + + + license + + + otherRestrictions + + + copyright + + + license + + + None + + + + + + + Copyright (Copyright Forestry Commission Scotland) + + + + + + + + + + + + 10000 + + + + + + + eng + + + boundaries + + + economy + + + + + + + + + Scotland + + + + + + + + + -9.229868 + + + -0.705137 + + + 54.513338 + + + 60.866111 + + + + + + + + + + + + + + + + + + + + + + + Unknown + + + Unknown + + + + + + + + + Geo-Information Services + + + Forestry Commission Scotland + + + Geo-Information Services Delivery Manager + + + + + + + 0131 334 0303 + + + + + + + Silvan House, 231 Corstorphine Road + + + Edinburgh + + + Scotland + + + EH12 7AT + + + United Kingdom + + + geoinformationservices.scotland@forestry.gsi.gov.uk + + + + + + + distributor + + + + + + + SDE Feature Class + + + + + + + + + + + + Server=fcspatialsv5; Service=5151; User=fcproduct; Version=SDE.DEFAULT + + + + + + + + + + + + + http://www.forestry.gov.uk/datadownload + + + + + + + + + + + + + dataset + + + + + + + This dataset was derived by merging OS Boundary Line polygons together (with the exception of the boundary between north and south Fife, which was digitised by Geo-Information Services). Boundary Line is based on 1:10,000 scale mapping. + + + + + + \ No newline at end of file diff --git a/ckanext/spatial/validation/validation.py b/ckanext/spatial/validation/validation.py index d89ec8e..3235885 100644 --- a/ckanext/spatial/validation/validation.py +++ b/ckanext/spatial/validation/validation.py @@ -200,11 +200,22 @@ class Gemini2Schematron(SchematronValidator): "validation/xml/gemini2/gemini2-schematron-20110906-v1.2.sch") as schema: return [cls.schematron(schema)] +class Gemini2Schematron13(SchematronValidator): + name = 'gemini2-1.3' + title = 'GEMINI 2.1 Schematron 1.3a' + + @classmethod + def get_schematrons(cls): + with resource_stream("ckanext.spatial", + "validation/xml/gemini2/Gemini2_R1r3a.sch") as schema: + return [cls.schematron(schema)] + all_validators = (ISO19139Schema, ISO19139EdenSchema, ConstraintsSchematron, ConstraintsSchematron14, - Gemini2Schematron) + Gemini2Schematron, + Gemini2Schematron13) class Validators(object): diff --git a/ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3a.sch b/ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3a.sch new file mode 100644 index 0000000..1866cca --- /dev/null +++ b/ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3a.sch @@ -0,0 +1,792 @@ + + + + + + + + + + + UK GEMINI Standard Draft Version 2.1 + + This Schematron schema is designed to test the constraints introduced in the GEMINI2 discovery metadata standard. + + + + + + + + + + + + + + + + + + + + + + Title + + + + + + + + + + + Alternative Title + + + + + + + + + + + Dataset Language + + + + + + + + + + + Abstract + + + + + + + + + + + Topic Category + + + Topic category is mandatory for datasets and series. One or more shall be provided. + + + + + Topic Category shall not be null. + + + + + + + + + Keyword + + + Descriptive keywords are mandatory. + + + + + + + + + + + + + + + + + + + + + Temporal extent + + + Temporal extent shall be implemented using gml:TimePeriod or gml:TimeInstant. + + + + + + + + + Dataset reference date + + + + + + + + + + + Lineage + + + Lineage is mandatory for datasets and series. One shall be provided. + + + + + + + + + + + + + West and east longitude, north and south latitude + + + Geographic bounding box is mandatory for datasets and series. One or more shall be provided. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Extent + + + + + + + + + + + Vertical extent information + + + + + + + + + + + Spatial reference system + + + + + + + + + + + Spatial Resolution + + + + + + + + + + + Resource locator + + + The value of resource locator does not appear to be a valid URL. It has a value of ''. The URL must start with either http://, https:// or ftp://. + + + + + + + + + + + + + Data Format + + + + + + + + + + + + + + + Responsible organisation + + + Responsible organisation is mandatory. At least one shall be provided. + + + + + The value of responsible organisation shall not be null. + + + + + + + + + + + + + + + + + + + + + Frequency of update + + + + + + + + + + + Limitations on public access + + + Limitations on public access code list value shall be 'otherRestrictions'. + + + Limitations on public access shall be expressed using gmd:otherConstraints. + + + + + + + + + + + + + + + + + Use constraints + + + Use constraints shall be provided. + + + + + + + + + + + + + Additional information source + + + + + + + + + + + Unique resource identifier + + + Unique resource identifier is mandatory for datasets and series. One or more shall be provided. + + + + + + + + + + + + + + + + + + + Resource type + + + Resource type is mandatory. One shall be provided. + + + Value of resource type shall be 'dataset', 'series' or 'service'. + + + + + + + + + + + + + Conformity + + + + + + + + + + + + + + + Specification + + + + + + + + + + + + + + + + + + + Equivalent scale + + + + + + + + + + + Metadata language + + + Metadata language is mandatory. One shall be provided. + + + + + + + + + + + + + Metadata date + + + + + + + + + + + Metadata point of contact + + + The value of metadata point of contact shall not be null. + + + At least one metadata point of contact shall have the role 'pointOfContact'. + + + + + + + + + + + + + + + + + Spatial data service type + + + If the resource type is service, one spatial data service type shall be provided. + + + Service type shall be one of 'discovery', 'view', 'download', 'transformation', 'invoke' or 'other' following INSPIRE generic names. + + + + + + + + + + + + + Coupled resource + + + Coupled resource shall be implemented by reference using the xlink:href attribute. + + + + + + + + + Data identification citation + The identification information citation cannot be null. + + + Identification information citation shall not be null. + + + + + + Metadata resource type test + Test to ensure that metadata about datasets include the gmd:MD_DataIdentification element and metadata about services include the srv:SV_ServiceIdentification element + + + The first identification information element shall be of type gmd:MD_DataIdentification. + + + The first identification information element shall be of type srv:SV_ServiceIdentification. + + + + + + Metadata file identifier + A file identifier is required + + + A metadata file identifier shall be provided. Its value shall be a system generated GUID. + + + + + + + + + + Constraints + Constraints (Limitations on public access and use constraints) are required. + + + Limitations on public access and use constrains are required. + + + + + + Creation date type + Constrain citation date type = creation to one occurrence. + + + The shall not be more than one creation date. + + + + + + + + + + + + + The element shall have a value or a valid Nil Reason. + + + + + + + + + The element is not nillable and shall have a value. + + + + + + + + + The codeListValue attribute does not have a value. + + + + + + + + + Language shall be implemented with gmd:LanguageCode. + + + + + The language code list value is absent. + + + + + + + + + + One organisation name shall be provided. + + + One email address shall be provided + + + + + + + + + + West bound longitude has a value of which is outside bounds. + + + + East bound longitude has a value of which is outside bounds. + + + + South bound latitude has a value of which is outside bounds. + + + + North bound latitude has a value of which is outside bounds. + + + + + \ No newline at end of file From 91e547a6221dd7b7f98bbd40c9746c7c32861106 Mon Sep 17 00:00:00 2001 From: David Read Date: Mon, 28 Jan 2013 21:53:15 +0000 Subject: [PATCH 013/114] #276 Coupled resources - first iteration. --- ckanext/spatial/bin/__init__.py | 0 ckanext/spatial/bin/coupled_resources.py | 272 ++++++++++++++++++ ckanext/spatial/harvesters.py | 15 +- ckanext/spatial/lib/coupled_resource.py | 37 +++ ckanext/spatial/lib/helpers.py | 51 ++++ .../tests/lib/test_coupled_resource.py | 26 ++ 6 files changed, 396 insertions(+), 5 deletions(-) create mode 100644 ckanext/spatial/bin/__init__.py create mode 100644 ckanext/spatial/bin/coupled_resources.py create mode 100644 ckanext/spatial/lib/coupled_resource.py create mode 100644 ckanext/spatial/lib/helpers.py create mode 100644 ckanext/spatial/tests/lib/test_coupled_resource.py diff --git a/ckanext/spatial/bin/__init__.py b/ckanext/spatial/bin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ckanext/spatial/bin/coupled_resources.py b/ckanext/spatial/bin/coupled_resources.py new file mode 100644 index 0000000..95f5770 --- /dev/null +++ b/ckanext/spatial/bin/coupled_resources.py @@ -0,0 +1,272 @@ +''' +Coupled Resources migration tool +''' + +import re +import os +import logging +import sys +import requests + +from pylons import config +from nose.tools import assert_equal +from lxml import etree + +from ckan.lib.base import json +from ckanext.spatial.model import GeminiDocument +from ckanext.spatial.lib.coupled_resource import extract_guid + +from ckanext.dgu.bin import common +from ckanext.dgu.bin.running_stats import StatsList + +service_stats = StatsList() +couple_stats = StatsList() + +class FindError(Exception): + pass + +class CoupledResources(object): + @classmethod + def detect(cls): + '''Finds datasets that are coupled and adds their + harvest_source_reference to the HarvestObject and package extras. + ''' + from ckan import model + from ckanext.harvest.model import HarvestObject + + # Find service records + for service_record in model.Session.query(model.Package).\ + filter_by(state='active').\ + join(model.PackageExtra).\ + filter_by(state='active').\ + filter_by(key='resource-type').\ + filter_by(value='service'): + + ## # Get HarvestObject + ## harvest_object_id = service_record.extras.get('harvest_object_id') + ## if not harvest_object_id: + ## service_stats.add('No harvest_object_id', service_record.name) + ## continue + ## harvest_object = HarvestObject.get(harvest_object_id) + ## if not harvest_object: + ## service_stats.add('No harvest_object found for id', service_record.name) + ## continue + + # Find coupled dataset records + service_type = service_record.extras['resource-type'] + if not 'coupled-resource' in service_record.extras: + if service_type in ('view', 'download'): + service_stats.add('No coupled-resource extra for %s type (where it is mandatory)', service_record.name, service_type) + else: + service_stats.add('No coupled-resource extra (but not mandatory for this service type)', service_record.name) + continue + coupled_resources_str = service_record.extras['coupled-resource'] + coupled_resources = json.loads(coupled_resources_str) + log.info('%s has %i coupled resources', + service_record.name, len(coupled_resources)) + couples_all_detected = True + couples_detected = False + for i, coupled_resource in enumerate(coupled_resources): + couple_id = '%s.%s' % (service_record.name, i) + href = coupled_resource['href'] + + # For tests only + #if href != ['http://www.ordnancesurvey.co.uk/oswebsite/xml/products/Topo.xml']: + # break + + if len(href) <> 1: + log.error('Coupled resource href is not a list of 1: %r couple=%s', + href, couple_id) + couple_stats.add('Couple href is length %i' % len(href), couple_id) + couples_all_detected = False + continue + href = href[0] + if not href.strip(): + log.error('Coupled resource href is blank. couple=%s', + couple_id) + couple_stats.add('Couple href is blank', couple_id) + couples_all_detected = False + continue + + # Look for the equivalent dataset resource + + # If it is CSW, we must extract the guid + # Example CSW url: http://ogcdev.bgs.ac.uk/geonetwork/srv/en/csw?SERVICE=CSW&REQUEST=GetRecordById&ID=9df8df52-d788-37a8-e044-0003ba9b0d98&elementSetName=full&OutputSchema=http://www.isotc211.org/2005/gmd + guid = extract_guid(href) + if guid: + if not guid.strip(): + couple_stats.add('Guid was blank', couple_id) + log.error('Guid was blank. href=%s', href, couple_id) + + try: + harvest_object = cls.find_harvest_object_by_guid(guid) + except FindError, e: + log.error('%s guid=%s couple=%s', e, guid, couple_id) + couple_stats.add(str(e), couple_id) + couples_all_detected = False + continue + + dataset_record = harvest_object.package #res.resource_group.package + couple_stats.add('Couple completed', couple_id) + log.info('Couple completed %s <-> %s', + service_record.name, dataset_record.name) + + cls.add_coupling(harvest_object, guid) + couples_detected = True + continue + + # Known bad couples are weeded out + bad_couples = ('GetCapabilities', 'CEH:EIDC', + 'ceh:eidc', + 'http://data.nbn.org.uk#', + 'www.geostore.com/OGC/OGCInterface', + 'spatialni.gov.uk/arcgis/services/LPS/CadastreNI/MapServer/WMSServer', + 'Please enter a valid url', + ) + bad_couple_detected = False + for bad_couple in bad_couples: + if bad_couple in href: + couple_stats.add('Invalid couple (%s)' % bad_couple, couple_id) + log.info('Invalid couple (%s): %s couple=%s', bad_couple, href, couple_id) + bad_couple_detected = True + if bad_couple_detected: + couples_all_detected = False + continue + + # Try as a WAF + # Try the URL to download the gemini again, to find the + # GUID of the dataset + log.info('Trying possible WAF href: %s' % href) + try: + res = requests.get(href, timeout=10) + except Exception, e: + couple_stats.add('Connecting to href failed: %s' % \ + e, couple_id) + log.warning('Connecting to href failed: %s href:"%s"', \ + e, href) + couples_all_detected = False + break + if not res.ok: + couple_stats.add('Resolving href failed: %s' % \ + res.reason, couple_id) + log.warning('Resolving href failed: %s %s href:"%s"', \ + res.status_code, res.reason, href) + couples_all_detected = False + break + gemini = GeminiDocument(res.content) + try: + guid = gemini.read_value('guid') + except KeyError, e: + couple_stats.add('Could not get GUID from Gemini downloaded' % \ + href, couple_id) + log.warning('Could not get GUID from Gemini downloaded href:"%s"', \ + href) + couples_all_detected = False + break + except etree.XMLSyntaxError, e: + couple_stats.add('Could not parse "Gemini" downloaded', + couple_id) + log.warning('Could not parse "Gemini" downloaded href:"%s"', \ + href) + couples_all_detected = False + break + try: + harvest_object = cls.find_harvest_object_by_guid(guid) + except FindError, e: + log.error('%s href=%s couple=%s', e, href, couple_id) + couple_stats.add(str(e), couple_id) + couples_all_detected = False + continue + + dataset_record = harvest_object.package #res.resource_group.package + couple_stats.add('Couple completed', couple_id) + log.info('Couple completed %s <-> %s', + service_record.name, dataset_record.name) + + cls.add_coupling(harvest_object, href) + couples_detected = True + + if coupled_resources: + if couples_all_detected: + service_stats.add('Service couples all completed', service_record.name) + elif couples_detected: + service_stats.add('Service couples partially completed', service_record.name) + else: + service_stats.add('Service couples not completed', service_record.name) + else: + if service_type in ('view', 'download'): + service_stats.add('No couples for %s type (where it is mandatory)', service_record.name, service_type) + else: + service_stats.add('No couples (but not mandatory for service type %s)' % service_type, service_record.name) + continue + + model.Session.remove() + + print "\nServices:" + print service_stats.report() + print "\nCouples:" + print couple_stats.report() + + @classmethod + def find_harvest_object_by_guid(cls, guid): + from ckan import model + from ckanext.harvest.model import HarvestObject + + q = model.Session.query(HarvestObject).\ + filter_by(guid=guid).\ + filter_by(current=True) + if q.count() == 0: + raise FindError('No matches for guid') + if q.count() <> 1: + raise FindError('Wrong number of matches (%i) for guid' % \ + q.count()) + harvest_object = q.one() + return harvest_object + + + @classmethod + def add_coupling(cls, dataset_harvest_object, harvest_source_reference): + from ckan import model + if dataset_harvest_object.harvest_source_reference != harvest_source_reference: + rev = model.repo.new_revision() + rev.author = 'Couple migration' + dataset_harvest_object.harvest_source_reference = harvest_source_reference + model.Session.commit() + + @classmethod + def setup_logging(cls, config_ini_filepath): + logging.config.fileConfig(config_ini_filepath) + global log + log = logging.getLogger(os.path.basename(__file__)) + + +warnings = [] +log = None +def warn(msg, *params): + global warnings + warnings.append(msg % params) + global_log.warn(msg, *params) + + +def usage(): + print """ +Coupled Resources tool +Usage: + + python coupled_resources.py detect + - finds datasets that are coupled and adds their harvest_source_reference + """ + +if __name__ == '__main__': + if len(sys.argv) != 3: + print 'Wrong number of arguments %i' % len(sys.argv) + usage() + sys.exit(0) + cmd, config_ini, action = sys.argv + common.load_config(config_ini) + CoupledResources.setup_logging(config_ini) + common.register_translator() + if action == 'detect': + CoupledResources.detect() + else: + raise NotImplementedError diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 7170b2e..6291811 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -141,7 +141,8 @@ class GeminiHarvester(SpatialHarvester): self._save_object_error('Empty content for object %s' % harvest_object.id,harvest_object,'Import') return False try: - self.import_gemini_object(harvest_object.content) + self.import_gemini_object(harvest_object.content, + harvest_object.harvest_source_reference) return True except Exception, e: log.error('Exception during import: %s' % text_traceback()) @@ -247,7 +248,8 @@ class GeminiHarvester(SpatialHarvester): extras = { 'UKLP': 'True', - 'harvest_object_id': self.obj.id + 'harvest_object_id': self.obj.id, + 'harvest_source_reference': self.obj.harvest_source_reference, } # Just add some of the metadata as extras, not the whole lot @@ -608,7 +610,8 @@ class GeminiCswHarvester(GeminiHarvester, SingletonPlugin): continue # Create a new HarvestObject for this identifier - obj = HarvestObject(guid=identifier, job=harvest_job) + obj = HarvestObject(guid=identifier, job=harvest_job, + harvest_source_reference=guid) obj.save() ids.append(obj.id) @@ -708,7 +711,8 @@ class GeminiDocHarvester(GeminiHarvester, SingletonPlugin): # have it, we might as well save a request obj = HarvestObject(guid=gemini_guid, job=harvest_job, - content=gemini_string) + content=gemini_string, + harvest_source_reference=gemini_string) obj.save() log.info('Got GUID %s' % gemini_guid) @@ -780,7 +784,8 @@ class GeminiWafHarvester(GeminiHarvester, SingletonPlugin): # have it, we might as well save a request obj = HarvestObject(guid=gemini_guid, job=harvest_job, - content=gemini_string) + content=gemini_string, + harvest_source_reference=url) obj.save() ids.append(obj.id) diff --git a/ckanext/spatial/lib/coupled_resource.py b/ckanext/spatial/lib/coupled_resource.py new file mode 100644 index 0000000..abe97c2 --- /dev/null +++ b/ckanext/spatial/lib/coupled_resource.py @@ -0,0 +1,37 @@ +import re + +guid_matcher = None + +def extract_guid(csw_url): + '''Given a CSW GetRecordByID URL, identify the record\'s ID (GUID). + Returns the GUID or None if it can\'t find it.''' + # Example CSW url: http://ogcdev.bgs.ac.uk/geonetwork/srv/en/csw?SERVICE=CSW&REQUEST=GetRecordById&ID=9df8df52-d788-37a8-e044-0003ba9b0d98&elementSetName=full&OutputSchema=http://www.isotc211.org/2005/gmd + if not guid_matcher: + global guid_matcher + guid_matcher = re.compile('id=\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})', flags=re.IGNORECASE) + guid_match = guid_matcher.search(csw_url) + if guid_match: + return guid_match.groups()[0] + +def extract_gemini_harvest_source_reference(coupled_href): + '''Given the href in the Coupled Resource (srv:operatesOn xlink:href) + this function returns the 'harvest_source_reference' identifier for + the coupled dataset record. + + This follows the Gemini Encoding Guidance 2.1, which differs from + the INSPIRE guidance: + + The value of the XLink attribute, as shown in the INSPIRE technical + guidance, is the value of the metadata item Unique Resource + Identifier. However, the guidance for GEMINI metadata is different. + The value of the attribute shall be a URL that + allows access to an unambiguous metadata instance, which may be: + * an OGC CS-W GetRecordById request + * an address of a metadata instance in a WAF + ''' + if not coupled_href.startswith('http'): + return + guid = extract_guid(coupled_href) + return guid or coupled_href + + diff --git a/ckanext/spatial/lib/helpers.py b/ckanext/spatial/lib/helpers.py new file mode 100644 index 0000000..05f043d --- /dev/null +++ b/ckanext/spatial/lib/helpers.py @@ -0,0 +1,51 @@ +# template helpers + +from ckan import model +from ckan.lib.base import json +from ckanext.harvest.model import HarvestObject +from ckanext.spatial.lib.coupled_resource import extract_gemini_harvest_source_reference + +def get_coupled_packages(pkg_extras): + res_type = pkg_extras.get('resource-type') + if res_type in ('dataset', 'series'): + coupled_packages = [] + # Find the service records which point to this dataset record + harvest_object_id = pkg_extras.get('harvest_object_id') + if not harvest_object_id: + return coupled_packages + harvest_object = HarvestObject.get(harvest_object_id) + dataset_ref = harvest_object.harvest_source_reference + if not dataset_ref: + return coupled_packages # [] + q = model.Session.query(model.Package) \ + .join(model.PackageExtra) \ + .join(HarvestObject) \ + .filter(HarvestObject.current==True) \ + .filter(model.PackageExtra.key=='coupled-resource') \ + .filter(model.PackageExtra.value.like('%' + dataset_ref + '%')) + # probably 0, 1 or 2 results if there is a view and download service. + coupled_packages.extend([(pkg.name, pkg.title) for pkg in q.all()]) + return coupled_packages + + elif res_type == 'service': + # Find the dataset records which are pointed to in this service record + coupled_resources_str = pkg_extras.get('coupled-resource', '[]') + coupled_resources = json.loads(coupled_resources_str) + coupled_packages = [] + for coupled_resource in coupled_resources: + hrefs = coupled_resource.get('href', '') + href = hrefs[0].strip() + harvest_source_reference = extract_gemini_harvest_source_reference(href) + if not harvest_source_reference: + continue + q = model.Session.query(model.Package) \ + .join(HarvestObject) \ + .filter(HarvestObject.current==True) \ + .filter(HarvestObject.harvest_source_reference==harvest_source_reference) \ + .filter(model.Package.state==u'active') + # probably 0 or 1 results, but there is the possibility + # WAFs lead to multiple results. Just add them all in that case. + coupled_packages.extend([(pkg.name, pkg.title) for pkg in q.all()]) + return coupled_packages + + diff --git a/ckanext/spatial/tests/lib/test_coupled_resource.py b/ckanext/spatial/tests/lib/test_coupled_resource.py new file mode 100644 index 0000000..b7c4948 --- /dev/null +++ b/ckanext/spatial/tests/lib/test_coupled_resource.py @@ -0,0 +1,26 @@ +from nose.tools import assert_equal + +from ckanext.spatial.lib.coupled_resource import extract_guid, extract_gemini_harvest_source_reference + +GOOD_CSW_RECORD = 'http://ogcdev.bgs.ac.uk/geonetwork/srv/en/csw?SERVICE=CSW&REQUEST=GetRecordById&ID=9df8df52-d788-37a8-e044-0003ba9b0d98&elementSetName=full&OutputSchema=http://www.isotc211.org/2005/gmd' +GOOD_CSW_RECORD_ID = '9df8df52-d788-37a8-e044-0003ba9b0d98' +BAD_CSW_RECORD = 'http://www.geostore.com/OGC/OGCInterface?INTERFACE=ENVIRONMENT&UID=def&PASSWORD=abc&LC=ffe0000000&' +WAF_ITEM = 'http://www.ordnancesurvey.co.uk/oswebsite/xml/products/Topo.xml' +BAD_COUPLE = 'CEH:EIDC:#1279200030617' # would be ok for INSPIRE, but not Gemini + +def test_extract_guid__ok(): + assert_equal(extract_guid(GOOD_CSW_RECORD), GOOD_CSW_RECORD_ID) + assert_equal(extract_guid(GOOD_CSW_RECORD.lower()), GOOD_CSW_RECORD_ID) + +def test_extract_guid__bad(): + assert_equal(extract_guid(BAD_CSW_RECORD), None) + assert_equal(extract_guid(''), None) + assert_equal(extract_guid(' '), None) + +def test_extract_gemini_harvest_source_reference(): + assert_equal(extract_gemini_harvest_source_reference(WAF_ITEM), + WAF_ITEM) + assert_equal(extract_gemini_harvest_source_reference(GOOD_CSW_RECORD), + GOOD_CSW_RECORD_ID) + assert_equal(extract_guid(BAD_COUPLE), + None) From ecd6036efe85e9246eeab75099eac62086dd2425 Mon Sep 17 00:00:00 2001 From: David Read Date: Mon, 28 Jan 2013 23:56:12 +0000 Subject: [PATCH 014/114] #276 Coupled resources - second iteration. Just need to update harvester now. --- ckanext/spatial/bin/coupled_resources.py | 92 +++++++++++++++++++----- ckanext/spatial/lib/helpers.py | 51 ++++--------- 2 files changed, 86 insertions(+), 57 deletions(-) diff --git a/ckanext/spatial/bin/coupled_resources.py b/ckanext/spatial/bin/coupled_resources.py index 95f5770..2cf981e 100644 --- a/ckanext/spatial/bin/coupled_resources.py +++ b/ckanext/spatial/bin/coupled_resources.py @@ -12,15 +12,12 @@ from pylons import config from nose.tools import assert_equal from lxml import etree -from ckan.lib.base import json -from ckanext.spatial.model import GeminiDocument -from ckanext.spatial.lib.coupled_resource import extract_guid - from ckanext.dgu.bin import common from ckanext.dgu.bin.running_stats import StatsList service_stats = StatsList() couple_stats = StatsList() +additional_couple_stats = StatsList() class FindError(Exception): pass @@ -31,9 +28,12 @@ class CoupledResources(object): '''Finds datasets that are coupled and adds their harvest_source_reference to the HarvestObject and package extras. ''' + from ckan.lib.base import json from ckan import model from ckanext.harvest.model import HarvestObject - + from ckanext.spatial.model import GeminiDocument + from ckanext.spatial.lib.coupled_resource import extract_guid + # Find service records for service_record in model.Session.query(model.Package).\ filter_by(state='active').\ @@ -42,16 +42,6 @@ class CoupledResources(object): filter_by(key='resource-type').\ filter_by(value='service'): - ## # Get HarvestObject - ## harvest_object_id = service_record.extras.get('harvest_object_id') - ## if not harvest_object_id: - ## service_stats.add('No harvest_object_id', service_record.name) - ## continue - ## harvest_object = HarvestObject.get(harvest_object_id) - ## if not harvest_object: - ## service_stats.add('No harvest_object found for id', service_record.name) - ## continue - # Find coupled dataset records service_type = service_record.extras['resource-type'] if not 'coupled-resource' in service_record.extras: @@ -111,7 +101,7 @@ class CoupledResources(object): log.info('Couple completed %s <-> %s', service_record.name, dataset_record.name) - cls.add_coupling(harvest_object, guid) + cls.add_coupling(service_record, dataset_record, harvest_object, guid) couples_detected = True continue @@ -183,7 +173,7 @@ class CoupledResources(object): log.info('Couple completed %s <-> %s', service_record.name, dataset_record.name) - cls.add_coupling(harvest_object, href) + cls.add_coupling(service_record, dataset_record, harvest_object, href) couples_detected = True if coupled_resources: @@ -201,11 +191,24 @@ class CoupledResources(object): continue model.Session.remove() - + + # Ensure all dataset records are in the harvest_coupled_resource table + # for future reference + for dataset_record in model.Session.query(model.Package).\ + filter_by(state='active').\ + join(model.PackageExtra).\ + filter_by(state='active').\ + filter_by(key='resource-type').\ + filter(model.PackageExtra.value.in_(('dataset', 'series'))): + cls.ensure_dataset_is_in_couple_table(dataset_record) + model.Session.remove() + print "\nServices:" print service_stats.report() print "\nCouples:" print couple_stats.report() + print "\nAdditional datasets added to couple table:" + print additional_couple_stats.report() @classmethod def find_harvest_object_by_guid(cls, guid): @@ -225,13 +228,64 @@ class CoupledResources(object): @classmethod - def add_coupling(cls, dataset_harvest_object, harvest_source_reference): + def add_coupling(cls, service_record, dataset_record, + dataset_harvest_object, harvest_source_reference): from ckan import model + from ckanext.harvest.model import HarvestCoupledResource + if dataset_harvest_object.harvest_source_reference != harvest_source_reference: rev = model.repo.new_revision() rev.author = 'Couple migration' dataset_harvest_object.harvest_source_reference = harvest_source_reference model.Session.commit() + q = model.Session.query(HarvestCoupledResource) \ + .filter_by(service_record_package_id=service_record.id) \ + .filter_by(dataset_record_package_id=dataset_record.id) \ + .filter_by(harvest_source_reference=harvest_source_reference) + if q.count() == 0: + rev = model.repo.new_revision() + rev.author = 'Couple migration' + obj = HarvestCoupledResource( + service_record_package_id=service_record.id, + dataset_record_package_id=dataset_record.id, + harvest_source_reference=harvest_source_reference) + model.Session.add(obj) + model.Session.commit() + + @classmethod + def ensure_dataset_is_in_couple_table(cls, dataset_record): + from ckan import model + from ckanext.harvest.model import HarvestCoupledResource + + q = model.Session.query(HarvestCoupledResource) \ + .filter_by(dataset_record_package_id=dataset_record.id) + if q.count() == 0: + harvest_objects = [ho for ho in dataset_record.harvest_objects \ + if ho.current] + if len(harvest_objects) != 1: + log.warning('Wrong num of current harvest_objects (%i)', + len(harvest_objects)) + additional_couple_stats.add('Wrong num of harvest_objects (%i)' % len(harvest_objects), + dataset_record.name) + return + harvest_object = harvest_objects[0] + harvest_source_reference = harvest_object.harvest_source_reference + + rev = model.repo.new_revision() + rev.author = 'Couple migration' + obj = HarvestCoupledResource( + dataset_record_package_id=dataset_record.id, + harvest_source_reference=harvest_source_reference) + model.Session.add(obj) + model.Session.commit() + additional_couple_stats.add('Added to couple table', + dataset_record.name) + log.info('Added to couple table: %s', dataset_record.name) + else: + additional_couple_stats.add('Already in couple table', + dataset_record.name) + log.info('Already in couple table: %s', dataset_record.name) + @classmethod def setup_logging(cls, config_ini_filepath): diff --git a/ckanext/spatial/lib/helpers.py b/ckanext/spatial/lib/helpers.py index 05f043d..9bd8abd 100644 --- a/ckanext/spatial/lib/helpers.py +++ b/ckanext/spatial/lib/helpers.py @@ -2,50 +2,25 @@ from ckan import model from ckan.lib.base import json -from ckanext.harvest.model import HarvestObject +from ckanext.harvest.model import HarvestObject, HarvestCoupledResource from ckanext.spatial.lib.coupled_resource import extract_gemini_harvest_source_reference -def get_coupled_packages(pkg_extras): - res_type = pkg_extras.get('resource-type') +def get_coupled_packages(pkg): + res_type = pkg.extras.get('resource-type') if res_type in ('dataset', 'series'): - coupled_packages = [] - # Find the service records which point to this dataset record - harvest_object_id = pkg_extras.get('harvest_object_id') - if not harvest_object_id: - return coupled_packages - harvest_object = HarvestObject.get(harvest_object_id) - dataset_ref = harvest_object.harvest_source_reference - if not dataset_ref: - return coupled_packages # [] - q = model.Session.query(model.Package) \ - .join(model.PackageExtra) \ - .join(HarvestObject) \ - .filter(HarvestObject.current==True) \ - .filter(model.PackageExtra.key=='coupled-resource') \ - .filter(model.PackageExtra.value.like('%' + dataset_ref + '%')) - # probably 0, 1 or 2 results if there is a view and download service. - coupled_packages.extend([(pkg.name, pkg.title) for pkg in q.all()]) + coupled_resources = pkg.coupled_service + coupled_packages = \ + [(couple.service_record.name, couple.service_record.title) \ + for couple in coupled_resources \ + if couple.service_record_package_id] return coupled_packages elif res_type == 'service': # Find the dataset records which are pointed to in this service record - coupled_resources_str = pkg_extras.get('coupled-resource', '[]') - coupled_resources = json.loads(coupled_resources_str) - coupled_packages = [] - for coupled_resource in coupled_resources: - hrefs = coupled_resource.get('href', '') - href = hrefs[0].strip() - harvest_source_reference = extract_gemini_harvest_source_reference(href) - if not harvest_source_reference: - continue - q = model.Session.query(model.Package) \ - .join(HarvestObject) \ - .filter(HarvestObject.current==True) \ - .filter(HarvestObject.harvest_source_reference==harvest_source_reference) \ - .filter(model.Package.state==u'active') - # probably 0 or 1 results, but there is the possibility - # WAFs lead to multiple results. Just add them all in that case. - coupled_packages.extend([(pkg.name, pkg.title) for pkg in q.all()]) + coupled_resources = pkg.coupled_dataset + coupled_packages = \ + [(couple.dataset_record.name, couple.dataset_record.title) \ + for couple in coupled_resources \ + if couple.dataset_record_package_id] return coupled_packages - From 2cef9d6daef7da1065941ff939845cec6c9cbd82 Mon Sep 17 00:00:00 2001 From: David Read Date: Thu, 31 Jan 2013 14:32:19 +0000 Subject: [PATCH 015/114] #noticket Tests added to clarify license URL extraction. --- ckanext/spatial/tests/test_harvest.py | 33 +++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/ckanext/spatial/tests/test_harvest.py b/ckanext/spatial/tests/test_harvest.py index 6599d57..7453e0f 100644 --- a/ckanext/spatial/tests/test_harvest.py +++ b/ckanext/spatial/tests/test_harvest.py @@ -13,7 +13,8 @@ from ckanext.harvest.model import (setup as harvest_model_setup, HarvestSource, HarvestJob, HarvestObject) from ckanext.spatial.validation import Validators, SchematronValidator from ckanext.spatial.harvesters import (GeminiCswHarvester, GeminiDocHarvester, - GeminiWafHarvester, SpatialHarvester) + GeminiWafHarvester, SpatialHarvester, + GeminiHarvester) from ckanext.spatial.model.package_extent import setup as spatial_db_setup from ckanext.spatial.tests.base import SpatialTestBase @@ -165,7 +166,7 @@ class TestHarvest(HarvestFixtureBase): pkgs = Session.query(Package).all() - assert len(pkgs) == 2 + assert_equal(len(pkgs), 2) pkg_ids = [pkg.id for pkg in pkgs] @@ -802,6 +803,34 @@ class TestHarvest(HarvestFixtureBase): source_dict = get_action('harvest_source_show')(self.context,{'id':source.id}) assert len(source_dict['status']['packages']) == 1 +class TestImportStageTools: + def test_licence_url_normal(self): + assert_equal(GeminiHarvester._extract_first_licence_url( + ['Reference and PSMA Only', + 'http://www.test.gov.uk/licenseurl']), + 'http://www.test.gov.uk/licenseurl') + + def test_licence_url_multiple_urls(self): + # only the first URL is extracted + assert_equal(GeminiHarvester._extract_first_licence_url( + ['Reference and PSMA Only', + 'http://www.test.gov.uk/licenseurl', + 'http://www.test.gov.uk/2nd_licenseurl']), + 'http://www.test.gov.uk/licenseurl') + + def test_licence_url_embedded(self): + # URL is embedded within the text field and not extracted + assert_equal(GeminiHarvester._extract_first_licence_url( + ['Reference and PSMA Only http://www.test.gov.uk/licenseurl']), + None) + + def test_licence_url_embedded_at_start(self): + # URL is embedded at the start of the text field and the + # whole field is returned. Noting this unusual behaviour + assert_equal(GeminiHarvester._extract_first_licence_url( + ['http://www.test.gov.uk/licenseurl Reference and PSMA Only']), + 'http://www.test.gov.uk/licenseurl Reference and PSMA Only') + class TestValidation(HarvestFixtureBase): From 01536873b9d5b44da3f2286c8b6b74378a2be246 Mon Sep 17 00:00:00 2001 From: David Read Date: Thu, 31 Jan 2013 18:05:48 +0000 Subject: [PATCH 016/114] #276 Coupled Resource table now gets updated during harvest. --- ckanext/spatial/bin/coupled_resources.py | 6 - ckanext/spatial/harvesters.py | 38 ++- ckanext/spatial/lib/coupled_resource.py | 153 +++++++++++- .../tests/lib/test_coupled_resource.py | 233 +++++++++++++++++- ckanext/spatial/tests/test_harvest.py | 23 +- test-core.ini | 14 +- 6 files changed, 446 insertions(+), 21 deletions(-) diff --git a/ckanext/spatial/bin/coupled_resources.py b/ckanext/spatial/bin/coupled_resources.py index 2cf981e..f32de77 100644 --- a/ckanext/spatial/bin/coupled_resources.py +++ b/ckanext/spatial/bin/coupled_resources.py @@ -234,8 +234,6 @@ class CoupledResources(object): from ckanext.harvest.model import HarvestCoupledResource if dataset_harvest_object.harvest_source_reference != harvest_source_reference: - rev = model.repo.new_revision() - rev.author = 'Couple migration' dataset_harvest_object.harvest_source_reference = harvest_source_reference model.Session.commit() q = model.Session.query(HarvestCoupledResource) \ @@ -243,8 +241,6 @@ class CoupledResources(object): .filter_by(dataset_record_package_id=dataset_record.id) \ .filter_by(harvest_source_reference=harvest_source_reference) if q.count() == 0: - rev = model.repo.new_revision() - rev.author = 'Couple migration' obj = HarvestCoupledResource( service_record_package_id=service_record.id, dataset_record_package_id=dataset_record.id, @@ -271,8 +267,6 @@ class CoupledResources(object): harvest_object = harvest_objects[0] harvest_source_reference = harvest_object.harvest_source_reference - rev = model.repo.new_revision() - rev.author = 'Couple migration' obj = HarvestCoupledResource( dataset_record_package_id=dataset_record.id, harvest_source_reference=harvest_source_reference) diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 6291811..b87d266 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -46,6 +46,7 @@ from ckanext.harvest.model import HarvestObject, HarvestGatherError, \ from ckanext.spatial.model import GeminiDocument from ckanext.spatial.lib.csw_client import CswService from ckanext.spatial.validation import Validators +from ckanext.spatial.lib.coupled_resource import extract_guid, update_coupled_resources log = logging.getLogger(__name__) @@ -154,7 +155,13 @@ class GeminiHarvester(SpatialHarvester): if debug_exception_mode: raise - def import_gemini_object(self, gemini_string): + def import_gemini_object(self, gemini_string, harvest_source_reference): + '''Imports the Gemini metadata into CKAN. + + The harvest_source_reference is an ID that the harvest_source uses + for the metadata document. It is the same ID the Coupled Resources + use to link dataset and service records. + ''' log = logging.getLogger(__name__ + '.import') xml = etree.fromstring(gemini_string) @@ -166,12 +173,18 @@ class GeminiHarvester(SpatialHarvester): unicode_gemini_string = etree.tostring(xml, encoding=unicode, pretty_print=True) - package = self.write_package_from_gemini_string(unicode_gemini_string) + package_dict = self.write_package_from_gemini_string(unicode_gemini_string) + + if package_dict: + package = Session.query(Package).get(package_dict['id']) + update_coupled_resources(package, harvest_source_reference) def write_package_from_gemini_string(self, content): '''Create or update a Package based on some content that has come from a URL. + + Returns the package_dict of the result, or None if there is an error. ''' log = logging.getLogger(__name__ + '.import') package = None @@ -438,11 +451,10 @@ class GeminiHarvester(SpatialHarvester): self.obj.current = True self.obj.save() - assert gemini_guid == [e['value'] for e in package['extras'] if e['key'] == 'guid'][0] assert self.obj.id == [e['value'] for e in package['extras'] if e['key'] == 'harvest_object_id'][0] - return package + return package # i.e. a package_dict def gen_new_name(self, title): name = munge_title_to_name(title).replace('_', '-') @@ -461,7 +473,8 @@ class GeminiHarvester(SpatialHarvester): counter = counter + 1 return None - def _extract_first_licence_url(self, licences): + @classmethod + def _extract_first_licence_url(cls, licences): '''Given a list of pieces of licence info, hunt for the first one which looks like a URL and return it. Otherwise returns None.''' for licence in licences: @@ -472,6 +485,14 @@ class GeminiHarvester(SpatialHarvester): def _create_package_from_data(self, package_dict, package = None): ''' + Given a package_dict describing a package, creates or updates + a package object. If you supply package then it will update it, + otherwise it will create a new one. + + Uses the logic layer to create it. + + Returns a package_dict of the resulting package. + {'name': 'council-owned-litter-bins', 'notes': 'Location of Council owned litter bins within Borough.', 'resources': [{'description': 'Resource locator', @@ -566,6 +587,7 @@ class GeminiHarvester(SpatialHarvester): return gemini_string, gemini_guid + class GeminiCswHarvester(GeminiHarvester, SingletonPlugin): ''' A Harvester for CSW servers @@ -612,6 +634,9 @@ class GeminiCswHarvester(GeminiHarvester, SingletonPlugin): # Create a new HarvestObject for this identifier obj = HarvestObject(guid=identifier, job=harvest_job, harvest_source_reference=guid) + # NB: Gemini uses GUID for the harvest_source_reference + # whereas INSPIRE specifies the Unique Resource + # Identifier obj.save() ids.append(obj.id) @@ -786,6 +811,9 @@ class GeminiWafHarvester(GeminiHarvester, SingletonPlugin): job=harvest_job, content=gemini_string, harvest_source_reference=url) + # NB: Gemini uses WAF URL for the + # harvest_source_reference whereas INSPIRE + # specifies the Unique Resource Identifier obj.save() ids.append(obj.id) diff --git a/ckanext/spatial/lib/coupled_resource.py b/ckanext/spatial/lib/coupled_resource.py index abe97c2..c266c77 100644 --- a/ckanext/spatial/lib/coupled_resource.py +++ b/ckanext/spatial/lib/coupled_resource.py @@ -1,7 +1,17 @@ import re +import logging + +from ckan.lib.base import json +from ckanext.harvest.model import HarvestCoupledResource +from ckan import model + +log = logging.getLogger(__name__) guid_matcher = None +class CoupledResourceParseError(Exception): + pass + def extract_guid(csw_url): '''Given a CSW GetRecordByID URL, identify the record\'s ID (GUID). Returns the GUID or None if it can\'t find it.''' @@ -32,6 +42,147 @@ def extract_gemini_harvest_source_reference(coupled_href): if not coupled_href.startswith('http'): return guid = extract_guid(coupled_href) - return guid or coupled_href + return guid or coupled_href.strip() +def extract_harvest_source_reference_from_coupled_resource(coupled_resource_dict): + '''Given a coupled_resource_dict, returns the harvest_source_reference. + + May raise CoupledResourceParseError. + ''' + href = coupled_resource_dict['href'] + if len(href) <> 1: + raise CoupledResourceParseError('Coupled resource href is not a list of 1: %r' % href) + href = href[0] + if not href.strip(): + raise CoupledResourceParseError('Coupled resource href is blank.') + ref = extract_gemini_harvest_source_reference(href) + if not ref: + raise CoupledResourceParseError('Coupled resource harvest source reference is blank') + return ref +def _package_name(package_or_none): + return package_or_none.name if package_or_none else None + +def update_coupled_resources(package, harvest_source_reference): + '''Update the harvest_coupled_resource_table with the details of this + harvested package\'s couplings. + + :param package: the Package object containing extra fields with couples + to update in the table. + :param harvest_source_reference: the ref of this package being harvested. + This is not relevant if it is a service record, but + essential if it is a dataset. + ''' + resource_type = package.extras['resource-type'] + if resource_type == 'service': + # When a service record is harvested, ensure the couples listed + # in it match the couples in the HarvestCoupledResource objects, + # ignoring their dataset values (they might be filled in or not). + pkg_couples_str = package.extras['coupled-resource'] + pkg_couples = json.loads(pkg_couples_str) + log.info('Service Record %s has %i coupled resources to update', + package.name, len(pkg_couples)) + + table_couples_matching_service = HarvestCoupledResource.get_by_service_record(package) + table_couples_not_matching_pkg = table_couples_matching_service.all() # cross them off as we go + + for pkg_couple in pkg_couples: + try: + ref = extract_harvest_source_reference_from_coupled_resource(pkg_couple) + except CoupledResourceParseError, e: + log.warn('Error parsing couple: %s Ignoring couple=%s', e, pkg_couple) + continue + # Match both service and ref + matching_table_couples = table_couples_matching_service.filter_by(harvest_source_reference=ref) + if matching_table_couples.count() > 0: + # Test: test_02_reharvest_existing_service + # Note down the matches so we don't delete them later + for matching_table_couple in matching_table_couples: + log.info('Service couple is already there (%s, %s, %s)', + package.name, ref, + _package_name(matching_table_couple.dataset_record)) + table_couples_not_matching_pkg.remove(matching_table_couple) + continue + # Match just ref with blank service + matching_table_couples = HarvestCoupledResource.get_by_harvest_source_reference(ref)\ + .filter_by(service_record=None) + if matching_table_couples.count() == 0: + # Test: test_06_harvest_service_not_matching_a_dataset + # create the row + obj = HarvestCoupledResource(service_record=package, + harvest_source_reference=ref) + model.Session.add(obj) + log.info('Ref is new for this service - adding (%s, %s, None)', + package.name, ref) + model.Session.commit() + else: + # Test: test_04_harvest_service_to_match_existing_dataset + for matching_table_couple in matching_table_couples: + # fill in the service value + matching_table_couple.service_record = package + log.info('Service filled into couple matching ref (%s, %s, %s)', + package.name, ref, + _package_name(matching_table_couple.dataset_record)) + model.Session.commit() + + # Delete service value for any table_couples not matching the package + # Test: test_08_reharvest_existing_service_to_delete_and_add_couples + for table_couple in table_couples_not_matching_pkg: + log.info('Service couple not matched - deleted service (%s->None, %s, %s)', + _package_name(table_couple.service_record), + ref, _package_name(table_couple.dataset_record)) + table_couple.service_record = None + model.Session.commit() + return + elif resource_type in ('dataset', 'series'): + # When a dataset (or dataset series) record is harvested, for its + # dataset_record_package_id there should be one ref - any with another + # ref is removed. And for the dataset_record_package_id and ref combo + # there should be one or more HarvestCoupledResource objects (with + # a service or without). + + # Couples where this dataset is under a different ref + # Test: test_07_reharvest_existing_dataset_but_with_changed_ref + ref = harvest_source_reference + assert ref + for couple in model.Session.query(HarvestCoupledResource) \ + .filter_by(dataset_record=package) \ + .filter(HarvestCoupledResource.harvest_source_reference!=ref): + log.info('Ref %s has been replaced for this dataset record with ' + '%s. Removing link to the dataset record (%s, %s, %s->None)', + couple.harvest_source_reference, ref, + _package_name(couple.service_record), + couple.harvest_source_reference, + _package_name(couple.dataset_record)) + couple.dataset_record = None + model.Session.commit() + + # Couples with this ref + for couple in HarvestCoupledResource.get_by_harvest_source_reference(ref): + if couple.dataset_record != package: + # Test: test_03_harvest_dataset_to_match_existing_service + log.info('Linking ref to this dataset record (%s, %s, %s->%s)', + _package_name(couple.service_record), + ref, + _package_name(couple.dataset_record), + package.name) + couple.dataset_record = package + model.Session.commit() + else: + # Test: test_01_reharvest_existing_dataset + log.info('Couple for this dataset and ref already exists (%s, %s, %s)', + _package_name(couple.service_record), + ref, + _package_name(couple.dataset_record)) + + # No couples for this ref + couples = HarvestCoupledResource.get_by_harvest_source_reference(ref) + if couples.count() == 0: + # Test: test_05_harvest_dataset_not_matching_a_service + obj = HarvestCoupledResource(dataset_record=package, + harvest_source_reference=ref) + model.Session.add(obj) + log.info('Ref is new - adding new dataset couple (None, %s, %s)', + ref, package.name) + model.Session.commit() + return diff --git a/ckanext/spatial/tests/lib/test_coupled_resource.py b/ckanext/spatial/tests/lib/test_coupled_resource.py index b7c4948..0d8888d 100644 --- a/ckanext/spatial/tests/lib/test_coupled_resource.py +++ b/ckanext/spatial/tests/lib/test_coupled_resource.py @@ -1,6 +1,15 @@ from nose.tools import assert_equal +from pylons import config +from pprint import pprint + +from ckan.logic import get_action +from ckan.lib.create_test_data import CreateTestData +from ckan import model +from ckan.lib.base import json +from ckanext.harvest.model import HarvestSource, HarvestJob, HarvestObject, HarvestCoupledResource + +from ckanext.spatial.lib.coupled_resource import extract_guid, extract_gemini_harvest_source_reference, update_coupled_resources -from ckanext.spatial.lib.coupled_resource import extract_guid, extract_gemini_harvest_source_reference GOOD_CSW_RECORD = 'http://ogcdev.bgs.ac.uk/geonetwork/srv/en/csw?SERVICE=CSW&REQUEST=GetRecordById&ID=9df8df52-d788-37a8-e044-0003ba9b0d98&elementSetName=full&OutputSchema=http://www.isotc211.org/2005/gmd' GOOD_CSW_RECORD_ID = '9df8df52-d788-37a8-e044-0003ba9b0d98' @@ -24,3 +33,225 @@ def test_extract_gemini_harvest_source_reference(): GOOD_CSW_RECORD_ID) assert_equal(extract_guid(BAD_COUPLE), None) + +ref_prefix = 'http://waf/' + +class TestUpdateCoupledResources: + def setup(self): + # Create fixtures + CreateTestData.create_arbitrary([ + {'name': 'serviceA', + 'extras': {'coupled-resource': json.dumps( + [{'href': [ref_prefix+'Bref']}, + {'href': [ref_prefix+'Href']}, + {'href': [ref_prefix+'Eref']}]), + 'resource-type': 'service'}}, + {'name': 'serviceF', + 'extras': {'coupled-resource': json.dumps( + [{'href': [ref_prefix+'Dref']}]), + 'resource-type': 'service'}}, + {'name': 'serviceG', + 'extras': {'coupled-resource': json.dumps( + [{'href': [ref_prefix+'Gref']}]), + 'resource-type': 'service'}}, + {'name': 'datasetB', + 'extras': {'resource-type': 'dataset'}}, + {'name': 'datasetC', + 'extras': {'resource-type': 'dataset'}}, + {'name': 'datasetD', + 'extras': {'resource-type': 'dataset'}}, + {'name': 'datasetE', + 'extras': {'resource-type': 'dataset'}}, + {'name': 'datasetG', + 'extras': {'resource-type': 'dataset'}}, + {'name': 'datasetH', + 'extras': {'resource-type': 'dataset'}}, + {'name': 'serviceD', + 'extras': {'coupled-resource': json.dumps( + [{'href': [ref_prefix+'Dref']}]), + 'resource-type': 'service'}}, + ]) + self._create_user() + self._create_publisher() + self.source, self.job = self._create_source_and_job() + self._create_harvest_object('datasetB', ref='Bref') + self._create_harvest_object('datasetC', ref='Cref') + self._create_harvest_object('datasetD', ref='Dref') + self._create_harvest_object('datasetE', ref='Eref') + + # Create a partially-filled coupling table + self._create_coupled_resource('serviceA', 'Bref', 'datasetB') + self._create_coupled_resource('serviceA', 'Cref', 'datasetC') + self._create_coupled_resource(None, 'Dref', 'datasetD') + self._create_coupled_resource('serviceA', 'Eref', None) + self._create_coupled_resource('serviceF', 'Dref', 'datasetD') + + model.Session.commit() + model.Session.remove() + + self.couples_before = self._get_coupled_resources() + pprint(self.couples_before) + assert_equal(len(self.couples_before), 5) + + def teardown(self): + model.repo.rebuild_db() + + def test_01_reharvest_existing_dataset(self): + package = model.Package.by_name(u'datasetB') + update_coupled_resources(package, ref_prefix+'Bref') + assert_equal(self._get_coupled_resources(), self.couples_before) + + def test_02_reharvest_existing_service(self): + package = model.Package.by_name(u'serviceF') + update_coupled_resources(package, None) + assert_equal(self._get_coupled_resources(), self.couples_before) + + def test_03_harvest_dataset_to_match_existing_service(self): + package = model.Package.by_name(u'datasetE') + update_coupled_resources(package, ref_prefix+'Eref') + assert_equal(self._get_coupled_resources(), + change_line(self.couples_before, + (u'serviceA', u'Eref', None), + (u'serviceA', u'Eref', u'datasetE'))) + + def test_04_harvest_service_to_match_existing_dataset(self): + package = model.Package.by_name(u'serviceD') + update_coupled_resources(package, None) + assert_equal(self._get_coupled_resources(), + change_line(self.couples_before, + (None, u'Dref', u'datasetD'), + (u'serviceD', u'Dref', u'datasetD'))) + + def test_05_harvest_dataset_not_matching_a_service(self): + package = model.Package.by_name(u'datasetG') + update_coupled_resources(package, ref_prefix+'Gref') + assert_equal(self._get_coupled_resources(), + add_line(self.couples_before, + (None, u'Gref', u'datasetG'))) + + def test_06_harvest_service_not_matching_a_dataset(self): + package = model.Package.by_name(u'serviceG') + update_coupled_resources(package, None) + assert_equal(self._get_coupled_resources(), + add_line(self.couples_before, + (u'serviceG', u'Gref', None))) + + def test_07_reharvest_existing_dataset_but_with_changed_ref(self): + # This may occur only in a WAF. If a dataset is reharvested from + # a different WAF URL then the old WAF URL (and therefore ref) + # for that dataset becomes invalid. + # (A CSW may change a dataset's GUID, but it becomes a different + # datasets entirely if that happens) + package = model.Package.by_name(u'datasetB') + update_coupled_resources(package, ref_prefix+'Jref') + expected_couples = change_line(self.couples_before, + ('serviceA', u'Bref', 'datasetB'), + ('serviceA', u'Bref', None)) + expected_couples = add_line(expected_couples, + (None, u'Jref', 'datasetB')) + assert_equal(self._get_coupled_resources(), expected_couples) + + def test_08_reharvest_existing_service_to_delete_and_add_couples(self): + package = model.Package.by_name(u'serviceA') + update_coupled_resources(package, None) + expected_couples = change_line(self.couples_before, + ('serviceA', u'Cref', 'datasetC'), + (None, 'Cref', 'datasetC')) + expected_couples = add_line(expected_couples, + (u'serviceA', u'Href', None)) + print 'EXPECTED_COUPLES'; pprint(expected_couples) + print 'RESULT_COUPLES'; pprint(self._get_coupled_resources()) + assert_equal(self._get_coupled_resources(), + expected_couples) + + + def _get_coupled_resources(self): + return [(couple.service_record.name if couple.service_record else None, + couple.harvest_source_reference.replace(ref_prefix, ''), + couple.dataset_record.name if couple.dataset_record else None)\ + for couple in model.Session.query(HarvestCoupledResource)] + + def _create_coupled_resource(self, service_name, ref, dataset_name): + service = model.Package.by_name(unicode(service_name or '')) + dataset = model.Package.by_name(unicode(dataset_name or '')) + if service_name: assert service + if dataset_name: assert dataset + model.Session.add( + HarvestCoupledResource(service_record=service, + harvest_source_reference=ref_prefix+ref, + dataset_record=dataset) + ) + + def _create_harvest_object(self, package_name, ref): + package = model.Package.by_name(unicode(package_name)) + model.Session.add( + HarvestObject(guid='not important', + current=True, source=self.source, job=self.job, + harvest_source_reference=ref_prefix+ref, + package=package) + ) + + + def _create_user(self): + harvest_user = model.User(name=u'harvest', password=u'test') + model.add_user_to_role(harvest_user, model.Role.ADMIN, model.System()) + model.Session.add(harvest_user) + model.Session.commit() + + def _create_publisher(self): + self.publisher = model.Group(name=u'test-publisher', + title=u'Test Publihser', + type=u'publisher') + model.Session.add(self.publisher) + model.Session.commit() + + def _create_source_and_job(self): + context ={'model': model, + 'session': model.Session, + 'user': u'harvest'} + source_fixture = { + 'url': u'http://csw/GetCapabilities', + 'type': u'csw' + } + if config.get('ckan.harvest.auth.profile') == u'publisher' \ + and not 'publisher_id' in source_fixture: + source_fixture['publisher_id'] = self.publisher.id + + source_dict=get_action('harvest_source_create')(context,source_fixture) + source = HarvestSource.get(source_dict['id']) + assert source + + job = self._create_job(source.id) + + return source, job + + def _create_job(self,source_id): + # Create a job + context ={'model':model, + 'session':model.Session, + 'user':u'harvest'} + + job_dict=get_action('harvest_job_create')(context,{'source_id':source_id}) + job = HarvestJob.get(job_dict['id']) + assert job + + return job + +def change_line(couples, line_to_change, replacement_line): + '''Given a list of coupled resource tuples, returns a similar + list, but with the line that matches line_to_change replaced + with replacement_line.''' + line_number = couples.index(line_to_change) + return couples[:line_number] + [replacement_line] + couples[line_number+1:] + +def add_line(couples, line_to_add): + '''Given a list of coupled resource tuples, returns a similar + list, but with the line added.''' + return couples[:] + [line_to_add] + +def remove_line(couples, line_to_remove): + '''Given a list of coupled resource tuples, returns a similar + list, but with the line added.''' + line_number = couples.index(line_to_remove) + return couples[:line_number] + couples[line_number+1:] + diff --git a/ckanext/spatial/tests/test_harvest.py b/ckanext/spatial/tests/test_harvest.py index 7453e0f..58deaa4 100644 --- a/ckanext/spatial/tests/test_harvest.py +++ b/ckanext/spatial/tests/test_harvest.py @@ -10,7 +10,8 @@ from ckan.model import Session,Package from ckan.logic.schema import default_update_package_schema from ckan.logic import get_action from ckanext.harvest.model import (setup as harvest_model_setup, - HarvestSource, HarvestJob, HarvestObject) + HarvestSource, HarvestJob, HarvestObject, + HarvestCoupledResource) from ckanext.spatial.validation import Validators, SchematronValidator from ckanext.spatial.harvesters import (GeminiCswHarvester, GeminiDocHarvester, GeminiWafHarvester, SpatialHarvester, @@ -261,17 +262,18 @@ class TestHarvest(HarvestFixtureBase): raise AssertionError('Unexpected value for extra %s: %s (was expecting %s)' % \ (key, package_dict['extras'][key], value)) + # Much of this depends on the particular WMS server working... expected_resource = { - 'ckan_recommended_wms_preview': 'True', + #'ckan_recommended_wms_preview': 'True', 'description': 'Link to the GetCapabilities request for this service', - 'format': 'WMS', + #'format': 'WMS', 'name': 'Web Map Service (WMS)', 'resource_locator_function': 'download', 'resource_locator_protocol': 'OGC:WMS-1.3.0-http-get-capabilities', 'resource_type': None, 'size': None, 'url': u'http://sedsh13.sedsh.gov.uk/ArcGIS/services/OSG/OSG/MapServer/WMSServer?request=GetCapabilities&service=WMS', - 'verified': 'True', + #'verified': 'True', } resource = package_dict['resources'][0] @@ -279,7 +281,18 @@ class TestHarvest(HarvestFixtureBase): if not resource[key] == value: raise AssertionError('Unexpected value in resource for %s: %s (was expecting %s)' % \ (key, resource[key], value)) - assert datetime.strptime(resource['verified_date'],'%Y-%m-%dT%H:%M:%S.%f').date() == date.today() + #assert datetime.strptime(resource['verified_date'],'%Y-%m-%dT%H:%M:%S.%f').date() == date.today() + + # See that the coupled resources are created (half of the link) + coupled_resources = self._get_coupled_resources() + assert_equal(coupled_resources, + set([(u'one-scotland-address-gazetteer-web-map-service-wms', '250ea276-48e2-4189-8a89-fcc4ca92d652', None)])) + + def _get_coupled_resources(self): + return set([(couple.service_record.name if couple.service_record else None, + couple.harvest_source_reference, + couple.dataset_record.name if couple.dataset_record else None)\ + for couple in model.Session.query(HarvestCoupledResource)]) def test_harvest_fields_dataset(self): diff --git a/test-core.ini b/test-core.ini index 5f80bb6..4ad5086 100644 --- a/test-core.ini +++ b/test-core.ini @@ -26,7 +26,7 @@ ckan.spatial.validator.profiles = iso19139,constraints,gemini2 # Logging configuration [loggers] -keys = root, ckan, sqlalchemy +keys = root, ckan, sqlalchemy, ckanext [handlers] keys = console @@ -40,13 +40,21 @@ handlers = console [logger_ckan] qualname = ckan -handlers = +handlers = console level = INFO +propagate = 0 + +[logger_ckanext] +qualname = ckanext +handlers = console +level = DEBUG +propagate = 0 [logger_sqlalchemy] -handlers = +handlers = console qualname = sqlalchemy.engine level = WARN +propagate = 0 [handler_console] class = StreamHandler From 73af616b812a00f2c1bc60e36c227d931f65bf41 Mon Sep 17 00:00:00 2001 From: David Read Date: Fri, 1 Feb 2013 12:04:50 +0000 Subject: [PATCH 017/114] #noticket No functionality has changed! Factored out responsible_organisation stuff into a separate method to add tests to show what it does. --- ckanext/spatial/harvesters.py | 76 ++++++++++++++++----------- ckanext/spatial/tests/test_harvest.py | 61 +++++++++++++++++++++ 2 files changed, 107 insertions(+), 30 deletions(-) diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index b87d266..5eb45a7 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -306,36 +306,10 @@ class GeminiHarvester(SpatialHarvester): extras['temporal_coverage-to'] = gemini_values['temporal-extent-end'] # Save responsible organization roles - parties = {} - owners = [] - publishers = [] - for responsible_party in gemini_values['responsible-organisation']: - - if responsible_party['role'] == 'owner': - owners.append(responsible_party['organisation-name']) - elif responsible_party['role'] == 'publisher': - publishers.append(responsible_party['organisation-name']) - - if responsible_party['organisation-name'] in parties: - if not responsible_party['role'] in parties[responsible_party['organisation-name']]: - parties[responsible_party['organisation-name']].append(responsible_party['role']) - else: - parties[responsible_party['organisation-name']] = [responsible_party['role']] - - parties_extra = [] - for party_name in parties: - parties_extra.append('%s (%s)' % (party_name, ', '.join(parties[party_name]))) - extras['responsible-party'] = '; '.join(parties_extra) - - # Save provider in a separate extra: - # first organization to have a role of 'owner', and if there is none, first one with - # a role of 'publisher' - if len(owners): - extras['provider'] = owners[0] - elif len(publishers): - extras['provider'] = publishers[0] - else: - extras['provider'] = u'' + provider, responsible_parties = self._process_responsible_organisation( + gemini_values['responsible-organisation']) + extras['provider'] = provider + extras['responsible-party'] = '; '.join(responsible_parties) # Construct a GeoJSON extent so ckanext-spatial can register the extent geometry extent_string = self.extent_template.substitute( @@ -456,6 +430,48 @@ class GeminiHarvester(SpatialHarvester): return package # i.e. a package_dict + @classmethod + def _process_responsible_organisation(cls, responsible_organisations): + '''Given the list of responsible_organisations and their roles, + (extracted from the GeminiDocument) determines who the provider is + and the list of all responsible organisations and their roles. + + :param responsible_organisations: list of dicts, each with keys + includeing 'organisation-name' and 'role' + :returns: tuple of: 'provider' (string, may be empty) and + 'responsible-parties' (list of strings) + ''' + parties = {} + owners = [] + publishers = [] + for responsible_party in responsible_organisations: + if responsible_party['role'] == 'owner': + owners.append(responsible_party['organisation-name']) + elif responsible_party['role'] == 'publisher': + publishers.append(responsible_party['organisation-name']) + + if responsible_party['organisation-name'] in parties: + if not responsible_party['role'] in parties[responsible_party['organisation-name']]: + parties[responsible_party['organisation-name']].append(responsible_party['role']) + else: + parties[responsible_party['organisation-name']] = [responsible_party['role']] + + responsible_parties = [] + for party_name in parties: + responsible_parties.append('%s (%s)' % (party_name, ', '.join(parties[party_name]))) + + # Save provider in a separate extra: + # first organization to have a role of 'owner', and if there is none, first one with + # a role of 'publisher' + if len(owners): + provider = owners[0] + elif len(publishers): + provider = publishers[0] + else: + provider = u'' + + return provider, responsible_parties + def gen_new_name(self, title): name = munge_title_to_name(title).replace('_', '-') while '--' in name: diff --git a/ckanext/spatial/tests/test_harvest.py b/ckanext/spatial/tests/test_harvest.py index 58deaa4..99d2806 100644 --- a/ckanext/spatial/tests/test_harvest.py +++ b/ckanext/spatial/tests/test_harvest.py @@ -844,6 +844,67 @@ class TestImportStageTools: ['http://www.test.gov.uk/licenseurl Reference and PSMA Only']), 'http://www.test.gov.uk/licenseurl Reference and PSMA Only') + def test_responsible_organisation_basic(self): + responsible_organisation = [{'organisation-name': 'Ordnance Survey', + 'role': 'owner'}, + {'organisation-name': 'Maps Ltd', + 'role': 'distributor'}] + assert_equal(GeminiHarvester._process_responsible_organisation(responsible_organisation), + ('Ordnance Survey', ['Maps Ltd (distributor)', + 'Ordnance Survey (owner)'])) + + def test_responsible_organisation_publisher(self): + # no owner, so falls back to publisher + responsible_organisation = [{'organisation-name': 'Ordnance Survey', + 'role': 'publisher'}, + {'organisation-name': 'Maps Ltd', + 'role': 'distributor'}] + assert_equal(GeminiHarvester._process_responsible_organisation(responsible_organisation), + ('Ordnance Survey', ['Maps Ltd (distributor)', + 'Ordnance Survey (publisher)'])) + + def test_responsible_organisation_owner(self): + # provider is the owner (ignores publisher) + responsible_organisation = [{'organisation-name': 'Ordnance Survey', + 'role': 'publisher'}, + {'organisation-name': 'Owner', + 'role': 'owner'}, + {'organisation-name': 'Maps Ltd', + 'role': 'distributor'}] + assert_equal(GeminiHarvester._process_responsible_organisation(responsible_organisation), + ('Owner', ['Owner (owner)', + 'Maps Ltd (distributor)', + 'Ordnance Survey (publisher)', + ])) + + def test_responsible_organisation_multiple_roles(self): + # provider is the owner (ignores publisher) + responsible_organisation = [{'organisation-name': 'Ordnance Survey', + 'role': 'publisher'}, + {'organisation-name': 'Ordnance Survey', + 'role': 'custodian'}, + {'organisation-name': 'Distributor', + 'role': 'distributor'}] + assert_equal(GeminiHarvester._process_responsible_organisation(responsible_organisation), + ('Ordnance Survey', ['Distributor (distributor)', + 'Ordnance Survey (publisher, custodian)', + ])) + + def test_responsible_organisation_blank_provider(self): + # no owner or publisher, so blank provider + responsible_organisation = [{'organisation-name': 'Ordnance Survey', + 'role': 'resourceProvider'}, + {'organisation-name': 'Maps Ltd', + 'role': 'distributor'}] + assert_equal(GeminiHarvester._process_responsible_organisation(responsible_organisation), + ('', ['Maps Ltd (distributor)', + 'Ordnance Survey (resourceProvider)'])) + + def test_responsible_organisation_blank(self): + # no owner or publisher, so blank provider + responsible_organisation = [] + assert_equal(GeminiHarvester._process_responsible_organisation(responsible_organisation), + ('', [])) class TestValidation(HarvestFixtureBase): From cdabab12cd8cbabb02c65f44fbca3426db61097d Mon Sep 17 00:00:00 2001 From: David Read Date: Fri, 1 Feb 2013 14:00:51 +0000 Subject: [PATCH 018/114] #154 Gemini schematron 1.3 has been accepted, so loses the "a" suffix. --- ckanext/spatial/validation/validation.py | 4 ++-- .../xml/gemini2/{Gemini2_R1r3a.sch => Gemini2_R1r3.sch} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename ckanext/spatial/validation/xml/gemini2/{Gemini2_R1r3a.sch => Gemini2_R1r3.sch} (98%) diff --git a/ckanext/spatial/validation/validation.py b/ckanext/spatial/validation/validation.py index 3235885..8f2d242 100644 --- a/ckanext/spatial/validation/validation.py +++ b/ckanext/spatial/validation/validation.py @@ -202,12 +202,12 @@ class Gemini2Schematron(SchematronValidator): class Gemini2Schematron13(SchematronValidator): name = 'gemini2-1.3' - title = 'GEMINI 2.1 Schematron 1.3a' + title = 'GEMINI 2.1 Schematron 1.3' @classmethod def get_schematrons(cls): with resource_stream("ckanext.spatial", - "validation/xml/gemini2/Gemini2_R1r3a.sch") as schema: + "validation/xml/gemini2/Gemini2_R1r3.sch") as schema: return [cls.schematron(schema)] all_validators = (ISO19139Schema, diff --git a/ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3a.sch b/ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3.sch similarity index 98% rename from ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3a.sch rename to ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3.sch index 1866cca..b9e8792 100644 --- a/ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3a.sch +++ b/ckanext/spatial/validation/xml/gemini2/Gemini2_R1r3.sch @@ -68,7 +68,7 @@ - Vertical extent (Metadata item 16) - remove rule restricting number of vertical extent elements to 0 or 1. - 2012-12-20 - Version 1.3a + 2012-12-20 - Version 1.3 - Metadata language - ensure that metadata contains one metadata language element. Gemini2-mi33 edited and rule added. --> @@ -789,4 +789,4 @@ - \ No newline at end of file + From 3eee0be135fb126f69affb62f5dc74da6ac5c986 Mon Sep 17 00:00:00 2001 From: David Read Date: Fri, 1 Feb 2013 18:09:12 +0000 Subject: [PATCH 019/114] #noticket Bugfix - diff (when harvest content changed without timestamp change) displayed raw html. --- ckanext/spatial/harvesters.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 5eb45a7..319c0a8 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -161,6 +161,8 @@ class GeminiHarvester(SpatialHarvester): The harvest_source_reference is an ID that the harvest_source uses for the metadata document. It is the same ID the Coupled Resources use to link dataset and service records. + + Some errors raise Exceptions. ''' log = logging.getLogger(__name__ + '.import') xml = etree.fromstring(gemini_string) @@ -173,6 +175,7 @@ class GeminiHarvester(SpatialHarvester): unicode_gemini_string = etree.tostring(xml, encoding=unicode, pretty_print=True) + # may raise Exception for errors package_dict = self.write_package_from_gemini_string(unicode_gemini_string) if package_dict: @@ -184,7 +187,8 @@ class GeminiHarvester(SpatialHarvester): '''Create or update a Package based on some content that has come from a URL. - Returns the package_dict of the result, or None if there is an error. + Returns the package_dict of the result. + If there is an error, it returns None or raises Exception. ''' log = logging.getLogger(__name__ + '.import') package = None @@ -247,7 +251,7 @@ class GeminiHarvester(SpatialHarvester): else: if last_harvested_object.content != self.obj.content and \ last_harvested_object.metadata_modified_date == self.obj.metadata_modified_date: - diff_generator = difflib.HtmlDiff().make_table( + diff_generator = difflib.unified_diff( last_harvested_object.content.split('\n'), self.obj.content.split('\n')) diff = '\n'.join([line for line in diff_generator]) From 3f627d9700c7a5fd5f352637a20885b26c264104 Mon Sep 17 00:00:00 2001 From: David Read Date: Fri, 1 Feb 2013 23:10:58 +0000 Subject: [PATCH 020/114] #276 Coupled Resource - fix to not show withdrawn packages in list of coupled resources. --- ckanext/spatial/harvesters.py | 2 ++ ckanext/spatial/lib/helpers.py | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 319c0a8..c84e366 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -64,6 +64,8 @@ debug_exception_mode = bool(os.getenv('DEBUG')) class SpatialHarvester(object): # Q: Why does this not inherit from HarvesterBase in ckanext-harvest? + # A: HarvesterBase just provides some useful util methods. The key thing + # a harvester does is it implements(IHarvester). def _is_wms(self,url): try: diff --git a/ckanext/spatial/lib/helpers.py b/ckanext/spatial/lib/helpers.py index 9bd8abd..284e33a 100644 --- a/ckanext/spatial/lib/helpers.py +++ b/ckanext/spatial/lib/helpers.py @@ -12,7 +12,9 @@ def get_coupled_packages(pkg): coupled_packages = \ [(couple.service_record.name, couple.service_record.title) \ for couple in coupled_resources \ - if couple.service_record_package_id] + if couple.service_record_package_id and \ + couple.service_record and \ + couple.service_record.state == 'active'] return coupled_packages elif res_type == 'service': @@ -21,6 +23,8 @@ def get_coupled_packages(pkg): coupled_packages = \ [(couple.dataset_record.name, couple.dataset_record.title) \ for couple in coupled_resources \ - if couple.dataset_record_package_id] + if couple.dataset_record_package_id and \ + couple.dataset_record and \ + couple.dataset_record.state == 'active'] return coupled_packages From 27c4ee81e2425bb79c1dd0bacc0e7b9108cb1b2e Mon Sep 17 00:00:00 2001 From: David Read Date: Sat, 2 Feb 2013 00:06:33 +0000 Subject: [PATCH 021/114] #287 Avoid doing extra validation for WAF in the gather stage. --- ckanext/spatial/harvesters.py | 25 ++++------ ckanext/spatial/tests/test_harvest.py | 67 +++++++++++++++++++++------ 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index c84e366..41af148 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -91,8 +91,8 @@ class SpatialHarvester(object): self._validator = Validators(profiles=profiles) return self._validator - def _save_gather_error(self,message,job): - err = HarvestGatherError(message=message,job=job) + def _save_gather_error(self, message, job): + err = HarvestGatherError(message=message, job=job) try: err.save() except InvalidRequestError: @@ -573,9 +573,8 @@ class GeminiHarvester(SpatialHarvester): '''From a string buffer containing Gemini XML, return the tree under gmd:MD_Metadata and the GUID for it. - During the process it does validation: - * XML validation which may cause it to store gather_errors - * GeminiDocument multiplicity checks which may raise Exception. + If it cannot parse the XML it will raise lxml.etree.XMLSyntaxError. + If it cannot find the GUID element, then gemini_guid will be ''. :param content: string containing Gemini XML :param url: string giving info about the location of the XML to be @@ -592,20 +591,14 @@ class GeminiHarvester(SpatialHarvester): gemini_xml = xml.find(metadata_tag) if gemini_xml is None: - self._save_gather_error('Content is not a valid Gemini document',self.harvest_job) - - valid, messages = self._get_validator().is_valid(gemini_xml) - if not valid: - out = messages[0] + ':\n' + '\n'.join(messages[1:]) - if url: - self._save_gather_error('Validation error for %s - %s'% (url,out),self.harvest_job) - else: - self._save_gather_error('Validation error - %s'%out,self.harvest_job) + self._save_gather_error('Content is not a valid Gemini document without the gmd:MD_Metadata element', self.harvest_job) gemini_string = etree.tostring(gemini_xml) gemini_document = GeminiDocument(gemini_string) - gemini_values = gemini_document.read_values() - gemini_guid = gemini_values['guid'] + try: + gemini_guid = gemini_document.read_value('guid') + except KeyError: + gemini_guid = None return gemini_string, gemini_guid diff --git a/ckanext/spatial/tests/test_harvest.py b/ckanext/spatial/tests/test_harvest.py index 99d2806..0ca283b 100644 --- a/ckanext/spatial/tests/test_harvest.py +++ b/ckanext/spatial/tests/test_harvest.py @@ -1,7 +1,7 @@ from datetime import datetime, date import lxml -from nose.tools import assert_equal, assert_in +from nose.tools import assert_equal, assert_in, assert_raises from ckan import plugins from ckan.lib.base import config @@ -83,7 +83,7 @@ class HarvestFixtureBase(SpatialTestBase): return job - def _create_source_and_job(self,source_fixture): + def _create_source_and_job(self, source_fixture): context ={'model':model, 'session':Session, 'user':u'harvest'} @@ -457,17 +457,7 @@ class TestHarvest(HarvestFixtureBase): assert object_ids, len(object_ids) == 1 # No gather errors - assert len(job.gather_errors) == 1 - assert job.gather_errors[0].harvest_job_id == job.id - - message = job.gather_errors[0].message - - assert_in('Validation error', message) - assert_in('Validating against "GEMINI 2.1 Schematron 1.2" profile failed', message) - assert_in('One email address shall be provided', message) - assert_in('Service type shall be one of \'discovery\', \'view\', \'download\', \'transformation\', \'invoke\' or \'other\' following INSPIRE generic names', message) - assert_in('Limitations on public access code list value shall be \'otherRestrictions\'', message) - assert_in('One organisation name shall be provided', message) + assert len(job.gather_errors) == 0 # Fetch stage always returns True for Single Doc harvesters assert harvester.fetch_stage(object_ids) == True @@ -480,6 +470,15 @@ class TestHarvest(HarvestFixtureBase): # Check errors assert len(obj.errors) == 1 + assert obj.errors[0].harvest_object_id == obj.id + + message = obj.errors[0].message + + assert_in('Validating against "GEMINI 2.1 Schematron 1.2" profile failed', message) + assert_in('One email address shall be provided', message) + assert_in('Service type shall be one of \'discovery\', \'view\', \'download\', \'transformation\', \'invoke\' or \'other\' following INSPIRE generic names', message) + assert_in('Limitations on public access code list value shall be \'otherRestrictions\'', message) + assert_in('One organisation name shall be provided', message) def test_harvest_update_records(self): @@ -816,6 +815,48 @@ class TestHarvest(HarvestFixtureBase): source_dict = get_action('harvest_source_show')(self.context,{'id':source.id}) assert len(source_dict['status']['packages']) == 1 +BASIC_GEMINI = ''' + + e269743a-cfda-4632-a939-0c8416ae801e + + + service + +''' +GUID = 'e269743a-cfda-4632-a939-0c8416ae801e' +GEMINI_MISSING_GUID = '''''' + +class TestGatherMethods(HarvestFixtureBase): + def setup(self): + HarvestFixtureBase.setup(self) + # Create source + source_fixture = { + 'url': u'http://127.0.0.1:8999/gemini2.1/dataset1.xml', + 'type': u'gemini-single' + } + source, job = self._create_source_and_job(source_fixture) + self.harvester = GeminiHarvester() + self.harvester.harvest_job = job + + def teardown(self): + model.repo.rebuild_db() + + def test_get_gemini_string_and_guid(self): + res = self.harvester.get_gemini_string_and_guid(BASIC_GEMINI, url=None) + assert_equal(res, (BASIC_GEMINI, GUID)) + + def test_get_gemini_string_and_guid__no_guid(self): + res = self.harvester.get_gemini_string_and_guid(GEMINI_MISSING_GUID, url=None) + assert_equal(res, (GEMINI_MISSING_GUID, '')) + + def test_get_gemini_string_and_guid__non_parsing(self): + content = '' # no closing tag + assert_raises(lxml.etree.XMLSyntaxError, self.harvester.get_gemini_string_and_guid, content) + + def test_get_gemini_string_and_guid__empty(self): + content = '' + assert_raises(lxml.etree.XMLSyntaxError, self.harvester.get_gemini_string_and_guid, content) + class TestImportStageTools: def test_licence_url_normal(self): assert_equal(GeminiHarvester._extract_first_licence_url( From 84b75ea759b61c303a21b3330543a1c3deb74ad3 Mon Sep 17 00:00:00 2001 From: David Read Date: Mon, 4 Feb 2013 16:00:34 +0000 Subject: [PATCH 022/114] Revert "#276 Coupled Resource - fix to not show withdrawn packages in list of coupled resources." Reverting changes for "#276 Coupled Resource" on master as it is INSPIRE-specific. Moving to datagovuk/ckanext-spatial branch dgu. This reverts commit 3f627d9700c7a5fd5f352637a20885b26c264104. --- ckanext/spatial/harvesters.py | 2 -- ckanext/spatial/lib/helpers.py | 8 ++------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 41af148..022a0b3 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -64,8 +64,6 @@ debug_exception_mode = bool(os.getenv('DEBUG')) class SpatialHarvester(object): # Q: Why does this not inherit from HarvesterBase in ckanext-harvest? - # A: HarvesterBase just provides some useful util methods. The key thing - # a harvester does is it implements(IHarvester). def _is_wms(self,url): try: diff --git a/ckanext/spatial/lib/helpers.py b/ckanext/spatial/lib/helpers.py index 284e33a..9bd8abd 100644 --- a/ckanext/spatial/lib/helpers.py +++ b/ckanext/spatial/lib/helpers.py @@ -12,9 +12,7 @@ def get_coupled_packages(pkg): coupled_packages = \ [(couple.service_record.name, couple.service_record.title) \ for couple in coupled_resources \ - if couple.service_record_package_id and \ - couple.service_record and \ - couple.service_record.state == 'active'] + if couple.service_record_package_id] return coupled_packages elif res_type == 'service': @@ -23,8 +21,6 @@ def get_coupled_packages(pkg): coupled_packages = \ [(couple.dataset_record.name, couple.dataset_record.title) \ for couple in coupled_resources \ - if couple.dataset_record_package_id and \ - couple.dataset_record and \ - couple.dataset_record.state == 'active'] + if couple.dataset_record_package_id] return coupled_packages From c771a76e3db77674414f9a9379ac2c2f7a0c6b2c Mon Sep 17 00:00:00 2001 From: David Read Date: Mon, 4 Feb 2013 16:03:50 +0000 Subject: [PATCH 023/114] Revert "#276 Coupled Resource table now gets updated during harvest." Reverting changes for "#276 Coupled Resource" on master as it is INSPIRE-specific. Moving to datagovuk/ckanext-spatial branch dgu. This reverts commit 01536873b9d5b44da3f2286c8b6b74378a2be246. Conflicts: ckanext/spatial/harvesters.py --- ckanext/spatial/bin/coupled_resources.py | 6 + ckanext/spatial/harvesters.py | 28 +-- ckanext/spatial/lib/coupled_resource.py | 153 +----------- .../tests/lib/test_coupled_resource.py | 233 +----------------- ckanext/spatial/tests/test_harvest.py | 23 +- test-core.ini | 14 +- 6 files changed, 20 insertions(+), 437 deletions(-) diff --git a/ckanext/spatial/bin/coupled_resources.py b/ckanext/spatial/bin/coupled_resources.py index f32de77..2cf981e 100644 --- a/ckanext/spatial/bin/coupled_resources.py +++ b/ckanext/spatial/bin/coupled_resources.py @@ -234,6 +234,8 @@ class CoupledResources(object): from ckanext.harvest.model import HarvestCoupledResource if dataset_harvest_object.harvest_source_reference != harvest_source_reference: + rev = model.repo.new_revision() + rev.author = 'Couple migration' dataset_harvest_object.harvest_source_reference = harvest_source_reference model.Session.commit() q = model.Session.query(HarvestCoupledResource) \ @@ -241,6 +243,8 @@ class CoupledResources(object): .filter_by(dataset_record_package_id=dataset_record.id) \ .filter_by(harvest_source_reference=harvest_source_reference) if q.count() == 0: + rev = model.repo.new_revision() + rev.author = 'Couple migration' obj = HarvestCoupledResource( service_record_package_id=service_record.id, dataset_record_package_id=dataset_record.id, @@ -267,6 +271,8 @@ class CoupledResources(object): harvest_object = harvest_objects[0] harvest_source_reference = harvest_object.harvest_source_reference + rev = model.repo.new_revision() + rev.author = 'Couple migration' obj = HarvestCoupledResource( dataset_record_package_id=dataset_record.id, harvest_source_reference=harvest_source_reference) diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 022a0b3..2f0b9d5 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -46,7 +46,6 @@ from ckanext.harvest.model import HarvestObject, HarvestGatherError, \ from ckanext.spatial.model import GeminiDocument from ckanext.spatial.lib.csw_client import CswService from ckanext.spatial.validation import Validators -from ckanext.spatial.lib.coupled_resource import extract_guid, update_coupled_resources log = logging.getLogger(__name__) @@ -155,7 +154,7 @@ class GeminiHarvester(SpatialHarvester): if debug_exception_mode: raise - def import_gemini_object(self, gemini_string, harvest_source_reference): + def import_gemini_object(self, gemini_string): '''Imports the Gemini metadata into CKAN. The harvest_source_reference is an ID that the harvest_source uses @@ -178,10 +177,6 @@ class GeminiHarvester(SpatialHarvester): # may raise Exception for errors package_dict = self.write_package_from_gemini_string(unicode_gemini_string) - if package_dict: - package = Session.query(Package).get(package_dict['id']) - update_coupled_resources(package, harvest_source_reference) - def write_package_from_gemini_string(self, content): '''Create or update a Package based on some content that has @@ -429,10 +424,11 @@ class GeminiHarvester(SpatialHarvester): self.obj.current = True self.obj.save() + assert gemini_guid == [e['value'] for e in package['extras'] if e['key'] == 'guid'][0] assert self.obj.id == [e['value'] for e in package['extras'] if e['key'] == 'harvest_object_id'][0] - return package # i.e. a package_dict + return package @classmethod def _process_responsible_organisation(cls, responsible_organisations): @@ -493,8 +489,7 @@ class GeminiHarvester(SpatialHarvester): counter = counter + 1 return None - @classmethod - def _extract_first_licence_url(cls, licences): + def _extract_first_licence_url(self, licences): '''Given a list of pieces of licence info, hunt for the first one which looks like a URL and return it. Otherwise returns None.''' for licence in licences: @@ -505,14 +500,6 @@ class GeminiHarvester(SpatialHarvester): def _create_package_from_data(self, package_dict, package = None): ''' - Given a package_dict describing a package, creates or updates - a package object. If you supply package then it will update it, - otherwise it will create a new one. - - Uses the logic layer to create it. - - Returns a package_dict of the resulting package. - {'name': 'council-owned-litter-bins', 'notes': 'Location of Council owned litter bins within Borough.', 'resources': [{'description': 'Resource locator', @@ -600,7 +587,6 @@ class GeminiHarvester(SpatialHarvester): return gemini_string, gemini_guid - class GeminiCswHarvester(GeminiHarvester, SingletonPlugin): ''' A Harvester for CSW servers @@ -647,9 +633,6 @@ class GeminiCswHarvester(GeminiHarvester, SingletonPlugin): # Create a new HarvestObject for this identifier obj = HarvestObject(guid=identifier, job=harvest_job, harvest_source_reference=guid) - # NB: Gemini uses GUID for the harvest_source_reference - # whereas INSPIRE specifies the Unique Resource - # Identifier obj.save() ids.append(obj.id) @@ -824,9 +807,6 @@ class GeminiWafHarvester(GeminiHarvester, SingletonPlugin): job=harvest_job, content=gemini_string, harvest_source_reference=url) - # NB: Gemini uses WAF URL for the - # harvest_source_reference whereas INSPIRE - # specifies the Unique Resource Identifier obj.save() ids.append(obj.id) diff --git a/ckanext/spatial/lib/coupled_resource.py b/ckanext/spatial/lib/coupled_resource.py index c266c77..abe97c2 100644 --- a/ckanext/spatial/lib/coupled_resource.py +++ b/ckanext/spatial/lib/coupled_resource.py @@ -1,17 +1,7 @@ import re -import logging - -from ckan.lib.base import json -from ckanext.harvest.model import HarvestCoupledResource -from ckan import model - -log = logging.getLogger(__name__) guid_matcher = None -class CoupledResourceParseError(Exception): - pass - def extract_guid(csw_url): '''Given a CSW GetRecordByID URL, identify the record\'s ID (GUID). Returns the GUID or None if it can\'t find it.''' @@ -42,147 +32,6 @@ def extract_gemini_harvest_source_reference(coupled_href): if not coupled_href.startswith('http'): return guid = extract_guid(coupled_href) - return guid or coupled_href.strip() + return guid or coupled_href -def extract_harvest_source_reference_from_coupled_resource(coupled_resource_dict): - '''Given a coupled_resource_dict, returns the harvest_source_reference. - - May raise CoupledResourceParseError. - ''' - href = coupled_resource_dict['href'] - if len(href) <> 1: - raise CoupledResourceParseError('Coupled resource href is not a list of 1: %r' % href) - href = href[0] - if not href.strip(): - raise CoupledResourceParseError('Coupled resource href is blank.') - ref = extract_gemini_harvest_source_reference(href) - if not ref: - raise CoupledResourceParseError('Coupled resource harvest source reference is blank') - return ref -def _package_name(package_or_none): - return package_or_none.name if package_or_none else None - -def update_coupled_resources(package, harvest_source_reference): - '''Update the harvest_coupled_resource_table with the details of this - harvested package\'s couplings. - - :param package: the Package object containing extra fields with couples - to update in the table. - :param harvest_source_reference: the ref of this package being harvested. - This is not relevant if it is a service record, but - essential if it is a dataset. - ''' - resource_type = package.extras['resource-type'] - if resource_type == 'service': - # When a service record is harvested, ensure the couples listed - # in it match the couples in the HarvestCoupledResource objects, - # ignoring their dataset values (they might be filled in or not). - pkg_couples_str = package.extras['coupled-resource'] - pkg_couples = json.loads(pkg_couples_str) - log.info('Service Record %s has %i coupled resources to update', - package.name, len(pkg_couples)) - - table_couples_matching_service = HarvestCoupledResource.get_by_service_record(package) - table_couples_not_matching_pkg = table_couples_matching_service.all() # cross them off as we go - - for pkg_couple in pkg_couples: - try: - ref = extract_harvest_source_reference_from_coupled_resource(pkg_couple) - except CoupledResourceParseError, e: - log.warn('Error parsing couple: %s Ignoring couple=%s', e, pkg_couple) - continue - # Match both service and ref - matching_table_couples = table_couples_matching_service.filter_by(harvest_source_reference=ref) - if matching_table_couples.count() > 0: - # Test: test_02_reharvest_existing_service - # Note down the matches so we don't delete them later - for matching_table_couple in matching_table_couples: - log.info('Service couple is already there (%s, %s, %s)', - package.name, ref, - _package_name(matching_table_couple.dataset_record)) - table_couples_not_matching_pkg.remove(matching_table_couple) - continue - # Match just ref with blank service - matching_table_couples = HarvestCoupledResource.get_by_harvest_source_reference(ref)\ - .filter_by(service_record=None) - if matching_table_couples.count() == 0: - # Test: test_06_harvest_service_not_matching_a_dataset - # create the row - obj = HarvestCoupledResource(service_record=package, - harvest_source_reference=ref) - model.Session.add(obj) - log.info('Ref is new for this service - adding (%s, %s, None)', - package.name, ref) - model.Session.commit() - else: - # Test: test_04_harvest_service_to_match_existing_dataset - for matching_table_couple in matching_table_couples: - # fill in the service value - matching_table_couple.service_record = package - log.info('Service filled into couple matching ref (%s, %s, %s)', - package.name, ref, - _package_name(matching_table_couple.dataset_record)) - model.Session.commit() - - # Delete service value for any table_couples not matching the package - # Test: test_08_reharvest_existing_service_to_delete_and_add_couples - for table_couple in table_couples_not_matching_pkg: - log.info('Service couple not matched - deleted service (%s->None, %s, %s)', - _package_name(table_couple.service_record), - ref, _package_name(table_couple.dataset_record)) - table_couple.service_record = None - model.Session.commit() - return - elif resource_type in ('dataset', 'series'): - # When a dataset (or dataset series) record is harvested, for its - # dataset_record_package_id there should be one ref - any with another - # ref is removed. And for the dataset_record_package_id and ref combo - # there should be one or more HarvestCoupledResource objects (with - # a service or without). - - # Couples where this dataset is under a different ref - # Test: test_07_reharvest_existing_dataset_but_with_changed_ref - ref = harvest_source_reference - assert ref - for couple in model.Session.query(HarvestCoupledResource) \ - .filter_by(dataset_record=package) \ - .filter(HarvestCoupledResource.harvest_source_reference!=ref): - log.info('Ref %s has been replaced for this dataset record with ' - '%s. Removing link to the dataset record (%s, %s, %s->None)', - couple.harvest_source_reference, ref, - _package_name(couple.service_record), - couple.harvest_source_reference, - _package_name(couple.dataset_record)) - couple.dataset_record = None - model.Session.commit() - - # Couples with this ref - for couple in HarvestCoupledResource.get_by_harvest_source_reference(ref): - if couple.dataset_record != package: - # Test: test_03_harvest_dataset_to_match_existing_service - log.info('Linking ref to this dataset record (%s, %s, %s->%s)', - _package_name(couple.service_record), - ref, - _package_name(couple.dataset_record), - package.name) - couple.dataset_record = package - model.Session.commit() - else: - # Test: test_01_reharvest_existing_dataset - log.info('Couple for this dataset and ref already exists (%s, %s, %s)', - _package_name(couple.service_record), - ref, - _package_name(couple.dataset_record)) - - # No couples for this ref - couples = HarvestCoupledResource.get_by_harvest_source_reference(ref) - if couples.count() == 0: - # Test: test_05_harvest_dataset_not_matching_a_service - obj = HarvestCoupledResource(dataset_record=package, - harvest_source_reference=ref) - model.Session.add(obj) - log.info('Ref is new - adding new dataset couple (None, %s, %s)', - ref, package.name) - model.Session.commit() - return diff --git a/ckanext/spatial/tests/lib/test_coupled_resource.py b/ckanext/spatial/tests/lib/test_coupled_resource.py index 0d8888d..b7c4948 100644 --- a/ckanext/spatial/tests/lib/test_coupled_resource.py +++ b/ckanext/spatial/tests/lib/test_coupled_resource.py @@ -1,15 +1,6 @@ from nose.tools import assert_equal -from pylons import config -from pprint import pprint - -from ckan.logic import get_action -from ckan.lib.create_test_data import CreateTestData -from ckan import model -from ckan.lib.base import json -from ckanext.harvest.model import HarvestSource, HarvestJob, HarvestObject, HarvestCoupledResource - -from ckanext.spatial.lib.coupled_resource import extract_guid, extract_gemini_harvest_source_reference, update_coupled_resources +from ckanext.spatial.lib.coupled_resource import extract_guid, extract_gemini_harvest_source_reference GOOD_CSW_RECORD = 'http://ogcdev.bgs.ac.uk/geonetwork/srv/en/csw?SERVICE=CSW&REQUEST=GetRecordById&ID=9df8df52-d788-37a8-e044-0003ba9b0d98&elementSetName=full&OutputSchema=http://www.isotc211.org/2005/gmd' GOOD_CSW_RECORD_ID = '9df8df52-d788-37a8-e044-0003ba9b0d98' @@ -33,225 +24,3 @@ def test_extract_gemini_harvest_source_reference(): GOOD_CSW_RECORD_ID) assert_equal(extract_guid(BAD_COUPLE), None) - -ref_prefix = 'http://waf/' - -class TestUpdateCoupledResources: - def setup(self): - # Create fixtures - CreateTestData.create_arbitrary([ - {'name': 'serviceA', - 'extras': {'coupled-resource': json.dumps( - [{'href': [ref_prefix+'Bref']}, - {'href': [ref_prefix+'Href']}, - {'href': [ref_prefix+'Eref']}]), - 'resource-type': 'service'}}, - {'name': 'serviceF', - 'extras': {'coupled-resource': json.dumps( - [{'href': [ref_prefix+'Dref']}]), - 'resource-type': 'service'}}, - {'name': 'serviceG', - 'extras': {'coupled-resource': json.dumps( - [{'href': [ref_prefix+'Gref']}]), - 'resource-type': 'service'}}, - {'name': 'datasetB', - 'extras': {'resource-type': 'dataset'}}, - {'name': 'datasetC', - 'extras': {'resource-type': 'dataset'}}, - {'name': 'datasetD', - 'extras': {'resource-type': 'dataset'}}, - {'name': 'datasetE', - 'extras': {'resource-type': 'dataset'}}, - {'name': 'datasetG', - 'extras': {'resource-type': 'dataset'}}, - {'name': 'datasetH', - 'extras': {'resource-type': 'dataset'}}, - {'name': 'serviceD', - 'extras': {'coupled-resource': json.dumps( - [{'href': [ref_prefix+'Dref']}]), - 'resource-type': 'service'}}, - ]) - self._create_user() - self._create_publisher() - self.source, self.job = self._create_source_and_job() - self._create_harvest_object('datasetB', ref='Bref') - self._create_harvest_object('datasetC', ref='Cref') - self._create_harvest_object('datasetD', ref='Dref') - self._create_harvest_object('datasetE', ref='Eref') - - # Create a partially-filled coupling table - self._create_coupled_resource('serviceA', 'Bref', 'datasetB') - self._create_coupled_resource('serviceA', 'Cref', 'datasetC') - self._create_coupled_resource(None, 'Dref', 'datasetD') - self._create_coupled_resource('serviceA', 'Eref', None) - self._create_coupled_resource('serviceF', 'Dref', 'datasetD') - - model.Session.commit() - model.Session.remove() - - self.couples_before = self._get_coupled_resources() - pprint(self.couples_before) - assert_equal(len(self.couples_before), 5) - - def teardown(self): - model.repo.rebuild_db() - - def test_01_reharvest_existing_dataset(self): - package = model.Package.by_name(u'datasetB') - update_coupled_resources(package, ref_prefix+'Bref') - assert_equal(self._get_coupled_resources(), self.couples_before) - - def test_02_reharvest_existing_service(self): - package = model.Package.by_name(u'serviceF') - update_coupled_resources(package, None) - assert_equal(self._get_coupled_resources(), self.couples_before) - - def test_03_harvest_dataset_to_match_existing_service(self): - package = model.Package.by_name(u'datasetE') - update_coupled_resources(package, ref_prefix+'Eref') - assert_equal(self._get_coupled_resources(), - change_line(self.couples_before, - (u'serviceA', u'Eref', None), - (u'serviceA', u'Eref', u'datasetE'))) - - def test_04_harvest_service_to_match_existing_dataset(self): - package = model.Package.by_name(u'serviceD') - update_coupled_resources(package, None) - assert_equal(self._get_coupled_resources(), - change_line(self.couples_before, - (None, u'Dref', u'datasetD'), - (u'serviceD', u'Dref', u'datasetD'))) - - def test_05_harvest_dataset_not_matching_a_service(self): - package = model.Package.by_name(u'datasetG') - update_coupled_resources(package, ref_prefix+'Gref') - assert_equal(self._get_coupled_resources(), - add_line(self.couples_before, - (None, u'Gref', u'datasetG'))) - - def test_06_harvest_service_not_matching_a_dataset(self): - package = model.Package.by_name(u'serviceG') - update_coupled_resources(package, None) - assert_equal(self._get_coupled_resources(), - add_line(self.couples_before, - (u'serviceG', u'Gref', None))) - - def test_07_reharvest_existing_dataset_but_with_changed_ref(self): - # This may occur only in a WAF. If a dataset is reharvested from - # a different WAF URL then the old WAF URL (and therefore ref) - # for that dataset becomes invalid. - # (A CSW may change a dataset's GUID, but it becomes a different - # datasets entirely if that happens) - package = model.Package.by_name(u'datasetB') - update_coupled_resources(package, ref_prefix+'Jref') - expected_couples = change_line(self.couples_before, - ('serviceA', u'Bref', 'datasetB'), - ('serviceA', u'Bref', None)) - expected_couples = add_line(expected_couples, - (None, u'Jref', 'datasetB')) - assert_equal(self._get_coupled_resources(), expected_couples) - - def test_08_reharvest_existing_service_to_delete_and_add_couples(self): - package = model.Package.by_name(u'serviceA') - update_coupled_resources(package, None) - expected_couples = change_line(self.couples_before, - ('serviceA', u'Cref', 'datasetC'), - (None, 'Cref', 'datasetC')) - expected_couples = add_line(expected_couples, - (u'serviceA', u'Href', None)) - print 'EXPECTED_COUPLES'; pprint(expected_couples) - print 'RESULT_COUPLES'; pprint(self._get_coupled_resources()) - assert_equal(self._get_coupled_resources(), - expected_couples) - - - def _get_coupled_resources(self): - return [(couple.service_record.name if couple.service_record else None, - couple.harvest_source_reference.replace(ref_prefix, ''), - couple.dataset_record.name if couple.dataset_record else None)\ - for couple in model.Session.query(HarvestCoupledResource)] - - def _create_coupled_resource(self, service_name, ref, dataset_name): - service = model.Package.by_name(unicode(service_name or '')) - dataset = model.Package.by_name(unicode(dataset_name or '')) - if service_name: assert service - if dataset_name: assert dataset - model.Session.add( - HarvestCoupledResource(service_record=service, - harvest_source_reference=ref_prefix+ref, - dataset_record=dataset) - ) - - def _create_harvest_object(self, package_name, ref): - package = model.Package.by_name(unicode(package_name)) - model.Session.add( - HarvestObject(guid='not important', - current=True, source=self.source, job=self.job, - harvest_source_reference=ref_prefix+ref, - package=package) - ) - - - def _create_user(self): - harvest_user = model.User(name=u'harvest', password=u'test') - model.add_user_to_role(harvest_user, model.Role.ADMIN, model.System()) - model.Session.add(harvest_user) - model.Session.commit() - - def _create_publisher(self): - self.publisher = model.Group(name=u'test-publisher', - title=u'Test Publihser', - type=u'publisher') - model.Session.add(self.publisher) - model.Session.commit() - - def _create_source_and_job(self): - context ={'model': model, - 'session': model.Session, - 'user': u'harvest'} - source_fixture = { - 'url': u'http://csw/GetCapabilities', - 'type': u'csw' - } - if config.get('ckan.harvest.auth.profile') == u'publisher' \ - and not 'publisher_id' in source_fixture: - source_fixture['publisher_id'] = self.publisher.id - - source_dict=get_action('harvest_source_create')(context,source_fixture) - source = HarvestSource.get(source_dict['id']) - assert source - - job = self._create_job(source.id) - - return source, job - - def _create_job(self,source_id): - # Create a job - context ={'model':model, - 'session':model.Session, - 'user':u'harvest'} - - job_dict=get_action('harvest_job_create')(context,{'source_id':source_id}) - job = HarvestJob.get(job_dict['id']) - assert job - - return job - -def change_line(couples, line_to_change, replacement_line): - '''Given a list of coupled resource tuples, returns a similar - list, but with the line that matches line_to_change replaced - with replacement_line.''' - line_number = couples.index(line_to_change) - return couples[:line_number] + [replacement_line] + couples[line_number+1:] - -def add_line(couples, line_to_add): - '''Given a list of coupled resource tuples, returns a similar - list, but with the line added.''' - return couples[:] + [line_to_add] - -def remove_line(couples, line_to_remove): - '''Given a list of coupled resource tuples, returns a similar - list, but with the line added.''' - line_number = couples.index(line_to_remove) - return couples[:line_number] + couples[line_number+1:] - diff --git a/ckanext/spatial/tests/test_harvest.py b/ckanext/spatial/tests/test_harvest.py index 0ca283b..df103e6 100644 --- a/ckanext/spatial/tests/test_harvest.py +++ b/ckanext/spatial/tests/test_harvest.py @@ -10,8 +10,7 @@ from ckan.model import Session,Package from ckan.logic.schema import default_update_package_schema from ckan.logic import get_action from ckanext.harvest.model import (setup as harvest_model_setup, - HarvestSource, HarvestJob, HarvestObject, - HarvestCoupledResource) + HarvestSource, HarvestJob, HarvestObject) from ckanext.spatial.validation import Validators, SchematronValidator from ckanext.spatial.harvesters import (GeminiCswHarvester, GeminiDocHarvester, GeminiWafHarvester, SpatialHarvester, @@ -262,18 +261,17 @@ class TestHarvest(HarvestFixtureBase): raise AssertionError('Unexpected value for extra %s: %s (was expecting %s)' % \ (key, package_dict['extras'][key], value)) - # Much of this depends on the particular WMS server working... expected_resource = { - #'ckan_recommended_wms_preview': 'True', + 'ckan_recommended_wms_preview': 'True', 'description': 'Link to the GetCapabilities request for this service', - #'format': 'WMS', + 'format': 'WMS', 'name': 'Web Map Service (WMS)', 'resource_locator_function': 'download', 'resource_locator_protocol': 'OGC:WMS-1.3.0-http-get-capabilities', 'resource_type': None, 'size': None, 'url': u'http://sedsh13.sedsh.gov.uk/ArcGIS/services/OSG/OSG/MapServer/WMSServer?request=GetCapabilities&service=WMS', - #'verified': 'True', + 'verified': 'True', } resource = package_dict['resources'][0] @@ -281,18 +279,7 @@ class TestHarvest(HarvestFixtureBase): if not resource[key] == value: raise AssertionError('Unexpected value in resource for %s: %s (was expecting %s)' % \ (key, resource[key], value)) - #assert datetime.strptime(resource['verified_date'],'%Y-%m-%dT%H:%M:%S.%f').date() == date.today() - - # See that the coupled resources are created (half of the link) - coupled_resources = self._get_coupled_resources() - assert_equal(coupled_resources, - set([(u'one-scotland-address-gazetteer-web-map-service-wms', '250ea276-48e2-4189-8a89-fcc4ca92d652', None)])) - - def _get_coupled_resources(self): - return set([(couple.service_record.name if couple.service_record else None, - couple.harvest_source_reference, - couple.dataset_record.name if couple.dataset_record else None)\ - for couple in model.Session.query(HarvestCoupledResource)]) + assert datetime.strptime(resource['verified_date'],'%Y-%m-%dT%H:%M:%S.%f').date() == date.today() def test_harvest_fields_dataset(self): diff --git a/test-core.ini b/test-core.ini index 4ad5086..5f80bb6 100644 --- a/test-core.ini +++ b/test-core.ini @@ -26,7 +26,7 @@ ckan.spatial.validator.profiles = iso19139,constraints,gemini2 # Logging configuration [loggers] -keys = root, ckan, sqlalchemy, ckanext +keys = root, ckan, sqlalchemy [handlers] keys = console @@ -40,21 +40,13 @@ handlers = console [logger_ckan] qualname = ckan -handlers = console +handlers = level = INFO -propagate = 0 - -[logger_ckanext] -qualname = ckanext -handlers = console -level = DEBUG -propagate = 0 [logger_sqlalchemy] -handlers = console +handlers = qualname = sqlalchemy.engine level = WARN -propagate = 0 [handler_console] class = StreamHandler From f4e3cfad00e01cb6ce411fe5a6ed5b2d380ad8ff Mon Sep 17 00:00:00 2001 From: David Read Date: Mon, 4 Feb 2013 16:07:03 +0000 Subject: [PATCH 024/114] Revert "#276 Coupled resources - second iteration. Just need to update harvester now." Reverting changes for "#276 Coupled Resource" on master as it is INSPIRE-specific. Moving to datagovuk/ckanext-spatial branch dgu. This reverts commit ecd6036efe85e9246eeab75099eac62086dd2425. --- ckanext/spatial/bin/coupled_resources.py | 92 +++++------------------- ckanext/spatial/lib/helpers.py | 51 +++++++++---- 2 files changed, 57 insertions(+), 86 deletions(-) diff --git a/ckanext/spatial/bin/coupled_resources.py b/ckanext/spatial/bin/coupled_resources.py index 2cf981e..95f5770 100644 --- a/ckanext/spatial/bin/coupled_resources.py +++ b/ckanext/spatial/bin/coupled_resources.py @@ -12,12 +12,15 @@ from pylons import config from nose.tools import assert_equal from lxml import etree +from ckan.lib.base import json +from ckanext.spatial.model import GeminiDocument +from ckanext.spatial.lib.coupled_resource import extract_guid + from ckanext.dgu.bin import common from ckanext.dgu.bin.running_stats import StatsList service_stats = StatsList() couple_stats = StatsList() -additional_couple_stats = StatsList() class FindError(Exception): pass @@ -28,12 +31,9 @@ class CoupledResources(object): '''Finds datasets that are coupled and adds their harvest_source_reference to the HarvestObject and package extras. ''' - from ckan.lib.base import json from ckan import model from ckanext.harvest.model import HarvestObject - from ckanext.spatial.model import GeminiDocument - from ckanext.spatial.lib.coupled_resource import extract_guid - + # Find service records for service_record in model.Session.query(model.Package).\ filter_by(state='active').\ @@ -42,6 +42,16 @@ class CoupledResources(object): filter_by(key='resource-type').\ filter_by(value='service'): + ## # Get HarvestObject + ## harvest_object_id = service_record.extras.get('harvest_object_id') + ## if not harvest_object_id: + ## service_stats.add('No harvest_object_id', service_record.name) + ## continue + ## harvest_object = HarvestObject.get(harvest_object_id) + ## if not harvest_object: + ## service_stats.add('No harvest_object found for id', service_record.name) + ## continue + # Find coupled dataset records service_type = service_record.extras['resource-type'] if not 'coupled-resource' in service_record.extras: @@ -101,7 +111,7 @@ class CoupledResources(object): log.info('Couple completed %s <-> %s', service_record.name, dataset_record.name) - cls.add_coupling(service_record, dataset_record, harvest_object, guid) + cls.add_coupling(harvest_object, guid) couples_detected = True continue @@ -173,7 +183,7 @@ class CoupledResources(object): log.info('Couple completed %s <-> %s', service_record.name, dataset_record.name) - cls.add_coupling(service_record, dataset_record, harvest_object, href) + cls.add_coupling(harvest_object, href) couples_detected = True if coupled_resources: @@ -191,24 +201,11 @@ class CoupledResources(object): continue model.Session.remove() - - # Ensure all dataset records are in the harvest_coupled_resource table - # for future reference - for dataset_record in model.Session.query(model.Package).\ - filter_by(state='active').\ - join(model.PackageExtra).\ - filter_by(state='active').\ - filter_by(key='resource-type').\ - filter(model.PackageExtra.value.in_(('dataset', 'series'))): - cls.ensure_dataset_is_in_couple_table(dataset_record) - model.Session.remove() - + print "\nServices:" print service_stats.report() print "\nCouples:" print couple_stats.report() - print "\nAdditional datasets added to couple table:" - print additional_couple_stats.report() @classmethod def find_harvest_object_by_guid(cls, guid): @@ -228,64 +225,13 @@ class CoupledResources(object): @classmethod - def add_coupling(cls, service_record, dataset_record, - dataset_harvest_object, harvest_source_reference): + def add_coupling(cls, dataset_harvest_object, harvest_source_reference): from ckan import model - from ckanext.harvest.model import HarvestCoupledResource - if dataset_harvest_object.harvest_source_reference != harvest_source_reference: rev = model.repo.new_revision() rev.author = 'Couple migration' dataset_harvest_object.harvest_source_reference = harvest_source_reference model.Session.commit() - q = model.Session.query(HarvestCoupledResource) \ - .filter_by(service_record_package_id=service_record.id) \ - .filter_by(dataset_record_package_id=dataset_record.id) \ - .filter_by(harvest_source_reference=harvest_source_reference) - if q.count() == 0: - rev = model.repo.new_revision() - rev.author = 'Couple migration' - obj = HarvestCoupledResource( - service_record_package_id=service_record.id, - dataset_record_package_id=dataset_record.id, - harvest_source_reference=harvest_source_reference) - model.Session.add(obj) - model.Session.commit() - - @classmethod - def ensure_dataset_is_in_couple_table(cls, dataset_record): - from ckan import model - from ckanext.harvest.model import HarvestCoupledResource - - q = model.Session.query(HarvestCoupledResource) \ - .filter_by(dataset_record_package_id=dataset_record.id) - if q.count() == 0: - harvest_objects = [ho for ho in dataset_record.harvest_objects \ - if ho.current] - if len(harvest_objects) != 1: - log.warning('Wrong num of current harvest_objects (%i)', - len(harvest_objects)) - additional_couple_stats.add('Wrong num of harvest_objects (%i)' % len(harvest_objects), - dataset_record.name) - return - harvest_object = harvest_objects[0] - harvest_source_reference = harvest_object.harvest_source_reference - - rev = model.repo.new_revision() - rev.author = 'Couple migration' - obj = HarvestCoupledResource( - dataset_record_package_id=dataset_record.id, - harvest_source_reference=harvest_source_reference) - model.Session.add(obj) - model.Session.commit() - additional_couple_stats.add('Added to couple table', - dataset_record.name) - log.info('Added to couple table: %s', dataset_record.name) - else: - additional_couple_stats.add('Already in couple table', - dataset_record.name) - log.info('Already in couple table: %s', dataset_record.name) - @classmethod def setup_logging(cls, config_ini_filepath): diff --git a/ckanext/spatial/lib/helpers.py b/ckanext/spatial/lib/helpers.py index 9bd8abd..05f043d 100644 --- a/ckanext/spatial/lib/helpers.py +++ b/ckanext/spatial/lib/helpers.py @@ -2,25 +2,50 @@ from ckan import model from ckan.lib.base import json -from ckanext.harvest.model import HarvestObject, HarvestCoupledResource +from ckanext.harvest.model import HarvestObject from ckanext.spatial.lib.coupled_resource import extract_gemini_harvest_source_reference -def get_coupled_packages(pkg): - res_type = pkg.extras.get('resource-type') +def get_coupled_packages(pkg_extras): + res_type = pkg_extras.get('resource-type') if res_type in ('dataset', 'series'): - coupled_resources = pkg.coupled_service - coupled_packages = \ - [(couple.service_record.name, couple.service_record.title) \ - for couple in coupled_resources \ - if couple.service_record_package_id] + coupled_packages = [] + # Find the service records which point to this dataset record + harvest_object_id = pkg_extras.get('harvest_object_id') + if not harvest_object_id: + return coupled_packages + harvest_object = HarvestObject.get(harvest_object_id) + dataset_ref = harvest_object.harvest_source_reference + if not dataset_ref: + return coupled_packages # [] + q = model.Session.query(model.Package) \ + .join(model.PackageExtra) \ + .join(HarvestObject) \ + .filter(HarvestObject.current==True) \ + .filter(model.PackageExtra.key=='coupled-resource') \ + .filter(model.PackageExtra.value.like('%' + dataset_ref + '%')) + # probably 0, 1 or 2 results if there is a view and download service. + coupled_packages.extend([(pkg.name, pkg.title) for pkg in q.all()]) return coupled_packages elif res_type == 'service': # Find the dataset records which are pointed to in this service record - coupled_resources = pkg.coupled_dataset - coupled_packages = \ - [(couple.dataset_record.name, couple.dataset_record.title) \ - for couple in coupled_resources \ - if couple.dataset_record_package_id] + coupled_resources_str = pkg_extras.get('coupled-resource', '[]') + coupled_resources = json.loads(coupled_resources_str) + coupled_packages = [] + for coupled_resource in coupled_resources: + hrefs = coupled_resource.get('href', '') + href = hrefs[0].strip() + harvest_source_reference = extract_gemini_harvest_source_reference(href) + if not harvest_source_reference: + continue + q = model.Session.query(model.Package) \ + .join(HarvestObject) \ + .filter(HarvestObject.current==True) \ + .filter(HarvestObject.harvest_source_reference==harvest_source_reference) \ + .filter(model.Package.state==u'active') + # probably 0 or 1 results, but there is the possibility + # WAFs lead to multiple results. Just add them all in that case. + coupled_packages.extend([(pkg.name, pkg.title) for pkg in q.all()]) return coupled_packages + From c6ac9494a2123181ae55ce8df4e16c0e2070a92d Mon Sep 17 00:00:00 2001 From: David Read Date: Mon, 4 Feb 2013 16:07:19 +0000 Subject: [PATCH 025/114] Revert "#276 Coupled resources - first iteration." Reverting changes for "#276 Coupled Resource" on master as it is INSPIRE-specific. Moving to datagovuk/ckanext-spatial branch dgu. This reverts commit 91e547a6221dd7b7f98bbd40c9746c7c32861106. --- ckanext/spatial/bin/__init__.py | 0 ckanext/spatial/bin/coupled_resources.py | 272 ------------------ ckanext/spatial/harvesters.py | 15 +- ckanext/spatial/lib/coupled_resource.py | 37 --- ckanext/spatial/lib/helpers.py | 51 ---- .../tests/lib/test_coupled_resource.py | 26 -- 6 files changed, 5 insertions(+), 396 deletions(-) delete mode 100644 ckanext/spatial/bin/__init__.py delete mode 100644 ckanext/spatial/bin/coupled_resources.py delete mode 100644 ckanext/spatial/lib/coupled_resource.py delete mode 100644 ckanext/spatial/lib/helpers.py delete mode 100644 ckanext/spatial/tests/lib/test_coupled_resource.py diff --git a/ckanext/spatial/bin/__init__.py b/ckanext/spatial/bin/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/ckanext/spatial/bin/coupled_resources.py b/ckanext/spatial/bin/coupled_resources.py deleted file mode 100644 index 95f5770..0000000 --- a/ckanext/spatial/bin/coupled_resources.py +++ /dev/null @@ -1,272 +0,0 @@ -''' -Coupled Resources migration tool -''' - -import re -import os -import logging -import sys -import requests - -from pylons import config -from nose.tools import assert_equal -from lxml import etree - -from ckan.lib.base import json -from ckanext.spatial.model import GeminiDocument -from ckanext.spatial.lib.coupled_resource import extract_guid - -from ckanext.dgu.bin import common -from ckanext.dgu.bin.running_stats import StatsList - -service_stats = StatsList() -couple_stats = StatsList() - -class FindError(Exception): - pass - -class CoupledResources(object): - @classmethod - def detect(cls): - '''Finds datasets that are coupled and adds their - harvest_source_reference to the HarvestObject and package extras. - ''' - from ckan import model - from ckanext.harvest.model import HarvestObject - - # Find service records - for service_record in model.Session.query(model.Package).\ - filter_by(state='active').\ - join(model.PackageExtra).\ - filter_by(state='active').\ - filter_by(key='resource-type').\ - filter_by(value='service'): - - ## # Get HarvestObject - ## harvest_object_id = service_record.extras.get('harvest_object_id') - ## if not harvest_object_id: - ## service_stats.add('No harvest_object_id', service_record.name) - ## continue - ## harvest_object = HarvestObject.get(harvest_object_id) - ## if not harvest_object: - ## service_stats.add('No harvest_object found for id', service_record.name) - ## continue - - # Find coupled dataset records - service_type = service_record.extras['resource-type'] - if not 'coupled-resource' in service_record.extras: - if service_type in ('view', 'download'): - service_stats.add('No coupled-resource extra for %s type (where it is mandatory)', service_record.name, service_type) - else: - service_stats.add('No coupled-resource extra (but not mandatory for this service type)', service_record.name) - continue - coupled_resources_str = service_record.extras['coupled-resource'] - coupled_resources = json.loads(coupled_resources_str) - log.info('%s has %i coupled resources', - service_record.name, len(coupled_resources)) - couples_all_detected = True - couples_detected = False - for i, coupled_resource in enumerate(coupled_resources): - couple_id = '%s.%s' % (service_record.name, i) - href = coupled_resource['href'] - - # For tests only - #if href != ['http://www.ordnancesurvey.co.uk/oswebsite/xml/products/Topo.xml']: - # break - - if len(href) <> 1: - log.error('Coupled resource href is not a list of 1: %r couple=%s', - href, couple_id) - couple_stats.add('Couple href is length %i' % len(href), couple_id) - couples_all_detected = False - continue - href = href[0] - if not href.strip(): - log.error('Coupled resource href is blank. couple=%s', - couple_id) - couple_stats.add('Couple href is blank', couple_id) - couples_all_detected = False - continue - - # Look for the equivalent dataset resource - - # If it is CSW, we must extract the guid - # Example CSW url: http://ogcdev.bgs.ac.uk/geonetwork/srv/en/csw?SERVICE=CSW&REQUEST=GetRecordById&ID=9df8df52-d788-37a8-e044-0003ba9b0d98&elementSetName=full&OutputSchema=http://www.isotc211.org/2005/gmd - guid = extract_guid(href) - if guid: - if not guid.strip(): - couple_stats.add('Guid was blank', couple_id) - log.error('Guid was blank. href=%s', href, couple_id) - - try: - harvest_object = cls.find_harvest_object_by_guid(guid) - except FindError, e: - log.error('%s guid=%s couple=%s', e, guid, couple_id) - couple_stats.add(str(e), couple_id) - couples_all_detected = False - continue - - dataset_record = harvest_object.package #res.resource_group.package - couple_stats.add('Couple completed', couple_id) - log.info('Couple completed %s <-> %s', - service_record.name, dataset_record.name) - - cls.add_coupling(harvest_object, guid) - couples_detected = True - continue - - # Known bad couples are weeded out - bad_couples = ('GetCapabilities', 'CEH:EIDC', - 'ceh:eidc', - 'http://data.nbn.org.uk#', - 'www.geostore.com/OGC/OGCInterface', - 'spatialni.gov.uk/arcgis/services/LPS/CadastreNI/MapServer/WMSServer', - 'Please enter a valid url', - ) - bad_couple_detected = False - for bad_couple in bad_couples: - if bad_couple in href: - couple_stats.add('Invalid couple (%s)' % bad_couple, couple_id) - log.info('Invalid couple (%s): %s couple=%s', bad_couple, href, couple_id) - bad_couple_detected = True - if bad_couple_detected: - couples_all_detected = False - continue - - # Try as a WAF - # Try the URL to download the gemini again, to find the - # GUID of the dataset - log.info('Trying possible WAF href: %s' % href) - try: - res = requests.get(href, timeout=10) - except Exception, e: - couple_stats.add('Connecting to href failed: %s' % \ - e, couple_id) - log.warning('Connecting to href failed: %s href:"%s"', \ - e, href) - couples_all_detected = False - break - if not res.ok: - couple_stats.add('Resolving href failed: %s' % \ - res.reason, couple_id) - log.warning('Resolving href failed: %s %s href:"%s"', \ - res.status_code, res.reason, href) - couples_all_detected = False - break - gemini = GeminiDocument(res.content) - try: - guid = gemini.read_value('guid') - except KeyError, e: - couple_stats.add('Could not get GUID from Gemini downloaded' % \ - href, couple_id) - log.warning('Could not get GUID from Gemini downloaded href:"%s"', \ - href) - couples_all_detected = False - break - except etree.XMLSyntaxError, e: - couple_stats.add('Could not parse "Gemini" downloaded', - couple_id) - log.warning('Could not parse "Gemini" downloaded href:"%s"', \ - href) - couples_all_detected = False - break - try: - harvest_object = cls.find_harvest_object_by_guid(guid) - except FindError, e: - log.error('%s href=%s couple=%s', e, href, couple_id) - couple_stats.add(str(e), couple_id) - couples_all_detected = False - continue - - dataset_record = harvest_object.package #res.resource_group.package - couple_stats.add('Couple completed', couple_id) - log.info('Couple completed %s <-> %s', - service_record.name, dataset_record.name) - - cls.add_coupling(harvest_object, href) - couples_detected = True - - if coupled_resources: - if couples_all_detected: - service_stats.add('Service couples all completed', service_record.name) - elif couples_detected: - service_stats.add('Service couples partially completed', service_record.name) - else: - service_stats.add('Service couples not completed', service_record.name) - else: - if service_type in ('view', 'download'): - service_stats.add('No couples for %s type (where it is mandatory)', service_record.name, service_type) - else: - service_stats.add('No couples (but not mandatory for service type %s)' % service_type, service_record.name) - continue - - model.Session.remove() - - print "\nServices:" - print service_stats.report() - print "\nCouples:" - print couple_stats.report() - - @classmethod - def find_harvest_object_by_guid(cls, guid): - from ckan import model - from ckanext.harvest.model import HarvestObject - - q = model.Session.query(HarvestObject).\ - filter_by(guid=guid).\ - filter_by(current=True) - if q.count() == 0: - raise FindError('No matches for guid') - if q.count() <> 1: - raise FindError('Wrong number of matches (%i) for guid' % \ - q.count()) - harvest_object = q.one() - return harvest_object - - - @classmethod - def add_coupling(cls, dataset_harvest_object, harvest_source_reference): - from ckan import model - if dataset_harvest_object.harvest_source_reference != harvest_source_reference: - rev = model.repo.new_revision() - rev.author = 'Couple migration' - dataset_harvest_object.harvest_source_reference = harvest_source_reference - model.Session.commit() - - @classmethod - def setup_logging(cls, config_ini_filepath): - logging.config.fileConfig(config_ini_filepath) - global log - log = logging.getLogger(os.path.basename(__file__)) - - -warnings = [] -log = None -def warn(msg, *params): - global warnings - warnings.append(msg % params) - global_log.warn(msg, *params) - - -def usage(): - print """ -Coupled Resources tool -Usage: - - python coupled_resources.py detect - - finds datasets that are coupled and adds their harvest_source_reference - """ - -if __name__ == '__main__': - if len(sys.argv) != 3: - print 'Wrong number of arguments %i' % len(sys.argv) - usage() - sys.exit(0) - cmd, config_ini, action = sys.argv - common.load_config(config_ini) - CoupledResources.setup_logging(config_ini) - common.register_translator() - if action == 'detect': - CoupledResources.detect() - else: - raise NotImplementedError diff --git a/ckanext/spatial/harvesters.py b/ckanext/spatial/harvesters.py index 2f0b9d5..8ab5620 100644 --- a/ckanext/spatial/harvesters.py +++ b/ckanext/spatial/harvesters.py @@ -141,8 +141,7 @@ class GeminiHarvester(SpatialHarvester): self._save_object_error('Empty content for object %s' % harvest_object.id,harvest_object,'Import') return False try: - self.import_gemini_object(harvest_object.content, - harvest_object.harvest_source_reference) + self.import_gemini_object(harvest_object.content) return True except Exception, e: log.error('Exception during import: %s' % text_traceback()) @@ -260,8 +259,7 @@ class GeminiHarvester(SpatialHarvester): extras = { 'UKLP': 'True', - 'harvest_object_id': self.obj.id, - 'harvest_source_reference': self.obj.harvest_source_reference, + 'harvest_object_id': self.obj.id } # Just add some of the metadata as extras, not the whole lot @@ -631,8 +629,7 @@ class GeminiCswHarvester(GeminiHarvester, SingletonPlugin): continue # Create a new HarvestObject for this identifier - obj = HarvestObject(guid=identifier, job=harvest_job, - harvest_source_reference=guid) + obj = HarvestObject(guid=identifier, job=harvest_job) obj.save() ids.append(obj.id) @@ -732,8 +729,7 @@ class GeminiDocHarvester(GeminiHarvester, SingletonPlugin): # have it, we might as well save a request obj = HarvestObject(guid=gemini_guid, job=harvest_job, - content=gemini_string, - harvest_source_reference=gemini_string) + content=gemini_string) obj.save() log.info('Got GUID %s' % gemini_guid) @@ -805,8 +801,7 @@ class GeminiWafHarvester(GeminiHarvester, SingletonPlugin): # have it, we might as well save a request obj = HarvestObject(guid=gemini_guid, job=harvest_job, - content=gemini_string, - harvest_source_reference=url) + content=gemini_string) obj.save() ids.append(obj.id) diff --git a/ckanext/spatial/lib/coupled_resource.py b/ckanext/spatial/lib/coupled_resource.py deleted file mode 100644 index abe97c2..0000000 --- a/ckanext/spatial/lib/coupled_resource.py +++ /dev/null @@ -1,37 +0,0 @@ -import re - -guid_matcher = None - -def extract_guid(csw_url): - '''Given a CSW GetRecordByID URL, identify the record\'s ID (GUID). - Returns the GUID or None if it can\'t find it.''' - # Example CSW url: http://ogcdev.bgs.ac.uk/geonetwork/srv/en/csw?SERVICE=CSW&REQUEST=GetRecordById&ID=9df8df52-d788-37a8-e044-0003ba9b0d98&elementSetName=full&OutputSchema=http://www.isotc211.org/2005/gmd - if not guid_matcher: - global guid_matcher - guid_matcher = re.compile('id=\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})', flags=re.IGNORECASE) - guid_match = guid_matcher.search(csw_url) - if guid_match: - return guid_match.groups()[0] - -def extract_gemini_harvest_source_reference(coupled_href): - '''Given the href in the Coupled Resource (srv:operatesOn xlink:href) - this function returns the 'harvest_source_reference' identifier for - the coupled dataset record. - - This follows the Gemini Encoding Guidance 2.1, which differs from - the INSPIRE guidance: - - The value of the XLink attribute, as shown in the INSPIRE technical - guidance, is the value of the metadata item Unique Resource - Identifier. However, the guidance for GEMINI metadata is different. - The value of the attribute shall be a URL that - allows access to an unambiguous metadata instance, which may be: - * an OGC CS-W GetRecordById request - * an address of a metadata instance in a WAF - ''' - if not coupled_href.startswith('http'): - return - guid = extract_guid(coupled_href) - return guid or coupled_href - - diff --git a/ckanext/spatial/lib/helpers.py b/ckanext/spatial/lib/helpers.py deleted file mode 100644 index 05f043d..0000000 --- a/ckanext/spatial/lib/helpers.py +++ /dev/null @@ -1,51 +0,0 @@ -# template helpers - -from ckan import model -from ckan.lib.base import json -from ckanext.harvest.model import HarvestObject -from ckanext.spatial.lib.coupled_resource import extract_gemini_harvest_source_reference - -def get_coupled_packages(pkg_extras): - res_type = pkg_extras.get('resource-type') - if res_type in ('dataset', 'series'): - coupled_packages = [] - # Find the service records which point to this dataset record - harvest_object_id = pkg_extras.get('harvest_object_id') - if not harvest_object_id: - return coupled_packages - harvest_object = HarvestObject.get(harvest_object_id) - dataset_ref = harvest_object.harvest_source_reference - if not dataset_ref: - return coupled_packages # [] - q = model.Session.query(model.Package) \ - .join(model.PackageExtra) \ - .join(HarvestObject) \ - .filter(HarvestObject.current==True) \ - .filter(model.PackageExtra.key=='coupled-resource') \ - .filter(model.PackageExtra.value.like('%' + dataset_ref + '%')) - # probably 0, 1 or 2 results if there is a view and download service. - coupled_packages.extend([(pkg.name, pkg.title) for pkg in q.all()]) - return coupled_packages - - elif res_type == 'service': - # Find the dataset records which are pointed to in this service record - coupled_resources_str = pkg_extras.get('coupled-resource', '[]') - coupled_resources = json.loads(coupled_resources_str) - coupled_packages = [] - for coupled_resource in coupled_resources: - hrefs = coupled_resource.get('href', '') - href = hrefs[0].strip() - harvest_source_reference = extract_gemini_harvest_source_reference(href) - if not harvest_source_reference: - continue - q = model.Session.query(model.Package) \ - .join(HarvestObject) \ - .filter(HarvestObject.current==True) \ - .filter(HarvestObject.harvest_source_reference==harvest_source_reference) \ - .filter(model.Package.state==u'active') - # probably 0 or 1 results, but there is the possibility - # WAFs lead to multiple results. Just add them all in that case. - coupled_packages.extend([(pkg.name, pkg.title) for pkg in q.all()]) - return coupled_packages - - diff --git a/ckanext/spatial/tests/lib/test_coupled_resource.py b/ckanext/spatial/tests/lib/test_coupled_resource.py deleted file mode 100644 index b7c4948..0000000 --- a/ckanext/spatial/tests/lib/test_coupled_resource.py +++ /dev/null @@ -1,26 +0,0 @@ -from nose.tools import assert_equal - -from ckanext.spatial.lib.coupled_resource import extract_guid, extract_gemini_harvest_source_reference - -GOOD_CSW_RECORD = 'http://ogcdev.bgs.ac.uk/geonetwork/srv/en/csw?SERVICE=CSW&REQUEST=GetRecordById&ID=9df8df52-d788-37a8-e044-0003ba9b0d98&elementSetName=full&OutputSchema=http://www.isotc211.org/2005/gmd' -GOOD_CSW_RECORD_ID = '9df8df52-d788-37a8-e044-0003ba9b0d98' -BAD_CSW_RECORD = 'http://www.geostore.com/OGC/OGCInterface?INTERFACE=ENVIRONMENT&UID=def&PASSWORD=abc&LC=ffe0000000&' -WAF_ITEM = 'http://www.ordnancesurvey.co.uk/oswebsite/xml/products/Topo.xml' -BAD_COUPLE = 'CEH:EIDC:#1279200030617' # would be ok for INSPIRE, but not Gemini - -def test_extract_guid__ok(): - assert_equal(extract_guid(GOOD_CSW_RECORD), GOOD_CSW_RECORD_ID) - assert_equal(extract_guid(GOOD_CSW_RECORD.lower()), GOOD_CSW_RECORD_ID) - -def test_extract_guid__bad(): - assert_equal(extract_guid(BAD_CSW_RECORD), None) - assert_equal(extract_guid(''), None) - assert_equal(extract_guid(' '), None) - -def test_extract_gemini_harvest_source_reference(): - assert_equal(extract_gemini_harvest_source_reference(WAF_ITEM), - WAF_ITEM) - assert_equal(extract_gemini_harvest_source_reference(GOOD_CSW_RECORD), - GOOD_CSW_RECORD_ID) - assert_equal(extract_guid(BAD_COUPLE), - None) From 5aeaa209ed0cce2e5c47bb0eea60db80131a0356 Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 20 Feb 2013 12:09:50 +0000 Subject: [PATCH 026/114] Fix bug in spatial query sorting --- ckanext/spatial/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ckanext/spatial/plugin.py b/ckanext/spatial/plugin.py index c190f52..2b176be 100644 --- a/ckanext/spatial/plugin.py +++ b/ckanext/spatial/plugin.py @@ -129,7 +129,7 @@ class SpatialQuery(SingletonPlugin): if not bbox: raise SearchError('Wrong bounding box provided') - if search_params['sort'] == 'spatial desc': + if 'sort' in search_params and search_params['sort'] == 'spatial desc': if search_params['q'] or search_params['fq']: raise SearchError('Spatial ranking cannot be mixed with other search parameters') # ...because it is too inefficient to use SOLR to filter From f795a33ac52cf8380a8c36a20fa29375aa5fb85e Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 7 Mar 2013 15:19:40 +0000 Subject: [PATCH 027/114] [#12] Fix wrong geometry type in 'Setting up a spatial table' section of README --- README.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 7e1db6f..493cde7 100644 --- a/README.rst +++ b/README.rst @@ -527,7 +527,7 @@ added via the ``AddGeometryColumn`` function:: ALTER TABLE package_extent OWNER TO [your_user]; - SELECT AddGeometryColumn('package_extent','the_geom', 4326, 'POLYGON', 2); + SELECT AddGeometryColumn('package_extent','the_geom', 4326, 'GEOMETRY', 2); This will add a geometry column in the ``package_extent`` table called ``the_geom``, with the spatial reference system EPSG:4326. The stored @@ -549,7 +549,6 @@ defined in the geometry column creation:: "package_extent_pkey" PRIMARY KEY, btree (package_id) Check constraints: "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2) - "enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'POLYGON'::text OR the_geom IS NULL) "enforce_srid_the_geom" CHECK (st_srid(the_geom) = 4326) Installing libxml2 From a2f95f4da4d5eb3e2e77ed57793bc171d0098c52 Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 10 Apr 2013 17:37:33 +0100 Subject: [PATCH 028/114] First docs draft --- doc/conf.py | 252 +++++++++++++++++++++++++++++++++++++++++ doc/dataset-map.rst | 9 ++ doc/index.ckan | 19 ++++ doc/index.rst | 50 ++++++++ doc/spatial-search.rst | 65 +++++++++++ 5 files changed, 395 insertions(+) create mode 100644 doc/conf.py create mode 100644 doc/dataset-map.rst create mode 100644 doc/index.ckan create mode 100644 doc/index.rst create mode 100644 doc/spatial-search.rst diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000..ea722e3 --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,252 @@ +# -*- coding: utf-8 -*- +# +# ckanext-spatial documentation build configuration file, created by +# sphinx-quickstart on Wed Apr 10 17:17:12 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.pngmath'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'ckanext-spatial' +copyright = u'2013, Open Knowledge Foundation' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.1' +# The full version, including alpha/beta/rc tags. +release = '0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'ckanext-spatialdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'ckanext-spatial.tex', u'ckanext-spatial Documentation', + u'Open Knowledge Foundation', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'ckanext-spatial', u'ckanext-spatial Documentation', + [u'Open Knowledge Foundation'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'ckanext-spatial', u'ckanext-spatial Documentation', + u'Open Knowledge Foundation', 'ckanext-spatial', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/dataset-map.rst b/doc/dataset-map.rst new file mode 100644 index 0000000..92dd43e --- /dev/null +++ b/doc/dataset-map.rst @@ -0,0 +1,9 @@ +Dataset Extent Map +------------------ + +To enable the dataset map you need to add the `dataset_extent_map` plugin to your +ini file (See `Configuration`_). You need to load the `spatial_metadata` plugin also. + +When the plugin is enabled, if datasets contain a 'spatial' extra like the one +described in the previous section, a map will be shown on the dataset details page. + diff --git a/doc/index.ckan b/doc/index.ckan new file mode 100644 index 0000000..67b8e99 --- /dev/null +++ b/doc/index.ckan @@ -0,0 +1,19 @@ +=============================== +Welcome to ckanext-spatial docs +=============================== + + +SPATIAL!! + +.. note :: + + This is the documentation for CKAN version '|version|'. If you are using a different version, use the links on the bottom right corner of the page to select the appropriate documentation. + +This Administration Guide covers how to set up and manage `CKAN `_ software. + +* The first two sections cover your two options for installing CKAN: package or source install. +* The rest of the first half of the Guide, up to :doc:`authorization`, covers setup and basic admin. +* The second half of the Guide, from :doc:`extensions` onwards, covers advanced tasks, including extensions and forms. + +For high-level information on what CKAN is, see the `CKAN website `_. + diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..60b2822 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,50 @@ +.. ckanext-spatial documentation master file, created by + sphinx-quickstart on Wed Apr 10 17:17:12 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to ckanext-spatial's documentation! +=========================================== + +============================================== +ckanext-spatial - Geo related plugins for CKAN +============================================== + +This extension contains plugins that add geospatial capabilities to CKAN. +The following plugins are currently available: + +* Spatial model for CKAN datasets and automatic geo-indexing (`spatial_metadata`) +* Spatial Search - Spatial search integration and API call (`spatial_query`). +* Spatial Search Widget - Map widget integrated on the search form (`spatial_query_widget`). +* Dataset Extent Map - Map widget showing a dataset extent (`dataset_extent_map`). +* WMS Preview - a Web Map Service (WMS) previewer (`wms_preview`). +* CSW Server - a basic CSW server - to server metadata from the CKAN instance (`cswserver`) +* GEMINI Harvesters - for importing INSPIRE-style metadata into CKAN (`gemini_csw_harvester`, `gemini_doc_harvester`, `gemini_waf_harvester`) +* Harvest Metadata API - a way for a user to view the harvested metadata XML, either as a raw file or styled to view in a web browser. (`spatial_harvest_metadata_api`) + +These libraries: +* CSW Client - a basic client for accessing a CSW server +* Validators - uses XSD / Schematron to validate geographic metadata XML. Used by the GEMINI Harvesters +* Validators for ISO19139/INSPIRE/GEMINI2 metadata. Used by the Validator. + +And these command-line tools: +* cswinfo - a command-line tool to help making requests of any CSW server + +As of October 2012, ckanext-csw and ckanext-inspire were merged into this extension. + +Contents: + +.. toctree:: + :maxdepth: 2 + + spatial-search + dataset-map + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/doc/spatial-search.rst b/doc/spatial-search.rst new file mode 100644 index 0000000..7404ee9 --- /dev/null +++ b/doc/spatial-search.rst @@ -0,0 +1,65 @@ +Spatial Search +============== + +To enable the spatial query you need to add the `spatial_query` plugin to your +ini file (See `Configuration`_). This plugin requires the `spatial_metadata` +plugin. + +The extension adds the following call to the CKAN search API, which returns +datasets with an extent that intersects with the bounding box provided:: + + /api/2/search/dataset/geo?bbox={minx,miny,maxx,maxy}[&crs={srid}] + +If the bounding box coordinates are not in the same projection as the one +defined in the database, a CRS must be provided, in one of the following +forms: + +- urn:ogc:def:crs:EPSG::4326 +- EPSG:4326 +- 4326 + +As of CKAN 1.6, you can integrate your spatial query in the full CKAN +search, via the web interface (see the `Spatial Query Widget`_) or +via the `action API`__, e.g.:: + + POST http://localhost:5000/api/action/package_search + { + "q": "Pollution", + "extras": { + "ext_bbox": "-7.535093,49.208494,3.890688,57.372349" + } + } + +__ http://docs.ckan.org/en/latest/apiv3.html + +Geo-Indexing your datasets +-------------------------- + +In order to make a dataset queryable by location, an special extra must +be defined, with its key named 'spatial'. The value must be a valid GeoJSON_ +geometry, for example:: + + {"type":"Polygon","coordinates":[[[2.05827, 49.8625],[2.05827, 55.7447], [-6.41736, 55.7447], [-6.41736, 49.8625], [2.05827, 49.8625]]]} + +or:: + + { "type": "Point", "coordinates": [-3.145,53.078] } + +.. _GeoJSON: http://geojson.org + +Every time a dataset is created, updated or deleted, the extension will synchronize +the information stored in the extra with the geometry table. + + +Spatial Search Widget +--------------------- + +**Note**: this plugin requires CKAN 1.6 or higher. + +To enable the search map widget you need to add the `spatial_query_widget` plugin to your +ini file (See `Configuration`_). You also need to load both the `spatial_metadata` +and the `spatial_query` plugins. + +When the plugin is enabled, a map widget will be shown in the dataset search form, +where users can refine their searchs drawing an area of interest. + From e85d647304c4a971bde5e6655ee8f93a773ab3e2 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 14 May 2013 14:04:54 +0100 Subject: [PATCH 029/114] [#7] Remove spatial_query_widget from setup --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index e58cc8e..e54d471 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,6 @@ setup( [ckan.plugins] spatial_metadata=ckanext.spatial.plugin:SpatialMetadata spatial_query=ckanext.spatial.plugin:SpatialQuery - spatial_query_widget=ckanext.spatial.plugin:SpatialQueryWidget wms_preview=ckanext.spatial.nongeos_plugin:WMSPreview cswserver=ckanext.spatial.plugin:CatalogueServiceWeb spatial_harvest_metadata_api=ckanext.spatial.plugin:HarvestMetadataApi From b4a7cf228929e6a1ed924359f72b41dba3ff60d1 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 14 May 2013 14:34:10 +0100 Subject: [PATCH 030/114] [#15] Reenable the Solr backend on master It can be used against CKAN core master (eventually 2.1) --- README.rst | 130 +++++++++++++++- ckanext/spatial/harvesters/base.py | 2 +- ckanext/spatial/plugin.py | 230 +++++++++++++++++++++++------ 3 files changed, 310 insertions(+), 52 deletions(-) diff --git a/README.rst b/README.rst index d9e354c..bdb3af9 100644 --- a/README.rst +++ b/README.rst @@ -55,14 +55,101 @@ To enable the spatial query you need to add the ``spatial_query`` plugin to your ini file (See `Configuration`_). This plugin requires the ``spatial_metadata`` plugin. +There are different backends supported for the spatial search, it is important +to understand their differences and the necessary setup required when choosing +which one to use. The backend to use is defined with the configuration option +``ckanext.spatial.search_backend``, eg:: + + ckanext.spatial.search_backend = solr + +The following table summarizes the different spatial search backends: + ++------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ +| Backend | Solr Versions | Supported geometries | Sorting and relevance | Performance with large number of datasets | ++========================+===============+=====================================+===========================================================+===========================================+ +| ``solr`` | 3.1 to 4.x | Bounding Box | Yes, spatial sorting combined with other query parameters | Good | ++------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ +| ``solr-spatial-field`` | 4.x | Bounding Box, Point and Polygon (1) | Not implemented | Good | ++------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ +| ``postgis`` | 1.3 to 4.x | Bounding Box | Partial, only spatial sorting supported (2) | Poor | ++------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ + +(1) Requires JTS +(2) Needs ``ckanext.spatial.use_postgis_sorting`` set to True + + +We recommend to use the ``solr`` backend whenever possible. Here are more +details about the available options: + +* ``solr`` (Recommended) + This option uses normal Solr fields to index the relevant bits of + information about the geometry and uses an algorithm function to + sort results by relevance, keeping any other non-spatial filtering. It only + supports bounding boxes both for the geometries to be indexed and the input + query shape. It requires `EDisMax`_ query parser, so it will only work on + versions of Solr greater than 3.1 (We recommend using Solr 4.x). + + You will need to add the following fields to your Solr schema file to enable it:: + + + + + + + + + + + +* ``solr-spatial-field`` + This option uses the `spatial field `_ + introduced in Solr 4, which allows to index points, rectangles and more + complex geometries (complex geometries will require `JTS`_, check the + documentation). Sorting has not yet been implemented, users willing to do so + will need to modify the query using the ``before_search`` extension point. + + You will need to add the following field type and field to your Solr schema + file to enable it (Check the Solr documentation for more information on + the different parameters, note that you don't need ``spatialContextFactory`` if + you are not using JTS):: + + + + + + + + + + +* ``postgis`` + This is the original implementation of the spatial search. It does not + require any change in the Solr schema and can run on Solr 1.x, but it is + not as efficient as the previous ones. Basically the bounding box based + query is performed in PostGIS first, and the ids of the matched datasets + are added as a filter to the Solr request. This, apart from being much + less efficient, can led to issues on Solr due to size of the requests (See + `Solr configuration issues on legacy PostGIS backend`_). There is support + for a spatial ranking on this backend (setting + ``ckanext.spatial.use_postgis_sorting`` to True on the ini file), but it + can not be combined with any other filtering. + + +.. _edismax: http://wiki.apache.org/solr/ExtendedDisMax +.. _JTS: http://www.vividsolutions.com/jts/JTSHome.htm Geo-Indexing your datasets ++++++++++++++++++++++++++ -In order to make a dataset queryable by location, an special extra must -be defined, with its key named 'spatial'. The value must be a valid GeoJSON_ -geometry, for example:: +Regardless of the backend that you are using, in order to make a dataset +queryable by location, an special extra must be defined, with its key named +'spatial'. The value must be a valid GeoJSON_ geometry, for example:: {"type":"Polygon","coordinates":[[[2.05827, 49.8625],[2.05827, 55.7447], [-6.41736, 55.7447], [-6.41736, 49.8625], [2.05827, 49.8625]]]} @@ -102,14 +189,43 @@ or with a GeoJSON object describing a bounding box (note the escaped quotes):: {% snippet "spatial/snippets/spatial_query.html", default_extent="{ \"type\": \"Polygon\", \"coordinates\": [[[74.89, 29.39],[74.89, 38.45], [60.50, 38.45], [60.50, 29.39], [74.89, 29.39]]]}" %} -You need to load the ``spatial_metadata`` and ``spatial_query`` plugins to use this snippet. +You need to load the `spatial_metadata` and `spatial_query` plugins to use this snippet. + + +Solr configuration issues on legacy PostGIS backend ++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. warning:: + + If you find any of the issues described in this section it is strongly + suggested that you consider switching to one of the Solr based backends + which are much more efficient. These notes are just kept for informative + purposes. + + +If using Spatial Query functionality then there is an additional SOLR/Lucene setting that should be used to set the limit on number of datasets searchable with a spatial value. + +The setting is ``maxBooleanClauses`` in the solrconfig.xml and the value is the number of datasets spatially searchable. The default is ``1024`` and this could be increased to say ``16384``. For a SOLR single core this will probably be at `/etc/solr/conf/solrconfig.xml`. For a multiple core set-up, there will me several solrconfig.xml files a couple of levels below `/etc/solr`. For that case, *all* of the cores' `solrconfig.xml` should have this setting at the new value. + +Example:: + + 16384 + +This setting is needed because PostGIS spatial query results are fed into SOLR using a Boolean expression, and the parser for that has a limit. So if your spatial area contains more than the limit (of which the default is 1024) then you will get this error:: + + Dataset search error: ('SOLR returned an error running query... + +and in the SOLR logs you see:: + + too many boolean clauses + ... + Caused by: org.apache.lucene.search.BooleanQuery$TooManyClauses: + maxClauseCount is set to 1024 + Legacy API ++++++++++ -.. note:: This API endpoint will be deprecated on future versions of CKAN and - should not be used. - The extension adds the following call to the CKAN search API, which returns datasets with an extent that intersects with the bounding box provided:: diff --git a/ckanext/spatial/harvesters/base.py b/ckanext/spatial/harvesters/base.py index 112e3e7..7f67a7b 100644 --- a/ckanext/spatial/harvesters/base.py +++ b/ckanext/spatial/harvesters/base.py @@ -114,7 +114,7 @@ class SpatialHarvester(HarvesterBase): force_import = False extent_template = Template(''' - {"type": "Polygon", "coordinates": [[[$xmin, $ymin], [$xmin, $ymax], [$xmax, $ymax], [$xmax, $ymin], [$xmin, $ymin]]]} + {"type": "Polygon", "coordinates": [[[$xmin, $ymin], [$xmax, $ymin], [$xmax, $ymax], [$xmin, $ymax], [$xmin, $ymin]]]} ''') ## IHarvester diff --git a/ckanext/spatial/plugin.py b/ckanext/spatial/plugin.py index bae831e..83c913c 100644 --- a/ckanext/spatial/plugin.py +++ b/ckanext/spatial/plugin.py @@ -4,6 +4,8 @@ from logging import getLogger from pylons import config +import shapely + from ckan import plugins as p from ckan.lib.search import SearchError, PackageSearchQuery @@ -42,6 +44,7 @@ class SpatialMetadata(p.SingletonPlugin): p.implements(p.ITemplateHelpers, inherit=True) def configure(self, config): + if not p.toolkit.asbool(config.get('ckan.spatial.testing', 'False')): setup_model() @@ -117,6 +120,13 @@ class SpatialQuery(p.SingletonPlugin): p.implements(p.IRoutes, inherit=True) p.implements(p.IPackageController, inherit=True) + p.implements(p.IConfigurable, inherit=True) + + search_backend = None + + def configure(self, config): + + self.search_backend = config.get('ckanext.spatial.search_backend', 'postgis') def before_map(self, map): @@ -125,60 +135,192 @@ class SpatialQuery(p.SingletonPlugin): action='spatial_query') return map - def before_search(self,search_params): - if 'extras' in search_params and 'ext_bbox' in search_params['extras'] \ - and search_params['extras']['ext_bbox']: + def before_index(self, pkg_dict): + + if pkg_dict.get('extras_spatial', None) and self.search_backend in ('solr', 'solr-spatial-field'): + try: + geometry = json.loads(pkg_dict['extras_spatial']) + except ValueError, e: + log.error('Geometry not valid GeoJSON, not indexing') + return pkg_dict + + if self.search_backend == 'solr': + # Only bbox supported for this backend + if not (geometry['type'] == 'Polygon' + and len(geometry['coordinates']) == 1 + and len(geometry['coordinates'][0]) == 5): + log.error('Solr backend only supports bboxes, ignoring geometry {0}'.format(pkg_dict['extras_spatial'])) + return pkg_dict + + coords = geometry['coordinates'] + pkg_dict['maxy'] = max(coords[0][2][1], coords[0][0][1]) + pkg_dict['miny'] = min(coords[0][2][1], coords[0][0][1]) + pkg_dict['maxx'] = max(coords[0][2][0], coords[0][0][0]) + pkg_dict['minx'] = min(coords[0][2][0], coords[0][0][0]) + pkg_dict['bbox_area'] = (pkg_dict['maxx'] - pkg_dict['minx']) * \ + (pkg_dict['maxy'] - pkg_dict['miny']) + + elif self.search_backend == 'solr-spatial-field': + wkt = None + + # Check potential problems with bboxes + if geometry['type'] == 'Polygon' \ + and len(geometry['coordinates']) == 1 \ + and len(geometry['coordinates'][0]) == 5: + + # Check wrong bboxes (4 same points) + xs = [p[0] for p in geometry['coordinates'][0]] + ys = [p[1] for p in geometry['coordinates'][0]] + + if xs.count(xs[0]) == 5 and ys.count(ys[0]) == 5: + wkt = 'POINT({x} {y})'.format(x=xs[0], y=ys[0]) + else: + # Check if coordinates are defined counter-clockwise, + # otherwise we'll get wrong results from Solr + lr = shapely.geometry.polygon.LinearRing(geometry['coordinates'][0]) + if not lr.is_ccw: + lr.coords = list(lr.coords)[::-1] + polygon = shapely.geometry.polygon.Polygon(lr) + wkt = polygon.wkt + + if not wkt: + shape = shapely.geometry.asShape(geometry) + if not shape.is_valid: + log.error('Wrong geometry, not indexing') + return pkg_dict + wkt = shape.wkt + + pkg_dict['spatial_geom'] = wkt + + + return pkg_dict + + def before_search(self, search_params): + if search_params.get('extras', None) and search_params['extras'].get('ext_bbox', None): bbox = validate_bbox(search_params['extras']['ext_bbox']) if not bbox: raise SearchError('Wrong bounding box provided') - # Note: This will be deprecated at some point in favour of the - # Solr 4 spatial sorting capabilities - if search_params.get('sort') == 'spatial desc' and \ - p.toolkit.asbool(config.get('ckanext.spatial.use_postgis_sorting', 'False')): - if search_params['q'] or search_params['fq']: - raise SearchError('Spatial ranking cannot be mixed with other search parameters') - # ...because it is too inefficient to use SOLR to filter - # results and return the entire set to this class and - # after_search do the sorting and paging. - extents = bbox_query_ordered(bbox) - are_no_results = not extents - search_params['extras']['ext_rows'] = search_params['rows'] - search_params['extras']['ext_start'] = search_params['start'] - # this SOLR query needs to return no actual results since - # they are in the wrong order anyway. We just need this SOLR - # query to get the count and facet counts. - rows = 0 - search_params['sort'] = None # SOLR should not sort. - # Store the rankings of the results for this page, so for - # after_search to construct the correctly sorted results - rows = search_params['extras']['ext_rows'] = search_params['rows'] - start = search_params['extras']['ext_start'] = search_params['start'] - search_params['extras']['ext_spatial'] = [ - (extent.package_id, extent.spatial_ranking) \ - for extent in extents[start:start+rows]] - else: - extents = bbox_query(bbox) - are_no_results = extents.count() == 0 + if self.search_backend == 'solr': + search_params = self._params_for_solr_search(bbox, search_params) + elif self.search_backend == 'solr-spatial-field': + search_params = self._params_for_solr_spatial_search(bbox, search_params) + elif self.search_backend == 'postgis': + search_params = self._params_for_postgis_search(bbox, search_params) - if are_no_results: - # We don't need to perform the search - search_params['abort_search'] = True - else: - # We'll perform the existing search but also filtering by the ids - # of datasets within the bbox - bbox_query_ids = [extent.package_id for extent in extents] + return search_params - q = search_params.get('q','').strip() or '""' - new_q = '%s AND ' % q if q else '' - new_q += '(%s)' % ' OR '.join(['id:%s' % id for id in bbox_query_ids]) + def _params_for_solr_search(self, bbox, search_params): + ''' + This will add the following parameters to the query: - search_params['q'] = new_q + defType - edismax (We need to define EDisMax to use bf) + bf - {function} A boost function to influence the score (thus + influencing the sorting). The algorithm can be basically defined as: + + 2 * X / Q + T + + Where X is the intersection between the query area Q and the + target geometry T. It gives a ratio from 0 to 1 where 0 means + no overlap at all and 1 a perfect fit + + fq - Adds a filter that force the value returned by the previous + function to be between 0 and 1, effectively applying the + spatial filter. + + ''' + + variables =dict( + x11=bbox['minx'], + x12=bbox['maxx'], + y11=bbox['miny'], + y12=bbox['maxy'], + x21='minx', + x22='maxx', + y21='miny', + y22='maxy', + area_search = abs(bbox['maxx'] - bbox['minx']) * abs(bbox['maxy'] - bbox['miny']) + ) + + bf = '''div( + mul( + mul(max(0, sub(min({x12},{x22}) , max({x11},{x21}))), + max(0, sub(min({y12},{y22}) , max({y11},{y21}))) + ), + 2), + add({area_search}, mul(sub({y22}, {y21}), sub({x22}, {x21}))) + )'''.format(**variables).replace('\n','').replace(' ','') + + search_params['fq_list'] = ['{!frange incl=false l=0 u=1}%s' % bf] + + search_params['bf'] = bf + search_params['defType'] = 'edismax' + + return search_params + + def _params_for_solr_spatial_field_search(self, bbox, search_params): + ''' + This will add an fq filter with the form: + + +spatial_geom:"Intersects({minx} {miny} {maxx} {maxy}) + + ''' + search_params['fq_list'] = search_params.get('fq_list', []) + search_params['fq_list'].append('+spatial_geom:"Intersects({minx} {miny} {maxx} {maxy})"' + .format(minx=bbox['minx'],miny=bbox['miny'],maxx=bbox['maxx'],maxy=bbox['maxy'])) + + return search_params + + def _params_for_postgis_search(self, bbox, search_params): + + # Note: This will be deprecated at some point in favour of the + # Solr 4 spatial sorting capabilities + if search_params['sort'] == 'spatial desc' and \ + p.toolkit.asbool(config.get('ckanext.spatial.use_postgis_sorting', 'False')): + if search_params['q'] or search_params['fq']: + raise SearchError('Spatial ranking cannot be mixed with other search parameters') + # ...because it is too inefficient to use SOLR to filter + # results and return the entire set to this class and + # after_search do the sorting and paging. + extents = bbox_query_ordered(bbox) + are_no_results = not extents + search_params['extras']['ext_rows'] = search_params['rows'] + search_params['extras']['ext_start'] = search_params['start'] + # this SOLR query needs to return no actual results since + # they are in the wrong order anyway. We just need this SOLR + # query to get the count and facet counts. + rows = 0 + search_params['sort'] = None # SOLR should not sort. + # Store the rankings of the results for this page, so for + # after_search to construct the correctly sorted results + rows = search_params['extras']['ext_rows'] = search_params['rows'] + start = search_params['extras']['ext_start'] = search_params['start'] + search_params['extras']['ext_spatial'] = [ + (extent.package_id, extent.spatial_ranking) \ + for extent in extents[start:start+rows]] + else: + extents = bbox_query(bbox) + are_no_results = extents.count() == 0 + + if are_no_results: + # We don't need to perform the search + search_params['abort_search'] = True + else: + # We'll perform the existing search but also filtering by the ids + # of datasets within the bbox + bbox_query_ids = [extent.package_id for extent in extents] + + q = search_params.get('q','').strip() or '""' + new_q = '%s AND ' % q if q else '' + new_q += '(%s)' % ' OR '.join(['id:%s' % id for id in bbox_query_ids]) + + search_params['q'] = new_q return search_params def after_search(self, search_results, search_params): + # Note: This will be deprecated at some point in favour of the # Solr 4 spatial sorting capabilities @@ -237,12 +379,12 @@ class HarvestMetadataApi(p.SingletonPlugin): ''' Harvest Metadata API (previously called "InspireApi") - + A way for a user to view the harvested metadata XML, either as a raw file or styled to view in a web browser. ''' p.implements(p.IRoutes) - + def before_map(self, route_map): controller = "ckanext.spatial.controllers.api:HarvestMetadataApiController" From 8e81d1bd69abd8f820f5f11364f48fb758d2ffe9 Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 15 May 2013 16:41:36 +0100 Subject: [PATCH 031/114] [#19] Extract thumbnail from ISO documents --- ckanext/spatial/harvesters/base.py | 11 ++++++ ckanext/spatial/model/harvested_metadata.py | 38 ++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/ckanext/spatial/harvesters/base.py b/ckanext/spatial/harvesters/base.py index 7f67a7b..8ccf7cd 100644 --- a/ckanext/spatial/harvesters/base.py +++ b/ckanext/spatial/harvesters/base.py @@ -259,6 +259,17 @@ class SpatialHarvester(HarvesterBase): extras['access_constraints'] = iso_values.get('limitations-on-public-access', '') + # Grpahic preview + browse_graphic = iso_values.get('browse-graphic') + if browse_graphic: + browse_graphic = browse_graphic[0] + extras['graphic-preview-file'] = browse_graphic.get('file') + if browse_graphic.get('description'): + extras['graphic-preview-description'] = browse_graphic.get('description') + if browse_graphic.get('type'): + extras['graphic-preview-type'] = browse_graphic.get('type') + + for key in ['temporal-extent-begin', 'temporal-extent-end']: if len(iso_values[key]) > 0: extras[key] = iso_values[key][0] diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index a505c4e..86700c5 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -344,6 +344,33 @@ class ISOBoundingBox(ISOElement): ), ] +class ISOBrowseGraphic(ISOElement): + + elements = [ + ISOElement( + name="file", + search_paths=[ + "gmd:fileName/gco:CharacterString/text()", + ], + multiplicity="1", + ), + ISOElement( + name="description", + search_paths=[ + "gmd:fileDescription/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), + ISOElement( + name="type", + search_paths=[ + "gmd:fileType/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), + ] + + class ISODocument(MappedXmlDocument): # Attribute specifications from "XPaths for GEMINI" by Peter Parslow. @@ -651,7 +678,16 @@ class ISODocument(MappedXmlDocument): "gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:lineage/gmd:LI_Lineage/gmd:statement/gco:CharacterString/text()", ], multiplicity="0..1", - ) + ), + ISOBrowseGraphic( + name="browse-graphic", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:graphicOverview/gmd:MD_BrowseGraphic", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:graphicOverview/gmd:MD_BrowseGraphic", + ], + multiplicity="*", + ), + ] def infer_values(self, values): From 27521221d6a40021d3e45e4029aeb0a20d67a346 Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 15 May 2013 16:58:12 +0100 Subject: [PATCH 032/114] [#20] Flag datasets created via the spatial harvesters via a generic extra --- ckanext/spatial/harvesters/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ckanext/spatial/harvesters/base.py b/ckanext/spatial/harvesters/base.py index 8ccf7cd..c7a4625 100644 --- a/ckanext/spatial/harvesters/base.py +++ b/ckanext/spatial/harvesters/base.py @@ -219,6 +219,7 @@ class SpatialHarvester(HarvesterBase): extras = { 'guid': harvest_object.guid, + 'spatial_harvester': True, } # Just add some of the metadata as extras, not the whole lot From add78d59313a0b54c4f349792397dec45794e8d8 Mon Sep 17 00:00:00 2001 From: kindly Date: Sat, 18 May 2013 18:28:25 +0100 Subject: [PATCH 033/114] allow csw to fetch differen output schema --- ckanext/spatial/harvesters/csw.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ckanext/spatial/harvesters/csw.py b/ckanext/spatial/harvesters/csw.py index a3c8816..769a1af 100644 --- a/ckanext/spatial/harvesters/csw.py +++ b/ckanext/spatial/harvesters/csw.py @@ -59,6 +59,8 @@ class CSWHarvester(SpatialHarvester, SingletonPlugin): return url + def output_schema(self): + return 'gmd' def gather_stage(self, harvest_job): log = logging.getLogger(__name__ + '.CSW.gather') @@ -87,7 +89,7 @@ class CSWHarvester(SpatialHarvester, SingletonPlugin): log.debug('Starting gathering for %s' % url) guids_in_harvest = set() try: - for identifier in self.csw.getidentifiers(page=10): + for identifier in self.csw.getidentifiers(page=10, outputschema=self.output_schema()): try: log.info('Got identifier %s from the CSW', identifier) if identifier is None: @@ -151,7 +153,7 @@ class CSWHarvester(SpatialHarvester, SingletonPlugin): identifier = harvest_object.guid try: - record = self.csw.getrecordbyid([identifier]) + record = self.csw.getrecordbyid([identifier], outputschema=self.output_schema()) except Exception, e: self._save_object_error('Error getting the CSW record with GUID %s' % identifier, harvest_object) return False From 4abd73e9559f88cc71dc5fb8ce7c687c83d08d80 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Thu, 13 Jun 2013 22:17:40 +0200 Subject: [PATCH 034/114] [#22] No need to add `resource_proxy_enabled` to config --- README.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.rst b/README.rst index bdb3af9..5da233e 100644 --- a/README.rst +++ b/README.rst @@ -290,9 +290,7 @@ WMS Preview To enable the WMS previewer you need to add the ``wms_preview`` plugin to your ini file (See `Configuration`_). This plugin also requires the ``resource_proxy`` -plugin and the following option in your ini file:: - - ckan.resource_proxy_enabled=1 +plugin. Please note that this is an experimental plugin and may be unstable. From 64d1846e900eeb26aa77f34598c87bab67235335 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Thu, 13 Jun 2013 22:51:01 +0200 Subject: [PATCH 035/114] [#21] Add basic GeoJSON preview and fix set up of wms preview --- ckanext/spatial/nongeos_plugin.py | 43 ++++++++++++ .../spatial/public/css/geojson_preview.css | 11 +++ ckanext/spatial/public/js/geojson_preview.js | 67 +++++++++++++++++++ ckanext/spatial/public/resource.config | 7 ++ .../spatial/templates/dataviewer/geojson.html | 14 ++++ setup.py | 1 + 6 files changed, 143 insertions(+) create mode 100644 ckanext/spatial/public/css/geojson_preview.css create mode 100644 ckanext/spatial/public/js/geojson_preview.js create mode 100644 ckanext/spatial/templates/dataviewer/geojson.html diff --git a/ckanext/spatial/nongeos_plugin.py b/ckanext/spatial/nongeos_plugin.py index 95103d5..69151b5 100644 --- a/ckanext/spatial/nongeos_plugin.py +++ b/ckanext/spatial/nongeos_plugin.py @@ -13,6 +13,10 @@ class WMSPreview(p.SingletonPlugin): def update_config(self, config): + p.toolkit.add_public_directory(config, 'public') + p.toolkit.add_template_directory(config, 'templates') + p.toolkit.add_resource('public', 'ckanext-spatial') + self.proxy_enabled = p.toolkit.asbool(config.get('ckan.resource_proxy_enabled', 'False')) @@ -34,3 +38,42 @@ class WMSPreview(p.SingletonPlugin): def preview_template(self, context, data_dict): return 'dataviewer/wms.html' + + +class GeoJSONPreview(p.SingletonPlugin): + p.implements(p.IConfigurer, inherit=True) + p.implements(p.IResourcePreview, inherit=True) + + GeoJSON = ['gjson', 'geojson'] + + def update_config(self, config): + ''' Set up the resource library, public directory and + template directory for the preview + ''' + + p.toolkit.add_public_directory(config, 'public') + p.toolkit.add_template_directory(config, 'templates') + p.toolkit.add_resource('public', 'ckanext-spatial') + + self.proxy_enabled = config.get( + 'ckan.resource_proxy_enabled', False) + + def can_preview(self, data_dict): + format_lower = data_dict['resource']['format'].lower() + + check = format_lower in self.GeoJSON + if not self.proxy_enabled and check: + check = data_dict['resource']['on_same_domain'] + + return check + + def setup_template_variables(self, context, data_dict): + import ckanext.resourceproxy.plugin as proxy + if (self.proxy_enabled + and not data_dict['resource']['on_same_domain']): + p.toolkit.c.resource['original_url'] = p.toolkit.c.resource['url'] + p.toolkit.c.resource['url'] = proxy.get_proxified_resource_url( + data_dict) + + def preview_template(self, context, data_dict): + return 'dataviewer/geojson.html' diff --git a/ckanext/spatial/public/css/geojson_preview.css b/ckanext/spatial/public/css/geojson_preview.css new file mode 100644 index 0000000..29d3e64 --- /dev/null +++ b/ckanext/spatial/public/css/geojson_preview.css @@ -0,0 +1,11 @@ +html, body { + height: 100%; + padding: 0; + margin: 0; +} + +#map { + position: absolute; + width: 100%; + height: 100%; +} diff --git a/ckanext/spatial/public/js/geojson_preview.js b/ckanext/spatial/public/js/geojson_preview.js new file mode 100644 index 0000000..46d6c9d --- /dev/null +++ b/ckanext/spatial/public/js/geojson_preview.js @@ -0,0 +1,67 @@ +// geojson preview module +ckan.module('geojsonpreview', function (jQuery, _) { + return { + options: { + }, + initialize: function () { + var self = this; + + self.el.empty(); + self.el.append($("
").attr("id","map")); + self.map = L.map('map'); + + var mapUrl = "http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"; + var osmAttribution = 'Map data © 2011 OpenStreetMap contributors, Tiles Courtesy of MapQuest '; + var bg = new L.TileLayer(mapUrl, {maxZoom: 18, attribution: osmAttribution, subdomains: '1234'}); + self.map.addLayer(bg); + + // use CORS, if supported by browser and server + if (jQuery.support.cors && preload_resource['original_url'] !== undefined) { + jQuery.getJSON(preload_resource['original_url']) + .done( + function(data){ + self.showPreview(data); + }) + .fail( + function(jqxhr, textStatus, error) { + jQuery.getJSON(preload_resource['url']) + .done( + function(data){ + self.showPreview(data); + }) + .fail( + function(jqXHR, textStatus, errorThrown) { + self.showError(jqXHR, textStatus, errorThrown); + } + ); + } + ); + } else { + jQuery.getJSON(preload_resource['url']).done( + function(data){ + self.showPreview(data); + }) + .fail( + function(jqXHR, textStatus, errorThrown) { + self.showError(jqXHR, textStatus, errorThrown); + } + ); + } + }, + + showError: function (jqXHR, textStatus, errorThrown) { + if (textStatus == 'error' && jqXHR.responseText.length) { + self.el.html(jqXHR.responseText); + } else { + self.el.html(self.i18n('error', {text: textStatus, error: errorThrown})); + } + }, + + showPreview: function (geojsonFeature) { + var self = this; + var gjLayer = L.geoJson().addTo(self.map); + gjLayer.addData(geojsonFeature); + self.map.fitBounds(gjLayer.getBounds()); + } + }; +}); diff --git a/ckanext/spatial/public/resource.config b/ckanext/spatial/public/resource.config index d4bc955..597d0af 100644 --- a/ckanext/spatial/public/resource.config +++ b/ckanext/spatial/public/resource.config @@ -37,3 +37,10 @@ wms = js/wms_preview.js css/wms_preview.css + +geojson = + js/vendor/leaflet/leaflet.js + js/vendor/leaflet/leaflet.css + + js/geojson_preview.js + css/geojson_preview.css \ No newline at end of file diff --git a/ckanext/spatial/templates/dataviewer/geojson.html b/ckanext/spatial/templates/dataviewer/geojson.html new file mode 100644 index 0000000..29c6bc3 --- /dev/null +++ b/ckanext/spatial/templates/dataviewer/geojson.html @@ -0,0 +1,14 @@ +{% extends "dataviewer/base.html" %} + +{% block page %} +
+

+
+
{{ _('Loading...') }}
+

+
+ + {% resource 'ckanext-spatial/geojson' %} + +{% endblock %} + diff --git a/setup.py b/setup.py index e54d471..87ecb86 100644 --- a/setup.py +++ b/setup.py @@ -31,6 +31,7 @@ setup( spatial_metadata=ckanext.spatial.plugin:SpatialMetadata spatial_query=ckanext.spatial.plugin:SpatialQuery wms_preview=ckanext.spatial.nongeos_plugin:WMSPreview + geojson_preview=ckanext.spatial.nongeos_plugin:GeoJSONPreview cswserver=ckanext.spatial.plugin:CatalogueServiceWeb spatial_harvest_metadata_api=ckanext.spatial.plugin:HarvestMetadataApi From 6eb180c02a41ccc93c223ef456878d976a4e93c3 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Thu, 13 Jun 2013 23:24:01 +0200 Subject: [PATCH 036/114] [#21] Add properties information to popup, lighter style --- .../spatial/public/css/geojson_preview.css | 14 ++++++++++++++ ckanext/spatial/public/js/geojson_preview.js | 19 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/ckanext/spatial/public/css/geojson_preview.css b/ckanext/spatial/public/css/geojson_preview.css index 29d3e64..aeeab75 100644 --- a/ckanext/spatial/public/css/geojson_preview.css +++ b/ckanext/spatial/public/css/geojson_preview.css @@ -9,3 +9,17 @@ html, body { width: 100%; height: 100%; } + +.popup-table { + border-collapse: collapse; + border: 1px solid #bbb; +} + +.popup-table td, .popup-table th { + border: 1px solid #bbb; + padding: 4px; +} + +.popup-table tr:nth-child(even) { + background-color: #eee; +} \ No newline at end of file diff --git a/ckanext/spatial/public/js/geojson_preview.js b/ckanext/spatial/public/js/geojson_preview.js index 46d6c9d..a5435a1 100644 --- a/ckanext/spatial/public/js/geojson_preview.js +++ b/ckanext/spatial/public/js/geojson_preview.js @@ -2,6 +2,13 @@ ckan.module('geojsonpreview', function (jQuery, _) { return { options: { + table: '{body}', + row:'', + style: { + opacity: 0.7, + fillOpacity: 0.1, + weight: 2 + } }, initialize: function () { var self = this; @@ -59,7 +66,17 @@ ckan.module('geojsonpreview', function (jQuery, _) { showPreview: function (geojsonFeature) { var self = this; - var gjLayer = L.geoJson().addTo(self.map); + var gjLayer = L.geoJson(undefined, { + style: self.options.style, + onEachFeature: function(feature, layer) { + var body = ''; + jQuery.each(feature.properties, function(key, value){ + body += L.Util.template(self.options.row, {key: key, value: value}); + }); + var popupContent = L.Util.template(self.options.table, {body: body}); + layer.bindPopup(popupContent); + } + }).addTo(self.map); gjLayer.addData(geojsonFeature); self.map.fitBounds(gjLayer.getBounds()); } From 4aabfed78b2ebe70a0eced849316ce6319b13d83 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Thu, 13 Jun 2013 23:34:49 +0200 Subject: [PATCH 037/114] [#21] Add GeoJSON preview docs --- README.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.rst b/README.rst index bdb3af9..3a5f113 100644 --- a/README.rst +++ b/README.rst @@ -301,6 +301,17 @@ the resource page will load simple map viewer that will attempt to load the remote service layers, based on the GetCapabilities response. +GeoJSON Preview +--------------- + +To enable the GeoJSON previewer you need to add the ``geojson_preview`` plugin to your +ini file (See `Configuration`_). This plugin also requires the ``resource_proxy`` +plugin. + +When the plugin is enabled, if datasets contain a resource that has 'gjson' or 'geojson' +format, the resource page will load simple map viewer that will show the features on a map. + + CSW Server ---------- From fe8c469c12c0f3081a7fca9410de2da6783413dc Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Fri, 14 Jun 2013 13:23:06 +0200 Subject: [PATCH 038/114] [#21] show object in popup, fix layout --- ckanext/spatial/public/css/geojson_preview.css | 5 ++++- ckanext/spatial/public/js/geojson_preview.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ckanext/spatial/public/css/geojson_preview.css b/ckanext/spatial/public/css/geojson_preview.css index aeeab75..4220ee8 100644 --- a/ckanext/spatial/public/css/geojson_preview.css +++ b/ckanext/spatial/public/css/geojson_preview.css @@ -1,5 +1,5 @@ html, body { - height: 100%; + height: 600px; padding: 0; margin: 0; } @@ -13,11 +13,14 @@ html, body { .popup-table { border-collapse: collapse; border: 1px solid #bbb; + table-layout: fixed; + width: 300px; } .popup-table td, .popup-table th { border: 1px solid #bbb; padding: 4px; + word-wrap: break-word; } .popup-table tr:nth-child(even) { diff --git a/ckanext/spatial/public/js/geojson_preview.js b/ckanext/spatial/public/js/geojson_preview.js index a5435a1..95f3f5a 100644 --- a/ckanext/spatial/public/js/geojson_preview.js +++ b/ckanext/spatial/public/js/geojson_preview.js @@ -2,7 +2,7 @@ ckan.module('geojsonpreview', function (jQuery, _) { return { options: { - table: '
{key}{value}
{body}', + table: '
{body}', row:'{key}{value}', style: { opacity: 0.7, @@ -71,6 +71,9 @@ ckan.module('geojsonpreview', function (jQuery, _) { onEachFeature: function(feature, layer) { var body = ''; jQuery.each(feature.properties, function(key, value){ + if (value != null && typeof value === 'object') { + value = JSON.stringify(value); + } body += L.Util.template(self.options.row, {key: key, value: value}); }); var popupContent = L.Util.template(self.options.table, {body: body}); From 9eec88b3208550c9a5b63c7078b83c4226ced1af Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 14 Jun 2013 15:59:45 +0100 Subject: [PATCH 039/114] [#15] Check CKAN version when using the Solr Search backend --- ckanext/spatial/plugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ckanext/spatial/plugin.py b/ckanext/spatial/plugin.py index 83c913c..3a8dc75 100644 --- a/ckanext/spatial/plugin.py +++ b/ckanext/spatial/plugin.py @@ -127,6 +127,10 @@ class SpatialQuery(p.SingletonPlugin): def configure(self, config): self.search_backend = config.get('ckanext.spatial.search_backend', 'postgis') + if self.search_backend != 'postgis' and not p.toolkit.check_ckan_version('2.0.1'): + msg = 'The Solr backends for the spatial search require CKAN 2.0.1 or higher. ' + \ + 'Please upgrade CKAN or select the \'postgis\' backend.' + raise p.toolkit.CkanVersionException(msg) def before_map(self, map): From fd84f24d56ff2e01b890f7d464608b2046003cd4 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 14 Jun 2013 16:08:25 +0100 Subject: [PATCH 040/114] [#22] More details about resource_proxy --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 5da233e..5ad180e 100644 --- a/README.rst +++ b/README.rst @@ -289,8 +289,8 @@ WMS Preview ----------- To enable the WMS previewer you need to add the ``wms_preview`` plugin to your -ini file (See `Configuration`_). This plugin also requires the ``resource_proxy`` -plugin. +ini file (See `Configuration`_). This plugin also requires the `resource_proxy `_ +plugin (part of CKAN core). Please note that this is an experimental plugin and may be unstable. From f8dd4c02bdeaa602452735081b6b6a3a793a78ad Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 14 Jun 2013 17:37:44 +0100 Subject: [PATCH 041/114] [#21] Fix i18n calls All the 'self' on the 'showError' function should be 'this', otherwise you will refer to the window. Also 'this.i18n' assumes an 'i18n' key in the module options. Looks like you are trying to pass some variables to the string template, note the sprintf-like syntax. --- ckanext/spatial/public/js/geojson_preview.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ckanext/spatial/public/js/geojson_preview.js b/ckanext/spatial/public/js/geojson_preview.js index 95f3f5a..19e5391 100644 --- a/ckanext/spatial/public/js/geojson_preview.js +++ b/ckanext/spatial/public/js/geojson_preview.js @@ -8,6 +8,9 @@ ckan.module('geojsonpreview', function (jQuery, _) { opacity: 0.7, fillOpacity: 0.1, weight: 2 + }, + i18n: { + 'error': _('An error occurred: %(text)s %(error)s') } }, initialize: function () { @@ -58,15 +61,15 @@ ckan.module('geojsonpreview', function (jQuery, _) { showError: function (jqXHR, textStatus, errorThrown) { if (textStatus == 'error' && jqXHR.responseText.length) { - self.el.html(jqXHR.responseText); + this.el.html(jqXHR.responseText); } else { - self.el.html(self.i18n('error', {text: textStatus, error: errorThrown})); + this.el.html(this.i18n('error', {text: textStatus, error: errorThrown})); } }, showPreview: function (geojsonFeature) { var self = this; - var gjLayer = L.geoJson(undefined, { + var gjLayer = L.geoJson(geojsonFeature, { style: self.options.style, onEachFeature: function(feature, layer) { var body = ''; @@ -80,7 +83,6 @@ ckan.module('geojsonpreview', function (jQuery, _) { layer.bindPopup(popupContent); } }).addTo(self.map); - gjLayer.addData(geojsonFeature); self.map.fitBounds(gjLayer.getBounds()); } }; From e30b662a368c0f5e81c2954022ce2dbc92f02bab Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 14 Jun 2013 17:40:39 +0100 Subject: [PATCH 042/114] [#21] Make popup table match the rest of CKAN tables --- ckanext/spatial/public/css/geojson_preview.css | 16 ++-------------- ckanext/spatial/public/js/geojson_preview.js | 2 +- .../spatial/templates/dataviewer/geojson.html | 4 ++++ 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/ckanext/spatial/public/css/geojson_preview.css b/ckanext/spatial/public/css/geojson_preview.css index 4220ee8..0dd66e5 100644 --- a/ckanext/spatial/public/css/geojson_preview.css +++ b/ckanext/spatial/public/css/geojson_preview.css @@ -2,6 +2,7 @@ html, body { height: 600px; padding: 0; margin: 0; + background: none; } #map { @@ -10,19 +11,6 @@ html, body { height: 100%; } -.popup-table { - border-collapse: collapse; - border: 1px solid #bbb; - table-layout: fixed; +#map .table{ width: 300px; } - -.popup-table td, .popup-table th { - border: 1px solid #bbb; - padding: 4px; - word-wrap: break-word; -} - -.popup-table tr:nth-child(even) { - background-color: #eee; -} \ No newline at end of file diff --git a/ckanext/spatial/public/js/geojson_preview.js b/ckanext/spatial/public/js/geojson_preview.js index 19e5391..d656061 100644 --- a/ckanext/spatial/public/js/geojson_preview.js +++ b/ckanext/spatial/public/js/geojson_preview.js @@ -2,7 +2,7 @@ ckan.module('geojsonpreview', function (jQuery, _) { return { options: { - table: '{body}', + table: '{body}
', row:'{key}{value}', style: { opacity: 0.7, diff --git a/ckanext/spatial/templates/dataviewer/geojson.html b/ckanext/spatial/templates/dataviewer/geojson.html index 29c6bc3..6ee998e 100644 --- a/ckanext/spatial/templates/dataviewer/geojson.html +++ b/ckanext/spatial/templates/dataviewer/geojson.html @@ -1,6 +1,10 @@ {% extends "dataviewer/base.html" %} {% block page %} + {%- block styles %} + {% resource g.main_css[6:] %} + {% endblock %} +

From 40ff7284cc24ade6c19b4821f2df5585e65029c7 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 14 Jun 2013 18:14:31 +0100 Subject: [PATCH 043/114] [#21] Add geojson previewer to index --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 26f327b..ae65036 100644 --- a/README.rst +++ b/README.rst @@ -9,6 +9,7 @@ The following plugins are currently available: * `Spatial Search`_ - Spatial filtering for the dataset search (``spatial_query``). * `Spatial Harvesters`_ - for importing spatial metadata into CKAN (``csw_harvester``, ``doc_harvester``, ``waf_harvester``) * `Harvest Metadata API`_ - a way for a user to view the harvested metadata XML, either as a raw file or styled to view in a web browser. (``spatial_harvest_metadata_api``) +* `GeoJSON Preview`_ - a GeoJSON previewer (``geojson_preview``). * `WMS Preview`_ - a Web Map Service (WMS) previewer (``wms_preview``). * `CSW Server`_ - a basic CSW server - to server metadata from the CKAN instance (``cswserver``) From 7b65813cbaa0796d3e2dc767eb64afcc5bb467de Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 20 Jun 2013 15:48:40 +0100 Subject: [PATCH 044/114] [#24] Add command for pycsw integration Based on the work by @kindly on https://github.com/kindly/ckan_pycsw_import, adds a command to the extension that allows to export easily the spatial datasets to pycsw. This will only work for harvested ISO datasets for the time being. The command can be run both via paster (in the context of a CKAN install) or independently (eg a separate server), as it uses the API to get the datasets. TODO docs --- bin/__init__.py | 7 + bin/ckan_pycsw.py | 309 ++++++++++++++++++++++++++++++++ ckanext/spatial/commands/csw.py | 55 ++++++ setup.py | 1 + 4 files changed, 372 insertions(+) create mode 100644 bin/__init__.py create mode 100644 bin/ckan_pycsw.py create mode 100644 ckanext/spatial/commands/csw.py diff --git a/bin/__init__.py b/bin/__init__.py new file mode 100644 index 0000000..2e2033b --- /dev/null +++ b/bin/__init__.py @@ -0,0 +1,7 @@ +# this is a namespace package +try: + import pkg_resources + pkg_resources.declare_namespace(__name__) +except ImportError: + import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py new file mode 100644 index 0000000..b72f60d --- /dev/null +++ b/bin/ckan_pycsw.py @@ -0,0 +1,309 @@ +import sys +import logging +import datetime +import io + +import requests +from lxml import etree + +from pycsw import metadata, repository, util +import pycsw.config + +logging.basicConfig(format='%(message)s', level=logging.INFO) + +log = logging.getLogger(__name__) + +def setup_db(pycsw_config): + """Setup database tables and indexes""" + from sqlalchemy import Column, create_engine, Integer, MetaData, \ + Table, Text + + database = pycsw_config.get('repository', 'database') + table_name = pycsw_config.get('repository', 'table', 'records') + + log.debug('Creating engine') + engine = create_engine(database) + + mdata = MetaData(engine) + + log.info('Creating table %s', table_name) + records = Table( + table_name, mdata, + # core; nothing happens without these + Column('identifier', Text, primary_key=True), + Column('typename', Text, + default='csw:Record', nullable=False, index=True), + Column('schema', Text, + default='http://www.opengis.net/cat/csw/2.0.2', nullable=False, + index=True), + Column('mdsource', Text, default='local', nullable=False, + index=True), + Column('insert_date', Text, nullable=False, index=True), + Column('xml', Text, nullable=False), + Column('anytext', Text, nullable=False), + Column('language', Text, index=True), + + # identification + Column('type', Text, index=True), + Column('title', Text, index=True), + Column('title_alternate', Text, index=True), + Column('abstract', Text), + Column('keywords', Text), + Column('keywordstype', Text, index=True), + Column('parentidentifier', Text, index=True), + Column('relation', Text, index=True), + Column('time_begin', Text, index=True), + Column('time_end', Text, index=True), + Column('topicategory', Text, index=True), + Column('resourcelanguage', Text, index=True), + + # attribution + Column('creator', Text, index=True), + Column('publisher', Text, index=True), + Column('contributor', Text, index=True), + Column('organization', Text, index=True), + + # security + Column('securityconstraints', Text), + Column('accessconstraints', Text), + Column('otherconstraints', Text), + + # date + Column('date', Text, index=True), + Column('date_revision', Text, index=True), + Column('date_creation', Text, index=True), + Column('date_publication', Text, index=True), + Column('date_modified', Text, index=True), + + Column('format', Text, index=True), + Column('source', Text, index=True), + + # geospatial + Column('crs', Text, index=True), + Column('geodescode', Text, index=True), + Column('denominator', Integer, index=True), + Column('distancevalue', Integer, index=True), + Column('distanceuom', Text, index=True), + Column('wkt_geometry', Text), + + # service + Column('servicetype', Text, index=True), + Column('servicetypeversion', Text, index=True), + Column('operation', Text, index=True), + Column('couplingtype', Text, index=True), + Column('operateson', Text, index=True), + Column('operatesonidentifier', Text, index=True), + Column('operatesoname', Text, index=True), + + # additional + Column('degree', Text, index=True), + Column('classification', Text, index=True), + Column('conditionapplyingtoaccessanduse', Text, index=True), + Column('lineage', Text, index=True), + Column('responsiblepartyrole', Text, index=True), + Column('specificationtitle', Text, index=True), + Column('specificationdate', Text, index=True), + Column('specificationdatetype', Text, index=True), + + # distribution + # links: format "name,description,protocol,url[^,,,[^,,,]]" + Column('links', Text, index=True), + + Column('ckan_id', Text, index=True), + Column('ckan_modified', Text), + ) + records.create() + + +def load(pycsw_config, ckan_url): + + database = pycsw_config.get('repository', 'database') + table_name = pycsw_config.get('repository', 'table', 'records') + + context = pycsw.config.StaticContext() + repo = repository.Repository(database, context, table=table_name) + ckan_url = ckan_url.lstrip('/') + '/' + + log.info('Started gathering CKAN datasets identifiers: {0}'.format(str(datetime.datetime.now()))) + + query = 'api/search/dataset?qjson={"fl":"id,metadata_modified,extras_harvest_object_id,extras_metadata_source", "q":"harvest_object_id:*", "limit":1000, "start":%s}' + + start = 0 + + gathered_records = {} + + while True: + url = ckan_url + query % start + + response = requests.get(url) + listing = response.json() + results = listing.get('results') + if not results: + break + for result in results: + gathered_records[result['id']] = { + 'metadata_modified': result['metadata_modified'], + 'harvest_object_id': result['extras']['harvest_object_id'], + 'source': result['extras'].get('metadata_source') + } + + start = start + 1000 + log.debug('Gathered %s' % start) + + log.info('Gather finished ({0} datasets): {1}'.format( + len(gathered_records.keys()), + str(datetime.datetime.now()))) + + existing_records = {} + + query = repo.session.query(repo.dataset.ckan_id, repo.dataset.ckan_modified) + for row in query: + existing_records[row[0]] = row[1] + repo.session.close() + + new = set(gathered_records) - set(existing_records) + deleted = set(existing_records) - set(gathered_records) + changed = set() + + for key in set(gathered_records) & set(existing_records): + if gathered_records[key]['metadata_modified'] > existing_records[key]: + changed.add(key) + + for ckan_id in deleted: + try: + repo.session.begin() + repo.session.query(repo.dataset.ckan_id).filter_by( + ckan_id=ckan_id).delete() + log.info('Deleted %s' % ckan_id) + repo.session.commit() + except Exception, err: + repo.session.rollback() + raise + + for ckan_id in new: + ckan_info = gathered_records[ckan_id] + record = get_record(context, repo, ckan_url, ckan_id, ckan_info) + if not record: + log.info('Skipped record %s' % ckan_id) + continue + try: + repo.insert(record, 'local', util.get_today_and_now()) + log.info('Inserted %s' % ckan_id) + except Exception, err: + log.error('ERROR: not inserted %s Error:%s' % (ckan_id, err)) + + for ckan_id in changed: + ckan_info = gathered_records[ckan_id] + record = get_record(context, repo, ckan_url, ckan_id, ckan_info) + if not record: + continue + update_dict = dict([(getattr(repo.dataset, key), + getattr(record, key)) \ + for key in record.__dict__.keys() if key != '_sa_instance_state']) + try: + repo.session.begin() + repo.session.query(repo.dataset).filter_by( + ckan_id=ckan_id).update(update_dict) + repo.session.commit() + log.info('Changed %s' % ckan_id) + except Exception, err: + repo.session.rollback() + raise RuntimeError, 'ERROR: %s' % str(err) + + +def get_record(context, repo, ckan_url, ckan_id, ckan_info): + query = ckan_url + 'harvest/object/%s' + url = query % ckan_info['harvest_object_id'] + response = requests.get(url) + + if ckan_info['source'] == 'arcgis': + return + + try: + xml = etree.parse(io.BytesIO(response.content)) + except Exception, err: + log.error('Could not pass xml doc from %s, Error: %s' % (ckan_id, err)) + return + + try: + record = metadata.parse_record(context, xml, repo)[0] + except Exception, err: + log.error('Could not extract metadata from %s, Error: %s' % (ckan_id, err)) + return + + if not record.identifier: + record.identifier = ckan_id + record.ckan_id = ckan_id + record.ckan_modified = ckan_info['metadata_modified'] + + return record + + +usage=''' +Manages the CKAN-pycsw integration + + python ckan-pycsw.py setup [-p] + Setups the necessary pycsw table on the db. + + python ckan-pycsw.py load [-p] -u + Loads CKAN datasets as records into the pycsw db. + +All commands require the pycsw configuration file. By default it will try +to find a file called 'default.cfg' in the same directory, but you'll +probably need to provide the actual location via the -p option: + + paster ckan-pycsw setup -p /etc/pycsw/default.cfg + +The load command requires a CKAN URL from where the datasets will be pulled: + + paster ckan-pycsw setup -p /etc/pycsw/default.cfg -u http://localhost + +''' + +def _load_config(file_path): + abs_path = os.path.abspath(file_path) + if not os.path.exists(abs_path): + raise AssertionError('pycsw config file {0} does not exist.'.format(abs_path)) + + config = SafeConfigParser() + config.read(abs_path) + + return config + + + +import os +import argparse +from ConfigParser import SafeConfigParser + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='\n'.split(usage)[0], + usage=usage) + parser.add_argument('command', + help='Command to perform') + + parser.add_argument('-p', '--pycsw_config', + action='store', default='default.cfg', + help='Path to pycsw config file') + + parser.add_argument('-u', '--ckan_url', + action='store', + help='CKAN URL') + + if len(sys.argv) <= 1: + parser.print_usage() + sys.exit(1) + + arg = parser.parse_args() + pycsw_config = _load_config(arg.pycsw_config) + + if arg.command == 'setup': + setup_db(pycsw_config) + elif arg.command == 'load': + if not arg.ckan_url: + raise AssertionError('You need to provide a CKAN URL with -u or --ckan_url') + load(pycsw_config, arg.ckan_url) + else: + print 'Unknown command {0}'.format(arg.command) + sys.exit(1) diff --git a/ckanext/spatial/commands/csw.py b/ckanext/spatial/commands/csw.py new file mode 100644 index 0000000..acd1b76 --- /dev/null +++ b/ckanext/spatial/commands/csw.py @@ -0,0 +1,55 @@ +import sys +import logging + +from bin import ckan_pycsw + +from paste import script +log = logging.getLogger(__name__) +class Pycsw(script.command.Command): + '''Manages the CKAN-pycsw integration + + ckan-pycsw setup [-p] + Setups the necessary pycsw table on the db. + + ckan-pycsw load [-p] [-u] + Loads CKAN datasets as records into the pycsw db. + +All commands require the pycsw configuration file. By default it will try +to find a file called 'default.cfg' in the same directory, but you'll +probably need to provide the actual location with the -p option. + + paster ckan-pycsw setup -p /etc/pycsw/default.cfg + +The load command requires a CKAN URL from where the datasets will be pulled. +By default it is set to 'http://localhost', but you can define it with the -u +option: + + paster ckan-pycsw setup -p /etc/pycsw/default.cfg -u http://ckan.instance.org + + ''' + + parser = script.command.Command.standard_parser(verbose=True) + parser.add_option('-p', '--pycsw-config', dest='pycsw_config', + default='default.cfg', help='pycsw config file to use.') + parser.add_option('-u', '--ckan-url', dest='ckan_url', + default='http://localhost', help='pycsw config file to use.') + + summary = __doc__.split('\n')[0] + usage = __doc__ + max_args = 2 + min_args = 0 + + def command(self): + if len(self.args) == 0: + self.parser.print_usage() + sys.exit(1) + + config = ckan_pycsw._load_config(self.options.pycsw_config) + cmd = self.args[0] + if cmd == 'setup': + ckan_pycsw.setup_db(config) + elif cmd == 'load': + ckan_url = self.options.ckan_url + ckan_pycsw.load(config, ckan_url) + else: + print 'Command %s not recognized' % cmd diff --git a/setup.py b/setup.py index 87ecb86..1822fb1 100644 --- a/setup.py +++ b/setup.py @@ -46,6 +46,7 @@ setup( [paste.paster_command] spatial=ckanext.spatial.commands.spatial:Spatial + ckan-pycsw=ckanext.spatial.commands.csw:Pycsw validation=ckanext.spatial.commands.validation:Validation """, ) From 67b0941b3b55eac3f08549849f2c2c5bb2d16a58 Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 20 Jun 2013 16:45:37 +0100 Subject: [PATCH 045/114] [#24] Add clear command to empty the pycsw table --- bin/ckan_pycsw.py | 16 ++++++++++++++++ ckanext/spatial/commands/csw.py | 2 ++ 2 files changed, 18 insertions(+) diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py index b72f60d..f7d4a0e 100644 --- a/bin/ckan_pycsw.py +++ b/bin/ckan_pycsw.py @@ -211,6 +211,20 @@ def load(pycsw_config, ckan_url): raise RuntimeError, 'ERROR: %s' % str(err) +def clear(pycsw_config): + + from sqlalchemy import create_engine, MetaData, Table + + database = pycsw_config.get('repository', 'database') + table_name = pycsw_config.get('repository', 'table', 'records') + + log.debug('Creating engine') + engine = create_engine(database) + records = Table(table_name, MetaData(engine)) + records.delete().execute() + log.info('Table cleared') + + def get_record(context, repo, ckan_url, ckan_id, ckan_info): query = ckan_url + 'harvest/object/%s' url = query % ckan_info['harvest_object_id'] @@ -304,6 +318,8 @@ if __name__ == '__main__': if not arg.ckan_url: raise AssertionError('You need to provide a CKAN URL with -u or --ckan_url') load(pycsw_config, arg.ckan_url) + elif arg.command == 'clear': + clear(pycsw_config) else: print 'Unknown command {0}'.format(arg.command) sys.exit(1) diff --git a/ckanext/spatial/commands/csw.py b/ckanext/spatial/commands/csw.py index acd1b76..6d2fa3f 100644 --- a/ckanext/spatial/commands/csw.py +++ b/ckanext/spatial/commands/csw.py @@ -51,5 +51,7 @@ option: elif cmd == 'load': ckan_url = self.options.ckan_url ckan_pycsw.load(config, ckan_url) + elif cmd == 'clear': + ckan_pycsw.clear(config) else: print 'Command %s not recognized' % cmd From d4ffc9bf62b1a988c337b9a10d6047949627e22e Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 21 Jun 2013 11:46:50 +0100 Subject: [PATCH 046/114] [#24] Capture error when we get a wrong API response --- bin/ckan_pycsw.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py index f7d4a0e..0b006db 100644 --- a/bin/ckan_pycsw.py +++ b/bin/ckan_pycsw.py @@ -137,6 +137,8 @@ def load(pycsw_config, ckan_url): response = requests.get(url) listing = response.json() + if not isinstance(listing, dict): + raise RuntimeError, 'Wrong API response: %s' % listing results = listing.get('results') if not results: break From 6699d1e49804783b7b7eca1b06e2e712cfb9002e Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 21 Jun 2013 11:47:02 +0100 Subject: [PATCH 047/114] [#24] Update API query to make it compatible with older Solr versions The following expression is not valid in Solr 1.X: "q":"harvest_object_id:*" It returns the following error: '*' or '?' not allowed as first character in WildcardQuery It has been replaced with: "q":"harvest_object_id:[\"\" TO *]" --- bin/ckan_pycsw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py index 0b006db..8d303fb 100644 --- a/bin/ckan_pycsw.py +++ b/bin/ckan_pycsw.py @@ -126,7 +126,7 @@ def load(pycsw_config, ckan_url): log.info('Started gathering CKAN datasets identifiers: {0}'.format(str(datetime.datetime.now()))) - query = 'api/search/dataset?qjson={"fl":"id,metadata_modified,extras_harvest_object_id,extras_metadata_source", "q":"harvest_object_id:*", "limit":1000, "start":%s}' + query = 'api/search/dataset?qjson={"fl":"id,metadata_modified,extras_harvest_object_id,extras_metadata_source", "q":"harvest_object_id:[\"\" TO *]", "limit":1000, "start":%s}' start = 0 From ae9750f8eca0d9cdbca8e4539cffd68ae85808c6 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 21 Jun 2013 11:59:04 +0100 Subject: [PATCH 048/114] [#24] Escape properly expression in last commit --- bin/ckan_pycsw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py index 8d303fb..4a26d6b 100644 --- a/bin/ckan_pycsw.py +++ b/bin/ckan_pycsw.py @@ -126,7 +126,7 @@ def load(pycsw_config, ckan_url): log.info('Started gathering CKAN datasets identifiers: {0}'.format(str(datetime.datetime.now()))) - query = 'api/search/dataset?qjson={"fl":"id,metadata_modified,extras_harvest_object_id,extras_metadata_source", "q":"harvest_object_id:[\"\" TO *]", "limit":1000, "start":%s}' + query = 'api/search/dataset?qjson={"fl":"id,metadata_modified,extras_harvest_object_id,extras_metadata_source", "q":"harvest_object_id:[\\"\\" TO *]", "limit":1000, "start":%s}' start = 0 From 44e4ae380a04ec1a08132407818db00e9cd39a49 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 21 Jun 2013 13:21:30 +0100 Subject: [PATCH 049/114] [#24] Document CKAN-pycsw integration Ad overview of how it works, how to set it up and deploy it in a production server. --- README.rst | 180 +++++++++++++++++++++++++++++++- bin/ckan_pycsw.py | 11 +- ckanext/spatial/commands/csw.py | 9 +- 3 files changed, 191 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index ae65036..f207258 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ The following plugins are currently available: * `Harvest Metadata API`_ - a way for a user to view the harvested metadata XML, either as a raw file or styled to view in a web browser. (``spatial_harvest_metadata_api``) * `GeoJSON Preview`_ - a GeoJSON previewer (``geojson_preview``). * `WMS Preview`_ - a Web Map Service (WMS) previewer (``wms_preview``). -* `CSW Server`_ - a basic CSW server - to server metadata from the CKAN instance (``cswserver``) +* `CSW Server`_ - a basic CSW server - to server metadata from the CKAN instance (``cswserver``). **Deprecated:** Please see `ckan-pycsw`_. These snippets (to be used with CKAN>=2.0): @@ -26,8 +26,10 @@ These libraries: And these command-line tools: +* `ckan-pycsw`_ - a command for integrating CKAN with `pycsw `_, a fully compliant CSW server. * `cswinfo`_ - a command-line tool to help making requests of any CSW server + As of October 2012, ckanext-csw and ckanext-inspire were merged into this extension. About the components @@ -311,9 +313,180 @@ When the plugin is enabled, if datasets contain a resource that has 'gjson' or ' format, the resource page will load simple map viewer that will show the features on a map. +ckan-pycsw +---------- + +The spatial extension offers the ``ckan-pycsw`` command, which allows to expose +the spatial datasets harvested from other sources in a CSW interface. This is +powered by `pycsw `_, which fully implements the OGC CSW +specification. + +How it works +++++++++++++ + + +The current implementation is based on CKAN and pycsw being loosely integrated +via the CKAN API. pycsw will be generally installed in the same server as CKAN +(although it can also be run on a separate one), and the synchronization +command will be run regularly to keep the records on the pycsw repository up to +date. This is done using the CKAN API to get all the datasets identifiers (more +precisely the ones from datasets that have been harvested) and then deciding +which ones need to be created, updated or deleted on the pycsw repository. For +those that need to be created or updated, the original harvested spatial +document (ie ISO 19139) is requested from CKAN, and it is then imported using +pycsw internal functions:: + + Harvested + datasets + + + | + v + +--------+ +---------+ + | | CKAN API | | + | CKAN | +------------> | pycsw | +------> CSW + | | | | + +--------+ +---------+ + + +Remember, only datasets that were harvested with the `Spatial Harvesters`_ +can currently be exposed via pycsw. + +All necessary tasks are done with the ``ckan-pycsw`` command. To get more +details of its usage, run the following:: + + cd /usr/lib/ckan/default/src/ckanext-spatial + paster ckan-pycsw --help + + +Setup ++++++ + +1. Install pycsw. There are several options for this, depending on your + server setup, check the `pycsw documentation `_. + + The following instructions assume that you have installed CKAN via a + `package install `_ + and should be run as root, but the steps are the same if you are setting + it up in another location:: + + cd /usr/lib/ckan/default/src + source ../bin/activate + + # From now on the virtualenv should be activated + + git clone https://github.com/geopython/pycsw.git + cd pycsw + pip install -e . && pip install -r requirements.txt + python setup.py build + python setup.py install + +2. Create a database for pycsw. In theory you can use the same database that + CKAN is using, but if you want to keep them separated, use the following + command to create a new one (we'll use the same default user though):: + + sudo -u postgres createdb -O ckan_default pycsw -E utf-8 + +3. Configure pycsw. An example configuration file is included on the source:: + + cp default-sample.cfg default.cfg + + To keep things tidy we will create a symlink to this file on the CKAN + configuration directory:: + + ln -s /usr/lib/ckan/default/src/pycsw/default.cfg /etc/ckan/default/pycsw.cfg + + Open the file with your favourite editor. The main settings you should tweak + are ``server.home`` and ``repository.database``:: + + [server] + home=/usr/lib/ckan/default/src/pycsw + ... + [repository] + database=postgresql://ckan_default:pass@localhost/pycsw + + The rest of the options are described `here `_. + +4. Setup the pycsw table. This is done with the ``ckan-pycsw`` paster command + (Remember to have the virtualenv activated when running it):: + + cd /usr/lib/ckan/default/src/ckanext-spatial + paster ckan-pycsw setup -p /etc/ckan/default/pycsw.cfg + + At this point you should be ready to run pycsw with the wsgi script that it + includes:: + + cd /usr/lib/ckan/default/src/pycsw + python csw.wsgi + + This will run pycsw at http://localhost:8000. Visiting the following URL + should return you the Capabilities file: + + http://localhost:8000?service=CSW&version=2.0.2&request=GetCapabilities + +5. Load the CKAN datasets into pycsw. Again we will use the ``ckan-pycsw`` + command for this:: + + cd /usr/lib/ckan/default/src/ckanext-spatial + paster ckan-pycsw load -p /etc/ckan/default/pycsw.cfg + + When the loading is finished, check that results are returned when visiting + this link: + + http://localhost:8000/?request=GetRecords&service=CSW&version=2.0.2&resultType=results&outputSchema=http://www.isotc211.org/2005/gmd&typeNames=csw:Record&elementSetName=summary + + The ``numberOfRecordsMatched`` should match the number of harvested datasets + in CKAN (minus import errors). If you run the command again new or udpated + datasets will be synchronized and deleted datasets from CKAN will be removed + from pycsw as well. + +Running it on production site ++++++++++++++++++++++++++++++ + +On a production site you probably want to run the load command regularly to +keep CKAN and pycsw in sync, and serve pycsw with Apache + mod_wsgi like CKAN. + +* To run the load command regularly you can set up a cron job. Type ``crontab -e`` + and copy the following lines:: + + # m h dom mon dow command + 0 * * * * /usr/lib/ckan/default/bin/paster --plugin=ckanext-spatial ckan-pycsw load -p /etc/ckan/default/pycsw.cfg + + This particular example will run the load command every hour. You can of + course modify this periodicity, for instance reducing it for huge instances. + This `Wikipedia page `_ + has a good overview of the crontab syntax. + +* To run pycsw under Apache check the pycsw `installation documentation `_ + or follow this quick steps (they assume the paths used on the previous steps): + + - Edit ``/etc/apache2/sites-available/ckan_default`` and add the following + line just before the existing ``WSGIScriptAlias`` directive:: + + WSGIScriptAlias /csw /usr/lib/ckan/default/src/pycsw/csw.wsgi + + - Edit the ``/usr/lib/ckan/default/src/pycsw/csw.wsgi`` file and add these two + lines just after the imports on the top of the file:: + + activate_this = os.path.join('/usr/lib/ckan/default/bin/activate_this.py') + execfile(activate_this, {"__file__":activate_this}) + + We need these to activate the virtualenv where we installed pycsw into. + + - Restart Apache:: + + service apache2 restart + + pycsw should be now accessible at http://localhost/csw + + + + CSW Server ---------- +.. note:: **Deprecated:** The old csw plugin has been deprecated, please see `ckan-pycsw`_ + for details on how to integrate with pycsw. + CSW (Catalogue Service for the Web) is an OGC standard for a web interface that allows you to access metadata (which are records that describe data or services) The currently supported methods with this CSW Server are: @@ -449,7 +622,7 @@ To specify which validators to use during harvesting, specify their names in CKA cswinfo ------- -When ckanext-csw is installed, it provides a command-line tool ``cswinfo``, for making queries on CSW servers and returns the info in nicely formatted JSON. This may be more convenient to type than using, for example, curl. +The command-line tool ``cswinfo`` allows to make queries on CSW servers and returns the info in nicely formatted JSON. This may be more convenient to type than using, for example, curl. Currently available queries are: * getcapabilities @@ -565,6 +738,9 @@ the EPSG code as an integer (e.g 4326, 4258, 27700, etc). It defaults to Configuration - CSW Server -------------------------- +.. note:: **Deprecated:** The old csw plugin has been deprecated, please see `ckan-pycsw`_ + for details on how to integrate with pycsw. + Configure the CSW Server with the following keys in your CKAN config file (default values are shown):: cswservice.title = Untitled Service - set cswservice.title in config diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py index 4a26d6b..cc8c22e 100644 --- a/bin/ckan_pycsw.py +++ b/bin/ckan_pycsw.py @@ -264,15 +264,18 @@ Manages the CKAN-pycsw integration python ckan-pycsw.py load [-p] -u Loads CKAN datasets as records into the pycsw db. + python ckan-pycsw.py clear [-p] + Removes all records from the pycsw table. + All commands require the pycsw configuration file. By default it will try to find a file called 'default.cfg' in the same directory, but you'll probably need to provide the actual location via the -p option: - paster ckan-pycsw setup -p /etc/pycsw/default.cfg + paster ckan-pycsw setup -p /etc/ckan/default/pycsw.cfg The load command requires a CKAN URL from where the datasets will be pulled: - paster ckan-pycsw setup -p /etc/pycsw/default.cfg -u http://localhost + paster ckan-pycsw load -p /etc/ckan/default/pycsw.cfg -u http://localhost ''' @@ -301,11 +304,11 @@ if __name__ == '__main__': parser.add_argument('-p', '--pycsw_config', action='store', default='default.cfg', - help='Path to pycsw config file') + help='pycsw config file to use.') parser.add_argument('-u', '--ckan_url', action='store', - help='CKAN URL') + help='CKAN instance to import the datasets from.') if len(sys.argv) <= 1: parser.print_usage() diff --git a/ckanext/spatial/commands/csw.py b/ckanext/spatial/commands/csw.py index 6d2fa3f..3375d8b 100644 --- a/ckanext/spatial/commands/csw.py +++ b/ckanext/spatial/commands/csw.py @@ -14,17 +14,20 @@ class Pycsw(script.command.Command): ckan-pycsw load [-p] [-u] Loads CKAN datasets as records into the pycsw db. + ckan-pycsw clear [-p] + Removes all records from the pycsw table. + All commands require the pycsw configuration file. By default it will try to find a file called 'default.cfg' in the same directory, but you'll probably need to provide the actual location with the -p option. - paster ckan-pycsw setup -p /etc/pycsw/default.cfg + paster ckan-pycsw setup -p /etc/ckan/default/pycsw.cfg The load command requires a CKAN URL from where the datasets will be pulled. By default it is set to 'http://localhost', but you can define it with the -u option: - paster ckan-pycsw setup -p /etc/pycsw/default.cfg -u http://ckan.instance.org + paster ckan-pycsw load -p /etc/ckan/default/pycsw.cfg -u http://ckan.instance.org ''' @@ -32,7 +35,7 @@ option: parser.add_option('-p', '--pycsw-config', dest='pycsw_config', default='default.cfg', help='pycsw config file to use.') parser.add_option('-u', '--ckan-url', dest='ckan_url', - default='http://localhost', help='pycsw config file to use.') + default='http://localhost', help='CKAN instance to import the datasets from.') summary = __doc__.split('\n')[0] usage = __doc__ From f4ea4da3e0bcdbf9a2638558a980e6a8c279f00e Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Fri, 19 Jul 2013 12:35:35 +0200 Subject: [PATCH 050/114] [#29] Use new precedence feature for previews. --- ckanext/spatial/nongeos_plugin.py | 40 ++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/ckanext/spatial/nongeos_plugin.py b/ckanext/spatial/nongeos_plugin.py index 69151b5..360acb0 100644 --- a/ckanext/spatial/nongeos_plugin.py +++ b/ckanext/spatial/nongeos_plugin.py @@ -11,6 +11,8 @@ class WMSPreview(p.SingletonPlugin): p.implements(p.IConfigurer, inherit=True) p.implements(p.IResourcePreview, inherit=True) + WMS = ['wms'] + def update_config(self, config): p.toolkit.add_public_directory(config, 'public') @@ -28,13 +30,22 @@ class WMSPreview(p.SingletonPlugin): p.toolkit.c.resource['proxy_url'] = data_dict['resource']['url'] def can_preview(self, data_dict): - format_lower = data_dict['resource']['format'].lower() + correct_format = format_lower in self.WMS + can_preview_from_domain = self.proxy_enabled or data_dict['resource']['on_same_domain'] + quality = 2 - check = format_lower in ['wms'] - if not self.proxy_enabled and check: - check = data_dict['resource']['on_same_domain'] + if p.toolkit.check_ckan_version('2.1'): + if correct_format: + if can_preview_from_domain: + return {'can_preview': True, 'quality': quality} + else: + return {'can_preview': False, + 'fixable': 'Enable resource_proxy', + 'quality': quality} + else: + return {'can_preview': False, 'quality': quality} - return check + return correct_format and can_preview_from_domain def preview_template(self, context, data_dict): return 'dataviewer/wms.html' @@ -61,11 +72,22 @@ class GeoJSONPreview(p.SingletonPlugin): def can_preview(self, data_dict): format_lower = data_dict['resource']['format'].lower() - check = format_lower in self.GeoJSON - if not self.proxy_enabled and check: - check = data_dict['resource']['on_same_domain'] + correct_format = format_lower in self.GeoJSON + can_preview_from_domain = self.proxy_enabled or data_dict['resource']['on_same_domain'] + quality = 2 - return check + if p.toolkit.check_ckan_version('2.1'): + if correct_format: + if can_preview_from_domain: + return {'can_preview': True, 'quality': quality} + else: + return {'can_preview': False, + 'fixable': 'Enable resource_proxy', + 'quality': quality} + else: + return {'can_preview': False, 'quality': quality} + + return correct_format and can_preview_from_domain def setup_template_variables(self, context, data_dict): import ckanext.resourceproxy.plugin as proxy From f0aa5076a0f817f32bd7007511686af6b418c36a Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Fri, 19 Jul 2013 23:04:49 +0200 Subject: [PATCH 051/114] [#29] Fix missing variable --- ckanext/spatial/nongeos_plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ckanext/spatial/nongeos_plugin.py b/ckanext/spatial/nongeos_plugin.py index 360acb0..a1baeeb 100644 --- a/ckanext/spatial/nongeos_plugin.py +++ b/ckanext/spatial/nongeos_plugin.py @@ -21,7 +21,6 @@ class WMSPreview(p.SingletonPlugin): self.proxy_enabled = p.toolkit.asbool(config.get('ckan.resource_proxy_enabled', 'False')) - def setup_template_variables(self, context, data_dict): import ckanext.resourceproxy.plugin as proxy if self.proxy_enabled and not data_dict['resource']['on_same_domain']: @@ -30,6 +29,8 @@ class WMSPreview(p.SingletonPlugin): p.toolkit.c.resource['proxy_url'] = data_dict['resource']['url'] def can_preview(self, data_dict): + format_lower = data_dict['resource']['format'].lower() + correct_format = format_lower in self.WMS can_preview_from_domain = self.proxy_enabled or data_dict['resource']['on_same_domain'] quality = 2 From b6bd5ca308ddda0e187b2ba8c7ff1ae234c72a6b Mon Sep 17 00:00:00 2001 From: David Read Date: Mon, 22 Jul 2013 21:48:13 +0100 Subject: [PATCH 052/114] [noticket] Notes about CSW limitation. Example GetRecords. --- README.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.rst b/README.rst index ae65036..294cd13 100644 --- a/README.rst +++ b/README.rst @@ -316,6 +316,8 @@ CSW Server CSW (Catalogue Service for the Web) is an OGC standard for a web interface that allows you to access metadata (which are records that describe data or services) +NB Only 'harvested' datasets are served by this CSW Server. This is because the harvested document is the one that is served, not something derived from the CKAN Dataset object. Datasets that are created in CKAN by methods other than harvesting are not served. + The currently supported methods with this CSW Server are: * GetCapabilities * GetRecords @@ -327,6 +329,10 @@ For example you can ask the capabilities of the CSW server installed into CKAN r curl 'http://127.0.0.1:5000/csw?request=GetCapabilities&service=CSW' +And get a list of the records like this:: + + curl 'http://127.0.0.1:5000/csw?request=GetRecords&service=CSW&resultType=results&elementSetName=full' + The standard CSW response is in XML format. Spatial Harvesters From 14048a153c705e5706962e4816eee8021c083a7f Mon Sep 17 00:00:00 2001 From: amercader Date: Mon, 29 Jul 2013 17:23:21 +0100 Subject: [PATCH 053/114] [#31] Check if sort parameter exists --- ckanext/spatial/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ckanext/spatial/plugin.py b/ckanext/spatial/plugin.py index 3a8dc75..1d22cc2 100644 --- a/ckanext/spatial/plugin.py +++ b/ckanext/spatial/plugin.py @@ -280,7 +280,7 @@ class SpatialQuery(p.SingletonPlugin): # Note: This will be deprecated at some point in favour of the # Solr 4 spatial sorting capabilities - if search_params['sort'] == 'spatial desc' and \ + if search_params.get('sort') == 'spatial desc' and \ p.toolkit.asbool(config.get('ckanext.spatial.use_postgis_sorting', 'False')): if search_params['q'] or search_params['fq']: raise SearchError('Spatial ranking cannot be mixed with other search parameters') From 28042d2b6f5e875feaf94465963186930e1452bb Mon Sep 17 00:00:00 2001 From: amercader Date: Mon, 29 Jul 2013 17:25:04 +0100 Subject: [PATCH 054/114] [#28] Fix function name --- ckanext/spatial/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ckanext/spatial/plugin.py b/ckanext/spatial/plugin.py index 1d22cc2..9131337 100644 --- a/ckanext/spatial/plugin.py +++ b/ckanext/spatial/plugin.py @@ -209,7 +209,7 @@ class SpatialQuery(p.SingletonPlugin): if self.search_backend == 'solr': search_params = self._params_for_solr_search(bbox, search_params) elif self.search_backend == 'solr-spatial-field': - search_params = self._params_for_solr_spatial_search(bbox, search_params) + search_params = self._params_for_solr_spatial_field_search(bbox, search_params) elif self.search_backend == 'postgis': search_params = self._params_for_postgis_search(bbox, search_params) From 19ea9b1753eabfb1836e1aa5f0dde37922b268ec Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 8 Aug 2013 17:31:21 +0100 Subject: [PATCH 055/114] [#32] Do not set height to avoid scrollbars if container is less than 600px --- ckanext/spatial/public/css/geojson_preview.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ckanext/spatial/public/css/geojson_preview.css b/ckanext/spatial/public/css/geojson_preview.css index 0dd66e5..2e2642f 100644 --- a/ckanext/spatial/public/css/geojson_preview.css +++ b/ckanext/spatial/public/css/geojson_preview.css @@ -1,5 +1,5 @@ html, body { - height: 600px; + max-height: 600px; padding: 0; margin: 0; background: none; From 063a1b853019128de8fda55c7de2fda576ea4c6b Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 8 Aug 2013 17:33:56 +0100 Subject: [PATCH 056/114] [#26] Fix broken markers on debug mode --- ckanext/spatial/public/js/dataset_map.js | 3 +++ ckanext/spatial/public/js/geojson_preview.js | 3 +++ ckanext/spatial/templates/dataviewer/geojson.html | 2 +- .../spatial/templates/spatial/snippets/dataset_map_base.html | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ckanext/spatial/public/js/dataset_map.js b/ckanext/spatial/public/js/dataset_map.js index 1e697ed..8fc2571 100644 --- a/ckanext/spatial/public/js/dataset_map.js +++ b/ckanext/spatial/public/js/dataset_map.js @@ -25,6 +25,9 @@ this.ckan.module('dataset-map', function (jQuery, _) { this.extent = this.el.data('extent'); + // hack to make leaflet use a particular location to look for images + L.Icon.Default.imagePath = this.options.site_url + 'js/vendor/leaflet/images'; + jQuery.proxyAll(this, /_on/); this.el.ready(this._onReady); diff --git a/ckanext/spatial/public/js/geojson_preview.js b/ckanext/spatial/public/js/geojson_preview.js index d656061..3fcfa5e 100644 --- a/ckanext/spatial/public/js/geojson_preview.js +++ b/ckanext/spatial/public/js/geojson_preview.js @@ -20,6 +20,9 @@ ckan.module('geojsonpreview', function (jQuery, _) { self.el.append($("
").attr("id","map")); self.map = L.map('map'); + // hack to make leaflet use a particular location to look for images + L.Icon.Default.imagePath = this.options.site_url + 'js/vendor/leaflet/images'; + var mapUrl = "http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"; var osmAttribution = 'Map data © 2011 OpenStreetMap contributors, Tiles Courtesy of MapQuest '; var bg = new L.TileLayer(mapUrl, {maxZoom: 18, attribution: osmAttribution, subdomains: '1234'}); diff --git a/ckanext/spatial/templates/dataviewer/geojson.html b/ckanext/spatial/templates/dataviewer/geojson.html index 6ee998e..db1c6bd 100644 --- a/ckanext/spatial/templates/dataviewer/geojson.html +++ b/ckanext/spatial/templates/dataviewer/geojson.html @@ -5,7 +5,7 @@ {% resource g.main_css[6:] %} {% endblock %} -
+

{{ _('Loading...') }}
diff --git a/ckanext/spatial/templates/spatial/snippets/dataset_map_base.html b/ckanext/spatial/templates/spatial/snippets/dataset_map_base.html index 0dcf533..0bb9df4 100644 --- a/ckanext/spatial/templates/spatial/snippets/dataset_map_base.html +++ b/ckanext/spatial/templates/spatial/snippets/dataset_map_base.html @@ -9,7 +9,7 @@ extent {% snippet "spatial/snippets/dataset_map_base.html", extent=extent %} #} -
+
Map data CC-BY-SA by OpenStreetMap
From d6cfb46c6c1b6fe08e5542b82609f7703f56296f Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 8 Aug 2013 17:36:14 +0100 Subject: [PATCH 057/114] [#27] Remove spatial_query_widget mention from README --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 294cd13..9b3ec54 100644 --- a/README.rst +++ b/README.rst @@ -16,7 +16,7 @@ The following plugins are currently available: These snippets (to be used with CKAN>=2.0): * `Dataset Extent Map`_ - Map widget showing a dataset extent. -* `Spatial Search Widget`_ - Map widget integrated on the search form (``spatial_query_widget``). +* `Spatial Search Widget`_ - Map widget integrated on the search form. These libraries: From 4636379482a2665865716b4d99d271103de86f27 Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 8 Aug 2013 18:18:51 +0100 Subject: [PATCH 058/114] [#32] Add note about resource_proxy --- README.rst | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 9b3ec54..450cf50 100644 --- a/README.rst +++ b/README.rst @@ -290,8 +290,9 @@ WMS Preview ----------- To enable the WMS previewer you need to add the ``wms_preview`` plugin to your -ini file (See `Configuration`_). This plugin also requires the `resource_proxy `_ -plugin (part of CKAN core). +ini file (See `Configuration`_). This plugin also requires the `resource_proxy`_ +plugin (Make sure you load the ``resource_proxy`` plugin before any other +from the spatial extension). Please note that this is an experimental plugin and may be unstable. @@ -304,13 +305,17 @@ GeoJSON Preview --------------- To enable the GeoJSON previewer you need to add the ``geojson_preview`` plugin to your -ini file (See `Configuration`_). This plugin also requires the ``resource_proxy`` -plugin. +ini file (See `Configuration`_). This plugin also requires the `resource_proxy`_ +plugin (Make sure you load the ``resource_proxy`` plugin before any other +from the spatial extension). + When the plugin is enabled, if datasets contain a resource that has 'gjson' or 'geojson' format, the resource page will load simple map viewer that will show the features on a map. +.. _resource_proxy: http://docs.ckan.org/en/latest/data-viewer.html#viewing-remote-resources-the-resource-proxy + CSW Server ---------- From cf202ba33d8aa2d7084d9dcda1c4ac3e7e6195df Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 13 Aug 2013 11:53:22 +0100 Subject: [PATCH 059/114] Modify OWSLib requirement to prevent conflicts We will target a specific changeset of OWSLib for the time being, just until there is a proper release which includes geopython/OWSLib@4b0a62cd. Basically OWSLib required python-dateutil==2.1, which is intended for Python 3 and conflicted with the version used by CKAN core. --- pip-requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pip-requirements.txt b/pip-requirements.txt index d4fc919..7a78fd2 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -1,6 +1,8 @@ GeoAlchemy>=0.6 Shapely>=1.2.13 -OWSLib==0.7.2 +# Temporal requirement until there is an OWSLib release +# that requires python-dateutil<2.0 +-e git+https://github.com/geopython/OWSLib.git@4b0a62cd37a5a03aafc5c0cd9606e0658d5ac664#egg=owslib lxml<=2.2.99 argparse pyparsing==1.5.6 From c6e29ee25f7111903ee28501cd53c1e8d4a4e34a Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 14 Aug 2013 12:23:00 +0100 Subject: [PATCH 060/114] [#35] Ignore auth when using site_user --- ckanext/spatial/harvesters/base.py | 8 ++++++-- ckanext/spatial/tests/lib/test_spatial.py | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ckanext/spatial/harvesters/base.py b/ckanext/spatial/harvesters/base.py index c7a4625..98649bf 100644 --- a/ckanext/spatial/harvesters/base.py +++ b/ckanext/spatial/harvesters/base.py @@ -505,6 +505,9 @@ class SpatialHarvester(HarvesterBase): 'extras_as_string': True, 'api_version': '2', 'return_id_only': True} + if context['user'] == self._site_user['name']: + context['ignore_auth'] = True + # The default package schema does not like Upper case tags tag_schema = logic.schema.default_tags_schema() @@ -646,12 +649,13 @@ class SpatialHarvester(HarvesterBase): if self._user_name: return self._user_name + self._site_user = p.toolkit.get_action('get_site_user')({'model': model, 'ignore_auth': True}, {}) + config_user_name = config.get('ckanext.spatial.harvest.user_name') if config_user_name: self._user_name = config_user_name else: - user = p.toolkit.get_action('get_site_user')({'model': model, 'ignore_auth': True}, {}) - self._user_name = user['name'] + self._user_name = self._site_user['name'] return self._user_name diff --git a/ckanext/spatial/tests/lib/test_spatial.py b/ckanext/spatial/tests/lib/test_spatial.py index 2527217..21971c6 100644 --- a/ckanext/spatial/tests/lib/test_spatial.py +++ b/ckanext/spatial/tests/lib/test_spatial.py @@ -60,7 +60,9 @@ class SpatialQueryTestBase(SpatialTestBase): 'session': model.Session, 'user': user['name'], 'extras_as_string': True, - 'api_version': 2} + 'api_version': 2, + 'ignore_auth': True, + } package_dict = package_create(context, package_dict) return context.get('id') From b466b1157ebd3d7f81822ac0f73e79f289425165 Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 14 Aug 2013 13:14:55 +0100 Subject: [PATCH 061/114] [#34] Update lxml requirement Latest OWSLib introduces changes that require lxml>=2.3. --- pip-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pip-requirements.txt b/pip-requirements.txt index 7a78fd2..34c4b4e 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -3,6 +3,6 @@ Shapely>=1.2.13 # Temporal requirement until there is an OWSLib release # that requires python-dateutil<2.0 -e git+https://github.com/geopython/OWSLib.git@4b0a62cd37a5a03aafc5c0cd9606e0658d5ac664#egg=owslib -lxml<=2.2.99 +lxml>=2.3 argparse pyparsing==1.5.6 From fa7ede5e0306cbdf1cd713eb6a1040c38671a362 Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 21 Aug 2013 17:51:20 +0100 Subject: [PATCH 062/114] [#24] Minor tweaks in README --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 9771678..4774126 100644 --- a/README.rst +++ b/README.rst @@ -425,7 +425,7 @@ Setup This will run pycsw at http://localhost:8000. Visiting the following URL should return you the Capabilities file: - http://localhost:8000?service=CSW&version=2.0.2&request=GetCapabilities + http://localhost:8000/?service=CSW&version=2.0.2&request=GetCapabilities 5. Load the CKAN datasets into pycsw. Again we will use the ``ckan-pycsw`` command for this:: From eb1090a9c486300d20a4c5e241493a1c69159d3b Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 21 Aug 2013 17:51:38 +0100 Subject: [PATCH 063/114] [#24] Let pycsw define and create the table --- bin/ckan_pycsw.py | 102 +++++----------------------------------------- 1 file changed, 10 insertions(+), 92 deletions(-) diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py index cc8c22e..642dbfa 100644 --- a/bin/ckan_pycsw.py +++ b/bin/ckan_pycsw.py @@ -8,6 +8,7 @@ from lxml import etree from pycsw import metadata, repository, util import pycsw.config +import pycsw.admin logging.basicConfig(format='%(message)s', level=logging.INFO) @@ -15,104 +16,21 @@ log = logging.getLogger(__name__) def setup_db(pycsw_config): """Setup database tables and indexes""" - from sqlalchemy import Column, create_engine, Integer, MetaData, \ - Table, Text + + from sqlalchemy import Column, Text database = pycsw_config.get('repository', 'database') table_name = pycsw_config.get('repository', 'table', 'records') - log.debug('Creating engine') - engine = create_engine(database) - - mdata = MetaData(engine) - - log.info('Creating table %s', table_name) - records = Table( - table_name, mdata, - # core; nothing happens without these - Column('identifier', Text, primary_key=True), - Column('typename', Text, - default='csw:Record', nullable=False, index=True), - Column('schema', Text, - default='http://www.opengis.net/cat/csw/2.0.2', nullable=False, - index=True), - Column('mdsource', Text, default='local', nullable=False, - index=True), - Column('insert_date', Text, nullable=False, index=True), - Column('xml', Text, nullable=False), - Column('anytext', Text, nullable=False), - Column('language', Text, index=True), - - # identification - Column('type', Text, index=True), - Column('title', Text, index=True), - Column('title_alternate', Text, index=True), - Column('abstract', Text), - Column('keywords', Text), - Column('keywordstype', Text, index=True), - Column('parentidentifier', Text, index=True), - Column('relation', Text, index=True), - Column('time_begin', Text, index=True), - Column('time_end', Text, index=True), - Column('topicategory', Text, index=True), - Column('resourcelanguage', Text, index=True), - - # attribution - Column('creator', Text, index=True), - Column('publisher', Text, index=True), - Column('contributor', Text, index=True), - Column('organization', Text, index=True), - - # security - Column('securityconstraints', Text), - Column('accessconstraints', Text), - Column('otherconstraints', Text), - - # date - Column('date', Text, index=True), - Column('date_revision', Text, index=True), - Column('date_creation', Text, index=True), - Column('date_publication', Text, index=True), - Column('date_modified', Text, index=True), - - Column('format', Text, index=True), - Column('source', Text, index=True), - - # geospatial - Column('crs', Text, index=True), - Column('geodescode', Text, index=True), - Column('denominator', Integer, index=True), - Column('distancevalue', Integer, index=True), - Column('distanceuom', Text, index=True), - Column('wkt_geometry', Text), - - # service - Column('servicetype', Text, index=True), - Column('servicetypeversion', Text, index=True), - Column('operation', Text, index=True), - Column('couplingtype', Text, index=True), - Column('operateson', Text, index=True), - Column('operatesonidentifier', Text, index=True), - Column('operatesoname', Text, index=True), - - # additional - Column('degree', Text, index=True), - Column('classification', Text, index=True), - Column('conditionapplyingtoaccessanduse', Text, index=True), - Column('lineage', Text, index=True), - Column('responsiblepartyrole', Text, index=True), - Column('specificationtitle', Text, index=True), - Column('specificationdate', Text, index=True), - Column('specificationdatetype', Text, index=True), - - # distribution - # links: format "name,description,protocol,url[^,,,[^,,,]]" - Column('links', Text, index=True), - + ckan_columns = [ Column('ckan_id', Text, index=True), Column('ckan_modified', Text), - ) - records.create() + ] + + pycsw.admin.setup_db(database, + table_name, '', + create_plpythonu_functions=False, + extra_columns=ckan_columns) def load(pycsw_config, ckan_url): From a9414e755dbde75f7f02a9643c92d9771c0ad2bf Mon Sep 17 00:00:00 2001 From: fxia Date: Thu, 29 Aug 2013 00:05:24 -0400 Subject: [PATCH 064/114] add progress into the iso values --- ckanext/spatial/harvesters/base.py | 1 + ckanext/spatial/harvesters/gemini.py | 1 + ckanext/spatial/model/harvested_metadata.py | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/ckanext/spatial/harvesters/base.py b/ckanext/spatial/harvesters/base.py index 98649bf..b01d022 100644 --- a/ckanext/spatial/harvesters/base.py +++ b/ckanext/spatial/harvesters/base.py @@ -234,6 +234,7 @@ class SpatialHarvester(HarvesterBase): 'coupled-resource', 'contact-email', 'frequency-of-update', + 'progress', 'spatial-data-service-type', ]: extras[name] = iso_values[name] diff --git a/ckanext/spatial/harvesters/gemini.py b/ckanext/spatial/harvesters/gemini.py index 76120a8..e9bcd9e 100644 --- a/ckanext/spatial/harvesters/gemini.py +++ b/ckanext/spatial/harvesters/gemini.py @@ -200,6 +200,7 @@ class GeminiHarvester(SpatialHarvester): 'coupled-resource', 'contact-email', 'frequency-of-update', + 'progress', 'spatial-data-service-type', ]: extras[name] = gemini_values[name] diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index 86700c5..cf02467 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -481,6 +481,16 @@ class ISODocument(MappedXmlDocument): ], multiplicity="0..1", ), + ISOElement( + name="progress", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:status/gmd:MD_ProgressCode/@codeListValue", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:status/gmd:MD_ProgressCode/@codeListValue", + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:status/gmd:MD_ProgressCode/text()", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:status/gmd:MD_ProgressCode/text()", + ], + multiplicity="0..1", + ), ISOElement( name="keyword-inspire-theme", search_paths=[ From 44fd9816e1a117ec6be0d3f4dbc67e0d29016a94 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 30 Aug 2013 12:22:14 +0100 Subject: [PATCH 065/114] [#24] Mention required pycsw version in readme --- README.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 4774126..57bf470 100644 --- a/README.rst +++ b/README.rst @@ -368,6 +368,9 @@ Setup 1. Install pycsw. There are several options for this, depending on your server setup, check the `pycsw documentation `_. + .. note:: CKAN integration requires at least pycsw version 1.6.1. Make sure + to install at least this version. + The following instructions assume that you have installed CKAN via a `package install `_ and should be run as root, but the steps are the same if you are setting @@ -380,7 +383,9 @@ Setup git clone https://github.com/geopython/pycsw.git cd pycsw - pip install -e . && pip install -r requirements.txt + # Remember to use at least pycsw 1.6.1 + git checkout 1.6.1 + pip install -e . python setup.py build python setup.py install @@ -503,11 +508,11 @@ ckanext-csw provides the CSW service at ``/csw``. For example you can ask the capabilities of the CSW server installed into CKAN running on 127.0.0.1:5000 like this:: - curl 'http://127.0.0.1:5000/csw?request=GetCapabilities&service=CSW' + curl 'http://127.0.0.1:5000/csw?request=GetCapabilities&service=CSW&version=2.0.2' And get a list of the records like this:: - curl 'http://127.0.0.1:5000/csw?request=GetRecords&service=CSW&resultType=results&elementSetName=full' + curl 'http://127.0.0.1:5000/csw?request=GetRecords&service=CSW&resultType=results&elementSetName=full&version=2.0.2' The standard CSW response is in XML format. From 0793cd130f6c1239d419d4399ba448c76b4a09b0 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 30 Aug 2013 14:35:44 +0100 Subject: [PATCH 066/114] [#24] Readme: install Postgis and pycsw field length errors --- README.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.rst b/README.rst index 57bf470..a97484c 100644 --- a/README.rst +++ b/README.rst @@ -395,6 +395,10 @@ Setup sudo -u postgres createdb -O ckan_default pycsw -E utf-8 + It is strongly recommended that you install PostGIS in the pycsw databaset, + so its spatial functions are used. See the `Setting up PostGIS`_ section + for details. + 3. Configure pycsw. An example configuration file is included on the source:: cp default-sample.cfg default.cfg @@ -438,6 +442,13 @@ Setup cd /usr/lib/ckan/default/src/ckanext-spatial paster ckan-pycsw load -p /etc/ckan/default/pycsw.cfg + .. note:: If you get errors similar to this one, this is caused by + limitations on the pycsw model definition. This should be fixed in + future versions of pycsw:: + + ERROR: not inserted f8d48eaf-780b-40b8-a502-7a903fde5b1c Error:ERROR: value too long for type character varying(256) + + When the loading is finished, check that results are returned when visiting this link: From b371aee381b3ba646c5e654663d6b8208dff8607 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 30 Aug 2013 16:26:02 +0100 Subject: [PATCH 067/114] [#36] Fix spatial query widget for CKAN 2.1 --- ckanext/spatial/public/js/spatial_query.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ckanext/spatial/public/js/spatial_query.js b/ckanext/spatial/public/js/spatial_query.js index c6162ec..d164153 100644 --- a/ckanext/spatial/public/js/spatial_query.js +++ b/ckanext/spatial/public/js/spatial_query.js @@ -71,6 +71,11 @@ this.ckan.module('spatial-query', function ($, _) { var is_exanded = false; var should_zoom = true; var form = $("#dataset-search"); + // CKAN 2.1 + if (!form.length) { + form = $(".search-form"); + } + var buttons; // Add necessary fields to the search form if not already created From 028d26e6e0b5628f6060cc78858627023bc26f1d Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 30 Aug 2013 17:10:11 +0100 Subject: [PATCH 068/114] [#37] Common function for initializing maps This avoids duplication, mkaes all map consistent and makes easier future support for other base maps. --- ckanext/spatial/public/js/common_map.js | 44 ++++++++++++++++++++ ckanext/spatial/public/js/dataset_map.js | 9 +--- ckanext/spatial/public/js/geojson_preview.js | 6 +-- ckanext/spatial/public/js/spatial_query.js | 8 +--- ckanext/spatial/public/resource.config | 5 ++- 5 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 ckanext/spatial/public/js/common_map.js diff --git a/ckanext/spatial/public/js/common_map.js b/ckanext/spatial/public/js/common_map.js new file mode 100644 index 0000000..8b326d1 --- /dev/null +++ b/ckanext/spatial/public/js/common_map.js @@ -0,0 +1,44 @@ +(function (ckan, jQuery) { + + /* Returns a Leaflet map to use on the different spatial widgets + * + * All Leaflet based maps should use this constructor to provide consistent + * look and feel and avoid duplication. + * + * container - HTML element or id of the map container + * mapOptions - (Optional) Options to pass to the map constructor + * baseLayerOptions - (Optional) Options to pass to the base layer constructor + * + * Examples + * + * // Will return a map with attribution control + * var map = ckan.commonLeafletMap('map'); + * + * // For smaller maps where the attribution is shown outside the map, pass + * // the following option: + * var map = ckan.commonLeafletMap('map', {attributionControl: false}); + * + * Returns a Leaflet map object. + */ + ckan.commonLeafletMap = function (container, mapOptions, baseLayerOptions) { + + var mapOptions = mapOptions || {}; + var baseLayerOptions = jQuery.extend(baseLayerOptions, { + maxZoom: 18, + attribution: 'Map data © OpenStreetMap contributors' + }); + + map = new L.Map(container, mapOptions); + + // MapQuest OpenStreetMap base map + baseLayerUrl = '//otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png'; + baseLayerOptions.subdomains = '1234'; + baseLayerOptions.attribution += ', Tiles Courtesy of MapQuest '; + var baseLayer = new L.TileLayer(baseLayerUrl, baseLayerOptions); + map.addLayer(baseLayer); + + return map; + + } + +})(this.ckan, this.jQuery); diff --git a/ckanext/spatial/public/js/dataset_map.js b/ckanext/spatial/public/js/dataset_map.js index 8fc2571..4f28d06 100644 --- a/ckanext/spatial/public/js/dataset_map.js +++ b/ckanext/spatial/public/js/dataset_map.js @@ -41,14 +41,7 @@ this.ckan.module('dataset-map', function (jQuery, _) { return false; } - map = new L.Map('dataset-map-container', {attributionControl: false }); - - // MapQuest OpenStreetMap base map - var backgroundLayer = new L.TileLayer( - 'http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', - {maxZoom: 18, subdomains: '1234'} - ); - map.addLayer(backgroundLayer); + map = ckan.commonLeafletMap('dataset-map-container', {attributionControl: false}); var ckanIcon = L.Icon.extend({options: this.options.styles.point}); diff --git a/ckanext/spatial/public/js/geojson_preview.js b/ckanext/spatial/public/js/geojson_preview.js index 3fcfa5e..33b2ddd 100644 --- a/ckanext/spatial/public/js/geojson_preview.js +++ b/ckanext/spatial/public/js/geojson_preview.js @@ -18,15 +18,11 @@ ckan.module('geojsonpreview', function (jQuery, _) { self.el.empty(); self.el.append($("
").attr("id","map")); - self.map = L.map('map'); + self.map = ckan.commonLeafletMap('map'); // hack to make leaflet use a particular location to look for images L.Icon.Default.imagePath = this.options.site_url + 'js/vendor/leaflet/images'; - var mapUrl = "http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"; - var osmAttribution = 'Map data © 2011 OpenStreetMap contributors, Tiles Courtesy of MapQuest '; - var bg = new L.TileLayer(mapUrl, {maxZoom: 18, attribution: osmAttribution, subdomains: '1234'}); - self.map.addLayer(bg); // use CORS, if supported by browser and server if (jQuery.support.cors && preload_resource['original_url'] !== undefined) { diff --git a/ckanext/spatial/public/js/spatial_query.js b/ckanext/spatial/public/js/spatial_query.js index d164153..dbdd0d5 100644 --- a/ckanext/spatial/public/js/spatial_query.js +++ b/ckanext/spatial/public/js/spatial_query.js @@ -86,13 +86,7 @@ this.ckan.module('spatial-query', function ($, _) { }); // OK map time - map = new L.Map('dataset-map-container', {attributionControl: false}); - - // MapQuest OpenStreetMap base map - map.addLayer(new L.TileLayer( - 'http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', - {maxZoom: 18, subdomains: '1234'} - )); + map = ckan.commonLeafletMap('dataset-map-container', {attributionControl: false}); // Initialize the draw control map.addControl(new L.Control.Draw({ diff --git a/ckanext/spatial/public/resource.config b/ckanext/spatial/public/resource.config index 597d0af..d49da11 100644 --- a/ckanext/spatial/public/resource.config +++ b/ckanext/spatial/public/resource.config @@ -13,6 +13,7 @@ main = base/main dataset_map = js/vendor/leaflet/leaflet.js + js/common_map.js js/dataset_map.js js/vendor/leaflet/leaflet.css @@ -22,6 +23,7 @@ spatial_query = js/vendor/leaflet/leaflet.js js/vendor/leaflet.draw/leaflet.draw.js + js/common_map.js js/spatial_query.js js/vendor/leaflet/leaflet.css @@ -42,5 +44,6 @@ geojson = js/vendor/leaflet/leaflet.js js/vendor/leaflet/leaflet.css + js/common_map.js js/geojson_preview.js - css/geojson_preview.css \ No newline at end of file + css/geojson_preview.css From 435f9cdd4a163e760ef5219601db11603b010b2f Mon Sep 17 00:00:00 2001 From: amercader Date: Sun, 8 Sep 2013 19:42:39 +0100 Subject: [PATCH 069/114] [#39] New docs Completely revised and restructured docs to be built with Sphinx. Structured in logic areas, with a big cleanup and nice formatting. Revised install instructions. Added the okfn-sphinx-theme submodule to have a consistent look and feel with the core CKAN docs, although core docs are using an older revision. --- .gitignore | 1 + .gitmodules | 3 + doc/_static/ckanlogo.png | Bin 0 -> 1303 bytes doc/_static/dataset-extent-map.png | Bin 0 -> 97850 bytes doc/_static/preview-geojson.png | Bin 0 -> 237831 bytes doc/_static/preview-wms.png | Bin 0 -> 91970 bytes doc/_static/spatial-search-widget.png | Bin 0 -> 80182 bytes doc/_templates/footer.html | 29 +++ doc/_themes/sphinx-theme-okfn | 1 + doc/conf.py | 18 +- doc/csw.rst | 260 ++++++++++++++++++++ doc/dataset-map.rst | 9 - doc/harvesters.rst | 142 +++++++++++ doc/index.ckan | 19 -- doc/index.rst | 53 ++-- doc/install.rst | 243 +++++++++++++++++++ doc/postgis-manual.rst | 43 ++++ doc/previews.rst | 68 ++++++ doc/spatial-search.rst | 332 ++++++++++++++++++++++---- 19 files changed, 1106 insertions(+), 115 deletions(-) create mode 100644 .gitmodules create mode 100644 doc/_static/ckanlogo.png create mode 100644 doc/_static/dataset-extent-map.png create mode 100644 doc/_static/preview-geojson.png create mode 100644 doc/_static/preview-wms.png create mode 100644 doc/_static/spatial-search-widget.png create mode 100644 doc/_templates/footer.html create mode 160000 doc/_themes/sphinx-theme-okfn create mode 100644 doc/csw.rst delete mode 100644 doc/dataset-map.rst create mode 100644 doc/harvesters.rst delete mode 100644 doc/index.ckan create mode 100644 doc/install.rst create mode 100644 doc/postgis-manual.rst create mode 100644 doc/previews.rst diff --git a/.gitignore b/.gitignore index 39f7065..3304cfa 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ syntax: glob *.swp *~ dist +build diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..17ee088 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "doc/_themes/sphinx-theme-okfn"] + path = doc/_themes/sphinx-theme-okfn + url = git@github.com:okfn/sphinx-theme-okfn.git diff --git a/doc/_static/ckanlogo.png b/doc/_static/ckanlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..a234cc085bb9e9e0fe45df4d8851b43f2e8ed6c1 GIT binary patch literal 1303 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 R@B#(-NQuddR*4t{{6Bwhu&V$7 literal 0 HcmV?d00001 diff --git a/doc/_static/preview-geojson.png b/doc/_static/preview-geojson.png new file mode 100644 index 0000000000000000000000000000000000000000..c2ea881c4574c7df6e6c48faa5c9bfa3d8f8b854 GIT binary patch literal 237831 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

IsmvS(^7 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

m!npEqDcx& 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 NurRZQ*TG!l{tI{C2pRwY literal 0 HcmV?d00001 diff --git a/doc/_static/preview-wms.png b/doc/_static/preview-wms.png new file mode 100644 index 0000000000000000000000000000000000000000..1d947d3caff685d313eec901ff993428e3b40779 GIT binary patch literal 91970 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

+ + + +

+Source +— +Issues +— +Mailing List +— +Twitter @CKANProject +

+ +

+Related Projects: +The DataHub +— +DataCatalogs.org +— +OpenSpending.org +— +Open Data Handbook +

+ diff --git a/doc/_themes/sphinx-theme-okfn b/doc/_themes/sphinx-theme-okfn new file mode 160000 index 0000000..59688a6 --- /dev/null +++ b/doc/_themes/sphinx-theme-okfn @@ -0,0 +1 @@ +Subproject commit 59688a6679f3373a57e8d4e60e43f1b249878eb3 diff --git a/doc/conf.py b/doc/conf.py index ea722e3..93a6937 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -25,7 +25,7 @@ import sys, os # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.pngmath'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.intersphinx'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -89,12 +89,14 @@ pygments_style = 'sphinx' # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False +exclude_trees = ['.build'] + # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +#html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -103,6 +105,18 @@ html_theme = 'default' # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] +sys.path.append(os.path.abspath('_themes')) +html_theme_path = ['_themes'] +html_theme = 'sphinx-theme-okfn' +html_theme_options = { + 'logo_icon': 'ckanlogo.png', + 'show_version': False, + 'show_okfn_logo': False, + } +html_sidebars = { + '**': ['globaltoc.html'] +} + # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". diff --git a/doc/csw.rst b/doc/csw.rst new file mode 100644 index 0000000..0bbd792 --- /dev/null +++ b/doc/csw.rst @@ -0,0 +1,260 @@ +=========== +CSW support +=========== + +The extension provides the support for the CSW_ standard, a specification from +the Open Geospatial Consortium for exposing geospatial catalogues over the web. + +This support consists of: + +* Ability to import records from CSW servers with the CSW harvester. See + :doc:`harvesters` for more details. + +* Integration with pycsw_ to provide a fully compliat CSW interface for + harvested records. This integration is described on the following sections. + + +ckan-pycsw +---------- + +The spatial extension offers the ``ckan-pycsw`` command, which allows to expose +the spatial datasets harvested from other sources in a CSW interface. This is +powered by pycsw_, which fully implements the OGC CSW specification. + +How it works +++++++++++++ + + +The current implementation is based on CKAN and pycsw being loosely integrated +via the CKAN API. pycsw will be generally installed in the same server as CKAN +(although it can also be run on a separate one), and the synchronization +command will be run regularly to keep the records on the pycsw repository up to +date. This is done using the CKAN API to get all the datasets identifiers (more +precisely the ones from datasets that have been harvested) and then deciding +which ones need to be created, updated or deleted on the pycsw repository. For +those that need to be created or updated, the original harvested spatial +document (ie ISO 19139) is requested from CKAN, and it is then imported using +pycsw internal functions:: + + Harvested + datasets + + + | + v + +--------+ +---------+ + | | CKAN API | | + | CKAN | +------------> | pycsw | +------> CSW + | | | | + +--------+ +---------+ + + +Remember, only datasets that were harvested with the :doc:`harvesters` +can currently be exposed via pycsw. + +All necessary tasks are done with the ``ckan-pycsw`` command. To get more +details of its usage, run the following:: + + cd /usr/lib/ckan/default/src/ckanext-spatial + paster ckan-pycsw --help + + +Setup ++++++ + +1. Install pycsw. There are several options for this, depending on your + server setup, check the `pycsw documentation`_. + + .. note:: CKAN integration requires at least pycsw version 1.6.1. Make sure + to install at least this version. + + The following instructions assume that you have installed CKAN via a + `package install`_ and should be run as root, but the steps are the same if + you are setting it up in another location:: + + cd /usr/lib/ckan/default/src + source ../bin/activate + + # From now on the virtualenv should be activated + + git clone https://github.com/geopython/pycsw.git + cd pycsw + # Remember to use at least pycsw 1.6.1 + git checkout 1.6.1 + pip install -e . + python setup.py build + python setup.py install + +2. Create a database for pycsw. In theory you can use the same database that + CKAN is using, but if you want to keep them separated, use the following + command to create a new one (we'll use the same default user though):: + + sudo -u postgres createdb -O ckan_default pycsw -E utf-8 + + It is strongly recommended that you install PostGIS in the pycsw databaset, + so its spatial functions are used. See the :ref:`install_postgis` + section for details. + +3. Configure pycsw. An example configuration file is included on the source:: + + cp default-sample.cfg default.cfg + + To keep things tidy we will create a symlink to this file on the CKAN + configuration directory:: + + ln -s /usr/lib/ckan/default/src/pycsw/default.cfg /etc/ckan/default/pycsw.cfg + + Open the file with your favourite editor. The main settings you should tweak + are ``server.home`` and ``repository.database``:: + + [server] + home=/usr/lib/ckan/default/src/pycsw + ... + [repository] + database=postgresql://ckan_default:pass@localhost/pycsw + + The rest of the options are described `here `_. + +4. Setup the pycsw table. This is done with the ``ckan-pycsw`` paster command + (Remember to have the virtualenv activated when running it):: + + cd /usr/lib/ckan/default/src/ckanext-spatial + paster ckan-pycsw setup -p /etc/ckan/default/pycsw.cfg + + At this point you should be ready to run pycsw with the wsgi script that it + includes:: + + cd /usr/lib/ckan/default/src/pycsw + python csw.wsgi + + This will run pycsw at http://localhost:8000. Visiting the following URL + should return you the Capabilities file: + + http://localhost:8000/?service=CSW&version=2.0.2&request=GetCapabilities + +5. Load the CKAN datasets into pycsw. Again, we will use the ``ckan-pycsw`` + command for this:: + + cd /usr/lib/ckan/default/src/ckanext-spatial + paster ckan-pycsw load -p /etc/ckan/default/pycsw.cfg + + .. note:: If you get errors similar to this one, this is caused by + limitations on the pycsw model definition. This should be fixed in + future versions of pycsw:: + + ERROR: not inserted f8d48eaf-780b-40b8-a502-7a903fde5b1c Error:ERROR: value too long for type character varying(256) + + + When the loading is finished, check that results are returned when visiting + this link: + + http://localhost:8000/?request=GetRecords&service=CSW&version=2.0.2&resultType=results&outputSchema=http://www.isotc211.org/2005/gmd&typeNames=csw:Record&elementSetName=summary + + The ``numberOfRecordsMatched`` should match the number of harvested datasets + in CKAN (minus import errors). If you run the command again new or udpated + datasets will be synchronized and deleted datasets from CKAN will be removed + from pycsw as well. + +Running it on production site ++++++++++++++++++++++++++++++ + +On a production site you probably want to run the load command regularly to +keep CKAN and pycsw in sync, and serve pycsw with Apache + mod_wsgi like CKAN. + +* To run the load command regularly you can set up a cron job. Type ``crontab -e`` + and copy the following lines:: + + # m h dom mon dow command + 0 * * * * /usr/lib/ckan/default/bin/paster --plugin=ckanext-spatial ckan-pycsw load -p /etc/ckan/default/pycsw.cfg + + This particular example will run the load command every hour. You can of + course modify this periodicity, for instance reducing it for huge instances. + This `Wikipedia page `_ + has a good overview of the crontab syntax. + +* To run pycsw under Apache check the pycsw `installation documentation `_ + or follow this quick steps (they assume the paths used on the previous steps): + + - Edit ``/etc/apache2/sites-available/ckan_default`` and add the following + line just before the existing ``WSGIScriptAlias`` directive:: + + WSGIScriptAlias /csw /usr/lib/ckan/default/src/pycsw/csw.wsgi + + - Edit the ``/usr/lib/ckan/default/src/pycsw/csw.wsgi`` file and add these two + lines just after the imports on the top of the file:: + + activate_this = os.path.join('/usr/lib/ckan/default/bin/activate_this.py') + execfile(activate_this, {"__file__":activate_this}) + + We need these to activate the virtualenv where we installed pycsw into. + + - Restart Apache:: + + service apache2 restart + + pycsw should be now accessible at http://localhost/csw + + +Legacy plugins and libraries +---------------------------- + + +Old CSW Server +++++++++++++++ + +.. warning:: **Deprecated:** The old csw plugin has been deprecated, please see `ckan-pycsw`_ + for details on how to integrate with pycsw. + +To activate it, add the ``csw_server`` plugin to your ini file. + +Only harvested datasets are served by this CSW Server. This is because +the harvested document is the one that is served, not something derived +from the CKAN Dataset object. Datasets that are created in CKAN by methods +other than harvesting are not served. + +The currently supported methods with this CSW Server are: + * GetCapabilities + * GetRecords + * GetRecordById + +For example you can ask the capabilities of the CSW server installed into CKAN +running on 127.0.0.1:5000 like this:: + + curl 'http://127.0.0.1:5000/csw?request=GetCapabilities&service=CSW&version=2.0.2' + +And get a list of the records like this:: + + curl 'http://127.0.0.1:5000/csw?request=GetRecords&service=CSW&resultType=results&elementSetName=full&version=2.0.2' + +The standard CSW response is in XML format. + +cswinfo ++++++++ + +The command-line tool ``cswinfo`` allows to make queries on CSW servers and +returns the info in nicely formatted JSON. This may be more convenient to type +than using, for example, curl. + +Currently available queries are: + * getcapabilities + * getidentifiers + * getrecords + * getrecordbyid + +For details, type:: + + cswinfo csw -h + +There are options for querying by only certain types, keywords and typenames +as well as configuring the ElementSetName. + +The equivalent example to the one above for asking the cabailities is:: + + $ cswinfo csw getcapabilities http://127.0.0.1:5000/csw + +OWSLib is the library used to actually perform the queries. + +.. _pycsw: http://pycsw.org +.. _pycsw documentation: http://pycsw.org/docs/installation.html +.. _package install: http://docs.ckan.org/en/latest/install-from-package.html +.. _CSW: http://www.opengeospatial.org/standards/cat + diff --git a/doc/dataset-map.rst b/doc/dataset-map.rst deleted file mode 100644 index 92dd43e..0000000 --- a/doc/dataset-map.rst +++ /dev/null @@ -1,9 +0,0 @@ -Dataset Extent Map ------------------- - -To enable the dataset map you need to add the `dataset_extent_map` plugin to your -ini file (See `Configuration`_). You need to load the `spatial_metadata` plugin also. - -When the plugin is enabled, if datasets contain a 'spatial' extra like the one -described in the previous section, a map will be shown on the dataset details page. - diff --git a/doc/harvesters.rst b/doc/harvesters.rst new file mode 100644 index 0000000..69cd9b4 --- /dev/null +++ b/doc/harvesters.rst @@ -0,0 +1,142 @@ +================== +Spatial Harvesters +================== + +Overview and Configuration +-------------------------- + +The spatial extension provides some harvesters for importing ISO19139-based +metadata into CKAN, as well as providing a base class for writing new ones. +The harvesters use the interface provided by ckanext-harvest_, so you will need +to install and set it up first. + +Once ckanext-harvest is installed, you can add the following plugins to your +ini file to enable the different harvesters (If you are upgrading from a +previous version to CKAN 2.0 see legacy_harvesters_): + +* ``csw_harvester`` - CSW server +* ``waf_harvester`` - WAF (Web Accessible Folder): An online accessible index + page with links to metadata documents +* ``doc_harvester`` - A single online accessible metadata document. + +Have a look at the `ckanext-harvest documentation`_ if you want to have an +overview of how the CKAN harvesters work, but basically there are three +separate stages: + +* gather_stage - Aggregates all the remote identifiers for a particular source + (eg identifiers for a CSW server, files for a WAF). +* fetch_stage - Fetches all the remote documents and stores them on the + database. +* import_stage - Performs all the processing for transforming the remote + content into a CKAN dataset: validates the document, parses it, converts it + to a CKAN dataset dict and saves it in the database. + +The extension provides different XSD and schematron based validators. You can +specify which validators to use for the remote documents with the following +configuration option:: + + ckan.spatial.validator.profiles = iso19193eden + +By default, the import stage will stop if the validation of the harvested +document fails. This can be modified setting the +``ckanext.spatial.harvest.continue_on_validation_errors`` to True. The setting +can also be applied at the source level setting to True the +``continue_on_validation_errors`` key on the source configuration object. + +By default the harvesting actions (eg creating or updating datasets) will be +performed by the internal site admin user. This is the recommended setting, +but if necessary, it can be overridden with the +``ckanext.spatial.harvest.user_name`` config option, eg to support the old +hardcoded 'harvest' user:: + + ckanext.spatial.harvest.user_name = harvest + +Customizing the harvesters +-------------------------- + +The default harvesters provided in this extension can be overriden from +extensions to customize to your needs. You can either extend ``CswHarvester``, +``WAFfHarverster`` or the main ``SpatialHarvester`` class. There are some +extension points that can be safely overriden from your extension. Probably the +most useful is ``get_package_dict``, which allows to tweak the dataset fields +before creating or updating them. ``transform_to_iso`` allows to hook into +transformation mechanisms to transform other formats into ISO1939, the only one +directly supported byt he spatial harvesters. Finally, the whole +``import_stage`` can be overriden if the default logic does not suit your +needs. + +Check the source code of ``ckanext/spatial/harvesters/base.py`` for more +details on these functions. + +The `ckanext-geodatagov`_ extension contains live examples on how to extend +the default spatial harvesters and create new ones for other spatial services +like ArcGIS REST APIs. + + +Harvest Metadata API +-------------------- + +This plugin allows to access the actual harvested document via API requests. +It is enabled with the following plugin:: + + ckan.plugins = spatial_harvest_metadata_api + +(It was previously known as ``inspire_api``) + +To view the harvest objects (containing the harvested metadata) in the web +interface, these controller locations are added: + +* raw XML document: /harvest/object/{id} +* HTML representation: /harvest/object/{id}/html + +.. note:: The old URLs are now deprecated and redirect to the previously + mentioned: + + * /api/2/rest/harvestobject//xml + * /api/2/rest/harvestobject//html + + +For those harvest objects that have an original document (which was transformed +to ISO), this can be accessed via: + +* raw XML document: /harvest/object/{id}/original +* HTML representation: /harvest/object/{id}/html/original + +The HTML representation is created via an XSLT transformation. The extension +provides an XSLT file that should work on ISO 19139 based documents, but if you +want to use your own on your extension, you can override it using the following +configuration options:: + + ckanext.spatial.harvest.xslt_html_content = ckanext.myext:templates/xslt/custom.xslt + ckanext.spatial.harvest.xslt_html_content_original = ckanext.myext:templates/xslt/custom2.xslt + +If your project does not transform different metadata types you can ignore the +second option. + +.. _legacy_harvesters: + +Legacy harvesters +----------------- + +Prior to CKAN 2.0, the spatial harvesters available on this extension were +based on the GEMINI2 format, an ISO19139 profile used by the UK Location +Programme, and the logic for creating or updating datasets and the resulting +fields were somehow adapted to the needs for this particular project. The +harvesters were still generic enough and should work fine with other ISO19139 +based sources, but extra care has been put to make the new harvesters more +generic and robust, so these ones should only be used on existing instances: + +* ``gemini_csw_harvester`` +* ``gemini_waf_harvester`` +* ``gemini_doc_harvester`` + +If you are using these harvesters please consider upgrading to the new +versions described on the previous section. + + +.. todo:: Validation library details + + +.. _ckanext-harvest: https://github.com/okfn/ckanext-harvest +.. _ckanext-harvest documentation: https://github.com/okfn/ckanext-harvest#the-harvesting-interface +.. _ckanext-geodatagov: https://github.com/okfn/ckanext-geodatagov/blob/master/ckanext/geodatagov/harvesters/ diff --git a/doc/index.ckan b/doc/index.ckan deleted file mode 100644 index 67b8e99..0000000 --- a/doc/index.ckan +++ /dev/null @@ -1,19 +0,0 @@ -=============================== -Welcome to ckanext-spatial docs -=============================== - - -SPATIAL!! - -.. note :: - - This is the documentation for CKAN version '|version|'. If you are using a different version, use the links on the bottom right corner of the page to select the appropriate documentation. - -This Administration Guide covers how to set up and manage `CKAN `_ software. - -* The first two sections cover your two options for installing CKAN: package or source install. -* The rest of the first half of the Guide, up to :doc:`authorization`, covers setup and basic admin. -* The second half of the Guide, from :doc:`extensions` onwards, covers advanced tasks, including extensions and forms. - -For high-level information on what CKAN is, see the `CKAN website `_. - diff --git a/doc/index.rst b/doc/index.rst index 60b2822..9a6010f 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -1,50 +1,33 @@ -.. ckanext-spatial documentation master file, created by - sphinx-quickstart on Wed Apr 10 17:17:12 2013. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to ckanext-spatial's documentation! -=========================================== - ============================================== ckanext-spatial - Geo related plugins for CKAN ============================================== -This extension contains plugins that add geospatial capabilities to CKAN. -The following plugins are currently available: +This extension contains plugins that add geospatial capabilities to CKAN_. -* Spatial model for CKAN datasets and automatic geo-indexing (`spatial_metadata`) -* Spatial Search - Spatial search integration and API call (`spatial_query`). -* Spatial Search Widget - Map widget integrated on the search form (`spatial_query_widget`). -* Dataset Extent Map - Map widget showing a dataset extent (`dataset_extent_map`). -* WMS Preview - a Web Map Service (WMS) previewer (`wms_preview`). -* CSW Server - a basic CSW server - to server metadata from the CKAN instance (`cswserver`) -* GEMINI Harvesters - for importing INSPIRE-style metadata into CKAN (`gemini_csw_harvester`, `gemini_doc_harvester`, `gemini_waf_harvester`) -* Harvest Metadata API - a way for a user to view the harvested metadata XML, either as a raw file or styled to view in a web browser. (`spatial_harvest_metadata_api`) +You should have a CKAN instance installed before adding these plugins. Head to +the `CKAN documentation`_ for information on how to set up CKAN. -These libraries: -* CSW Client - a basic client for accessing a CSW server -* Validators - uses XSD / Schematron to validate geographic metadata XML. Used by the GEMINI Harvesters -* Validators for ISO19139/INSPIRE/GEMINI2 metadata. Used by the Validator. +The extension adds a spatial field to the default CKAN dataset schema, +using PostGIS_ as the backend. This allows to perform spatial queries and +display the dataset extent on the frontend. It also provides harvesters to +import geospatial metadata into CKAN from other sources, as well as commands +to support the CSW standard. Finally, it also includes plugins to preview +spatial formats such as GeoJSON_. -And these command-line tools: -* cswinfo - a command-line tool to help making requests of any CSW server - -As of October 2012, ckanext-csw and ckanext-inspire were merged into this extension. Contents: .. toctree:: :maxdepth: 2 - + + install spatial-search - dataset-map + harvesters + csw + previews - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` +.. _CKAN: http://ckan.org +.. _CKAN Documentation: http://docs.ckan.org +.. _PostGIS: http://postgis.org +.. _GeoJSON: http://geojson.org diff --git a/doc/install.rst b/doc/install.rst new file mode 100644 index 0000000..af67b06 --- /dev/null +++ b/doc/install.rst @@ -0,0 +1,243 @@ +====================== +Installation and Setup +====================== + +Check the Troubleshooting_ section if you get errors at any stage. + +.. _install_postgis: + +Install PostGIS and system packages +----------------------------------- + +.. note:: If you *only* want to load the :doc:`previews` you don't need to + install any of the packages on this section and can skip to the + next one. + +.. note:: The package names and paths shown are the defaults on an Ubuntu + 12.04 install (PostgreSQL 9.1 and PostGIS 1.5). Adjust the + package names and the paths if you are using a different version of + any of them. + +All commands assume an existing CKAN database named ``ckan_default``. + + +#. Install PostGIS:: + + sudo apt-get install postgresql-9.1-postgis + +#. Run the following commands. The first one will create the necessary + tables and functions in the database, and the second will populate + the spatial reference table:: + + sudo -u postgres psql -d ckan_default -f /usr/share/postgresql/9.1/contrib/postgis-1.5/postgis.sql + sudo -u postgres psql -d ckan_default -f /usr/share/postgresql/9.1/contrib/postgis-1.5/spatial_ref_sys.sql + + .. note:: If using PostgreSQL 8.x, run the following command to enable + the necessary language:: + + sudo -u postgres createlang plpgsql ckan_default + +#. Change the owner to spatial tables to the CKAN user to avoid errors later + on:: + + ALTER TABLE spatial_ref_sys OWNER TO ckan_default; + ALTER TABLE geometry_columns OWNER TO ckan_default; + +#. Execute the following command to see if PostGIS was properly + installed:: + + sudo -u postgres psql -d ckan_default -c "SELECT postgis_full_version()" + + You should get something like:: + + postgis_full_version + ------------------------------------------------------------------------------------------------------ + POSTGIS="1.5.2" GEOS="3.2.2-CAPI-1.6.2" PROJ="Rel. 4.7.1, 23 September 2009" LIBXML="2.7.7" USE_STATS + (1 row) + + +#. Install some other packages needed by the extension dependencies:: + + sudo apt-get install python-dev libxml2-dev libxslt1-dev libgeos-c1 + + +Install the extension +--------------------- + +1. Install this extension into your python environment (where CKAN is also + installed). + + .. note:: Depending on the CKAN core version you are targeting you will need + to use a different branch from the extension. + + For a production site, use the ``stable`` branch, unless there is a specific + branch that targets the CKAN core version that you are using. + + To target the latest CKAN core release:: + + (pyenv) $ pip install -e git+https://github.com/okfn/ckanext-spatial.git@stable#egg=ckanext-spatial + + To target an old release (if a release branch exists, otherwise use + ``stable``):: + + (pyenv) $ pip install -e git+https://github.com/okfn/ckanext-spatial.git@release-v1.8#egg=ckanext-spatial + + To target CKAN ``master``, use the extension ``master`` branch (ie no + branch defined):: + + (pyenv) $ pip install -e git+https://github.com/okfn/ckanext-spatial.git#egg=ckanext-spatial + + +2. Install the rest of python modules required by the extension:: + + (pyenv) $ pip install -r pip-requirements.txt + +To use the :doc:`harvesters`, you will need to install and configure the +harvester extension: `ckanext-harvest`_. Follow the install instructions on +its documentation for details on how to set it up. + + +Configuration +------------- + +Once PostGIS is installed and configured in the database the extension needs +to create a table to store the datasets extent, called ``package_extent``. + +This will happen automatically the next CKAN is restarted after adding the +plugins on the configuration ini file (eg when restarting Apache). + +If for some reason you need to explicitly create the table beforehand, you can +do it with the following command (with the virtualenv activated):: + + (pyenv) $ paster --plugin=ckanext-spatial spatial initdb [srid] --config=mysite.ini + +You can define the SRID of the geometry column. Default is 4326. If you are not +familiar with projections, we recommend to use the default value. To know more +about PostGIS tables, see :doc:`postgis-manual` + +Each plugin can be enabled by adding its name to the ``ckan.plugins`` in the +CKAN ini file. For example:: + + ckan.plugins = spatial_metadata spatial_query + +When enabling the spatial metadata, you can define the projection in which +extents are stored in the database with the following option. Use the EPSG code +as an integer (e.g 4326, 4258, 27700, etc). It defaults to 4326:: + + ckan.spatial.srid = 4326 + + +Troubleshooting +--------------- + +Here are some common problems you may find when installing or using the +extension: + +When initializing the spatial tables +++++++++++++++++++++++++++++++++++++ + +:: + + LINE 1: SELECT AddGeometryColumn('package_extent','the_geom', E'4326... + ^ + HINT: No function matches the given name and argument types. You might need to add explicit type casts. + "SELECT AddGeometryColumn('package_extent','the_geom', %s, 'GEOMETRY', 2)" ('4326',) + + +PostGIS was not installed correctly. Please check the "Setting up PostGIS" +section. + +:: + + sqlalchemy.exc.ProgrammingError: (ProgrammingError) permission denied for relation spatial_ref_sys + + +The user accessing the ckan database needs to be owner (or have permissions) +of the geometry_columns and spatial_ref_sys tables. + +When migrating to an existing PostGIS database +++++++++++++++++++++++++++++++++++++++++++++++ + +If you are loading a database dump to an existing PostGIS database, you may +find errors like :: + + ERROR: type "spheroid" already exists + +This means that the PostGIS functions are installed, but you may need to +create the necessary tables anyway. You can force psql to ignore these +errors and continue the transaction with the ON_ERROR_ROLLBACK=on:: + + sudo -u postgres psql -d ckan_default -f /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql -v ON_ERROR_ROLLBACK=on + +You will still need to populate the spatial_ref_sys table and change the +tables permissions. Refer to the previous section for details on how to do +it. + +When performing a spatial query ++++++++++++++++++++++++++++++++ + +:: + + InvalidRequestError: SQL expression, column, or mapped entity expected - got '' + +The spatial model has not been loaded. You probably forgot to add the +``spatial_metadata`` plugin to your ini configuration file. + +:: + + InternalError: (InternalError) Operation on two geometries with different SRIDs + +The spatial reference system of the database geometry column and the one +used by CKAN differ. Remember, if you are using a different spatial +reference system from the default one (WGS 84 lat/lon, EPSG:4326), you must +define it in the configuration file as follows:: + + ckan.spatial.srid = 4258 + +When running the spatial harvesters ++++++++++++++++++++++++++++++++++++ + +:: + + File "xmlschema.pxi", line 102, in lxml.etree.XMLSchema.__init__ (src/lxml/lxml.etree.c:154475) + lxml.etree.XMLSchemaParseError: local list type: A type, derived by list or union, must have the simple ur-type definition as base type, not '{http://www.opengis.net/gml}doubleList'., line 1 + +The XSD validation used by the spatial harvesters requires libxml2 ersion 2.9. + +With CKAN you would probably have installed an older version from your +distribution. (e.g. with ``sudo apt-get install libxml2-dev``). You need to +find the SO files for the old version:: + + $ find /usr -name "libxml2.so" + +For example, it may show it here: ``/usr/lib/x86_64-linux-gnu/libxml2.so``. +The directory of the SO file is used as a parameter to the ``configure`` next +on. + +Download the libxml2 source:: + + $ cd ~ + $ wget ftp://xmlsoft.org/libxml2/libxml2-2.9.0.tar.gz + +Unzip it:: + + $ tar zxvf libxml2-2.9.0.tar.gz + $ cd libxml2-2.9.0/ + +Configure with the SO directory you found before:: + + $ ./configure --libdir=/usr/lib/x86_64-linux-gnu + +Now make it and install it:: + + $ make + $ sudo make install + +Now check the install by running xmllint:: + + $ xmllint --version + xmllint: using libxml version 20900 + compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP DTDValid HTML Legacy C14N Catalog XPath XPointer XInclude Iconv ISO8859X Unicode Regexps Automata Expr Schemas Schematron Modules Debug Zlib + +.. _PostGIS: http://postgis.org +.. _ckanext-harvest: https://github.com/okfn/ckanext-harvest diff --git a/doc/postgis-manual.rst b/doc/postgis-manual.rst new file mode 100644 index 0000000..5fd08ee --- /dev/null +++ b/doc/postgis-manual.rst @@ -0,0 +1,43 @@ +========================== +Setting up a PostGIS table +========================== + +.. note:: The extension will generally set up the table automatically for you, + and also running the ``initdb`` command will have the same effect. This + section just describes what's going on for those who want to know more. + +To be able to store geometries and perform spatial operations, PostGIS_ +needs to work with geometry fields. Geometry fields should always be +added via the ``AddGeometryColumn`` function:: + + CREATE TABLE package_extent( + package_id text PRIMARY KEY + ); + + ALTER TABLE package_extent OWNER TO ckan_default; + + SELECT AddGeometryColumn('package_extent','the_geom', 4326, 'GEOMETRY', 2); + +This will add a geometry column in the ``package_extent`` table called +``the_geom``, with the spatial reference system EPSG:4326. The stored +geometries will be polygons, with 2 dimensions (The CKAN table uses the +GEOMETRY type to support multiple geometry types). + +Have a look a the table definition, and see how PostGIS has created +some constraints to ensure that the geometries follow the parameters +defined in the geometry column creation:: + + # \d package_extent + + Table "public.package_extent" + Column | Type | Modifiers + ------------+----------+----------- + package_id | text | not null + the_geom | geometry | + Indexes: + "package_extent_pkey" PRIMARY KEY, btree (package_id) + Check constraints: + "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2) + "enforce_srid_the_geom" CHECK (st_srid(the_geom) = 4326) + +.. _PostGIS: http://postgis.org diff --git a/doc/previews.rst b/doc/previews.rst new file mode 100644 index 0000000..7b0d737 --- /dev/null +++ b/doc/previews.rst @@ -0,0 +1,68 @@ +============================ +Previews for Spatial Formats +============================ + +The extension includes some plugins that implement the IResourcePreview_ +interface, allowing to preview spatial resource files. They are based in +popular Javascript mapping libraries and should be really easy to extend and +adapt to your own needs. + + +GeoJSON Preview +--------------- + +.. image:: _static/preview-geojson.png + +The GeoJSON previewer is based on Leaflet_. It will render GeoJSON_ files on a +map and add a popup showing the features properties, for those resources that +have a format of ``geojson`` or ``gjosn``. + +To enable the GeoJSON previewer you need to add the ``geojson_preview`` plugin +to your ini file. This plugin also requires the `resource_proxy`_ +plugin (Make sure you load the ``resource_proxy`` plugin before any other +from the spatial extension):: + + ckan.plugins = resource_proxy geojson_preview + + +WMS Preview +----------- + +.. image:: _static/preview-wms.png + +The WMS previewer is based o OpenLayers_. When the plugin is enabled, if +datasets contain a resource that has ``wms`` format, the resource page will +load a simple map viewer that will attempt to load the remote service layers, +based on the GetCapabilities response. + +To enable the WMS previewer you need to add the ``wms_preview`` plugin to your +ini file. This plugin also requires the `resource_proxy`_ +plugin (Make sure you load the ``resource_proxy`` plugin before any other +from the spatial extension:: + + ckan.plugins = resource_proxy wms_preview + +.. note:: Please note that the WMS previewer included in ckanext-spatial is + just a proof of concept and has important limitations, and is + just intended as a bootstrap for developers willing to build a more + sophisticated one. + + Some projects that have built more advanced map viewers and + integrated them with CKAN include: + + * Data.gov.uk (http://data.gov.uk): + - https://github.com/datagovuk/ckanext-dgu + - https://github.com/datagovuk/ckanext-os + + * Catalog.data.gov (http://catalog.data.gov): + - https://github.com/okfn/ckanext-geodatagov + - https://github.com/chilukey/viewer + + + +.. _IResourcePreview: http://docs.ckan.org/en/latest/writing-extensions.html#ckan.plugins.interfaces.IResourcePreview +.. _resource_proxy: http://docs.ckan.org/en/latest/data-viewer.html#viewing-remote-resources-the-resource-proxy +.. _Leaflet: http://leafletjs.org +.. _GeoJSON: http://geojson.org +.. _OpenLayers: http://openlayers.org + diff --git a/doc/spatial-search.rst b/doc/spatial-search.rst index 7404ee9..2223dff 100644 --- a/doc/spatial-search.rst +++ b/doc/spatial-search.rst @@ -1,9 +1,281 @@ +============== Spatial Search ============== -To enable the spatial query you need to add the `spatial_query` plugin to your -ini file (See `Configuration`_). This plugin requires the `spatial_metadata` -plugin. +The spatial extension allows to index datasets with spatial information so they +can be filtered via a spatial query. This includes both via the web interface +(see the `Spatial Search Widget`_) or via the `action API`_, e.g.:: + + POST http://localhost:5000/api/action/package_search + { "q": "Pollution", + "facet": "true", + "facet.field": "country", + "extras": { + "ext_bbox": "-7.535093,49.208494,3.890688,57.372349" } + } + +.. versionchanged:: 2.0.1 + Starting from this version the spatial filter it is also supported on GET + requests: + + http://localhost:5000/api/action/package_search?q=Pollution&ext_bbox=-7.535093,49.208494,3.890688,57.372349 + + +Setup +----- + +To enable the spatial query you need to add the ``spatial_query`` plugin to +your ini file. This plugin requires the ``spatial_metadata`` plugin, eg:: + + ckan.plugins = [other plugins] spatial_metadata spatial_query + +To define which backend to use for the spatial search use the following +configuration option (see `Choosing a backend for the spatial search`_):: + + ckanext.spatial.search_backend = solr + + +Geo-Indexing your datasets +-------------------------- + +Regardless of the backend that you are using, in order to make a dataset +queryable by location, an special extra must be defined, with its key named +'spatial'. The value must be a valid GeoJSON_ geometry, for example:: + + { + "type":"Polygon", + "coordinates":[[[2.05827, 49.8625],[2.05827, 55.7447], [-6.41736, 55.7447], [-6.41736, 49.8625], [2.05827, 49.8625]]] + } + +or:: + + { + "type": "Point", + "coordinates": [-3.145,53.078] + } + + +Every time a dataset is created, updated or deleted, the extension will +synchronize the information stored in the extra with the geometry table. + +Choosing a backend for the spatial search ++++++++++++++++++++++++++++++++++++++++++ + +There are different backends supported for the spatial search, it is important +to understand their differences and the necessary setup required when choosing +which one to use. + +The following table summarizes the different spatial search backends: + ++------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ +| Backend | Solr Versions | Supported geometries | Sorting and relevance | Performance with large number of datasets | ++========================+===============+=====================================+===========================================================+===========================================+ +| ``solr`` | 3.1 to 4.x | Bounding Box | Yes, spatial sorting combined with other query parameters | Good | ++------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ +| ``solr-spatial-field`` | 4.x | Bounding Box, Point and Polygon [1] | Not implemented | Good | ++------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ +| ``postgis`` | 1.3 to 4.x | Bounding Box | Partial, only spatial sorting supported [2] | Poor | ++------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ + + +[1] Requires JTS + +[2] Needs ``ckanext.spatial.use_postgis_sorting`` set to True + + + +We recommend to use the ``solr`` backend whenever possible. Here are more +details about the available options: + +* ``solr`` (Recommended) + This option uses normal Solr fields to index the relevant bits of + information about the geometry and uses an algorithm function to sort + results by relevance, keeping any other non-spatial filtering. It only + supports bounding boxes both for the geometries to be indexed and the + input query shape. It requires `EDisMax`_ query parser, so it will only + work on versions of Solr greater than 3.1 (We recommend using Solr 4.x). + + You will need to add the following fields to your Solr schema file to + enable it:: + + + + + + + + + + + +* ``solr-spatial-field`` + This option uses the `spatial field`_ introduced in Solr 4, which allows + to index points, rectangles and more complex geometries (complex geometries + will require `JTS`_, check the documentation). + Sorting has not yet been implemented, users willing to do so will need to + modify the query using the ``before_search`` extension point. + + You will need to add the following field type and field to your Solr + schema file to enable it (Check the `Solr documentation`__ for more + information on the different parameters, note that you don't need + ``spatialContextFactory`` if you are not using JTS):: + + + + + + + + + + +* ``postgis`` + This is the original implementation of the spatial search. It + does not require any change in the Solr schema and can run on Solr 1.x, + but it is not as efficient as the previous ones. Basically the bounding + box based query is performed in PostGIS first, and the ids of the matched + datasets are added as a filter to the Solr request. This, apart from being + much less efficient, can led to issues on Solr due to size of the requests + (See `Solr configuration issues on legacy PostGIS backend`_). There is + support for a spatial ranking on this backend (setting + ``ckanext.spatial.use_postgis_sorting`` to True on the ini file), but + it can not be combined with any other filtering. + + +Spatial Search Widget +--------------------- + + +.. image:: _static/spatial-search-widget.png + +The extension provides a snippet to add a map widget to the search form, which +allows filtering results by an area of interest. + +To add the map widget to the to the sidebar of the search page, add this to the +dataset search page template +(``myproj/ckanext/myproj/templates/package/search.html``):: + + {% block secondary_content %} + + {% snippet "spatial/snippets/spatial_query.html" %} + + {% endblock %} + +By default the map widget will show the whole world. If you want to set up a +different default extent, you can pass an extra ``default_extent`` to the +snippet, either with a pair of coordinates like this:: + + {% snippet "spatial/snippets/spatial_query.html", default_extent="[[15.62, + -139.21], [64.92, -61.87]]" %} + +or with a GeoJSON object describing a bounding box (note the escaped quotes):: + + {% snippet "spatial/snippets/spatial_query.html", default_extent="{ \"type\": + \"Polygon\", \"coordinates\": [[[74.89, 29.39],[74.89, 38.45], [60.50, + 38.45], [60.50, 29.39], [74.89, 29.39]]]}" %} + +You need to load the ``spatial_metadata`` and ``spatial_query`` plugins to use this +snippet. + + + +Dataset Extent Map +------------------ + +.. image:: _static/dataset-extent-map.png + +Using the snippets provided, if datasets contain a ``spatial`` extra like the +one described in the previous section, a map will be shown on the dataset +details page. + +There are snippets already created to load the map on the left sidebar or in +the main body of the dataset details page, but these can be easily modified to +suit your project needs + +To add a map to the sidebar, add this to the dataset details page template (eg +``myproj/ckanext/myproj/templates/package/read.html``):: + + {% block secondary_content %} + {{ super() }} + + {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %} + {% if dataset_extent %} + {% snippet "spatial/snippets/dataset_map_sidebar.html", extent=dataset_extent %} + {% endif %} + + {% endblock %} + +For adding the map to the main body, add this:: + + {% block primary_content %} + + + +
+ + + + {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %} + {% if dataset_extent %} + {% snippet "spatial/snippets/dataset_map.html", extent=dataset_extent %} + {% endif %} + +
+ {% endblock %} + + +You need to load the ``spatial_metadata`` plugin to use these snippets. + +Legacy Search +------------- + +Solr configuration issues on legacy PostGIS backend ++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. warning:: + + If you find any of the issues described in this section it is strongly + recommended that you consider switching to one of the Solr based backends + which are much more efficient. These notes are just kept for informative + purposes. + + +If using Spatial Query functionality then there is an additional SOLR/Lucene +setting that should be used to set the limit on number of datasets searchable +with a spatial value. + +The setting is ``maxBooleanClauses`` in the solrconfig.xml and the value is the +number of datasets spatially searchable. The default is ``1024`` and this could +be increased to say ``16384``. For a SOLR single core this will probably be at +`/etc/solr/conf/solrconfig.xml`. For a multiple core set-up, there will me +several solrconfig.xml files a couple of levels below `/etc/solr`. For that +case, *all* of the cores' `solrconfig.xml` should have this setting at the new +value. + +Example:: + + 16384 + +This setting is needed because PostGIS spatial query results are fed into SOLR +using a Boolean expression, and the parser for that has a limit. So if your +spatial area contains more than the limit (of which the default is 1024) then +you will get this error:: + + Dataset search error: ('SOLR returned an error running query... + +and in the SOLR logs you see:: + + too many boolean clauses ... Caused by: + org.apache.lucene.search.BooleanQuery$TooManyClauses: maxClauseCount is set to + 1024 + + +Legacy API +++++++++++ The extension adds the following call to the CKAN search API, which returns datasets with an extent that intersects with the bounding box provided:: @@ -11,55 +283,15 @@ datasets with an extent that intersects with the bounding box provided:: /api/2/search/dataset/geo?bbox={minx,miny,maxx,maxy}[&crs={srid}] If the bounding box coordinates are not in the same projection as the one -defined in the database, a CRS must be provided, in one of the following -forms: +defined in the database, a CRS must be provided, in one of the following forms: -- urn:ogc:def:crs:EPSG::4326 +- `urn:ogc:def:crs:EPSG::4326` - EPSG:4326 - 4326 -As of CKAN 1.6, you can integrate your spatial query in the full CKAN -search, via the web interface (see the `Spatial Query Widget`_) or -via the `action API`__, e.g.:: - - POST http://localhost:5000/api/action/package_search - { - "q": "Pollution", - "extras": { - "ext_bbox": "-7.535093,49.208494,3.890688,57.372349" - } - } - -__ http://docs.ckan.org/en/latest/apiv3.html - -Geo-Indexing your datasets --------------------------- - -In order to make a dataset queryable by location, an special extra must -be defined, with its key named 'spatial'. The value must be a valid GeoJSON_ -geometry, for example:: - - {"type":"Polygon","coordinates":[[[2.05827, 49.8625],[2.05827, 55.7447], [-6.41736, 55.7447], [-6.41736, 49.8625], [2.05827, 49.8625]]]} - -or:: - - { "type": "Point", "coordinates": [-3.145,53.078] } - +.. _action API: http://docs.ckan.org/en/latest/apiv3.html +.. _edismax: http://wiki.apache.org/solr/ExtendedDisMax +.. _JTS: http://www.vividsolutions.com/jts/JTSHome.htm +.. _spatial field: http://wiki.apache.org/solr/SolrAdaptersForLuceneSpatial4 +__ `spatial field`_ .. _GeoJSON: http://geojson.org - -Every time a dataset is created, updated or deleted, the extension will synchronize -the information stored in the extra with the geometry table. - - -Spatial Search Widget ---------------------- - -**Note**: this plugin requires CKAN 1.6 or higher. - -To enable the search map widget you need to add the `spatial_query_widget` plugin to your -ini file (See `Configuration`_). You also need to load both the `spatial_metadata` -and the `spatial_query` plugins. - -When the plugin is enabled, a map widget will be shown in the dataset search form, -where users can refine their searchs drawing an area of interest. - From e6e644353b065bd9a516609a765ce0323486aadd Mon Sep 17 00:00:00 2001 From: amercader Date: Sun, 8 Sep 2013 19:51:42 +0100 Subject: [PATCH 070/114] [#39] Add doc-requirements.txt --- doc-requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc-requirements.txt diff --git a/doc-requirements.txt b/doc-requirements.txt new file mode 100644 index 0000000..3049177 --- /dev/null +++ b/doc-requirements.txt @@ -0,0 +1 @@ +Sphinx==1.1.3 From 8d261514c3ab56bfab9508b924c4f1f31ec15c04 Mon Sep 17 00:00:00 2001 From: amercader Date: Sun, 8 Sep 2013 21:25:41 +0100 Subject: [PATCH 071/114] [#39] Update submodule path --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 17ee088..157e28c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "doc/_themes/sphinx-theme-okfn"] path = doc/_themes/sphinx-theme-okfn - url = git@github.com:okfn/sphinx-theme-okfn.git + url = https://github.com/okfn/sphinx-theme-okfn.git From 93974bc0a3de528743392d85d01d3547f594caef Mon Sep 17 00:00:00 2001 From: amercader Date: Mon, 9 Sep 2013 09:43:55 +0100 Subject: [PATCH 072/114] [#39] Update README to point to new docs --- README.rst | 1065 ++-------------------------------------------------- 1 file changed, 30 insertions(+), 1035 deletions(-) diff --git a/README.rst b/README.rst index a97484c..f9abb71 100644 --- a/README.rst +++ b/README.rst @@ -2,1055 +2,50 @@ ckanext-spatial - Geo related plugins for CKAN ============================================== -This extension contains plugins that add geospatial capabilities to CKAN. -The following plugins are currently available: -* `Spatial model <#geo-indexing-your-datasets>`_ for CKAN datasets and automatic geo-indexing (``spatial_metadata``) -* `Spatial Search`_ - Spatial filtering for the dataset search (``spatial_query``). -* `Spatial Harvesters`_ - for importing spatial metadata into CKAN (``csw_harvester``, ``doc_harvester``, ``waf_harvester``) -* `Harvest Metadata API`_ - a way for a user to view the harvested metadata XML, either as a raw file or styled to view in a web browser. (``spatial_harvest_metadata_api``) -* `GeoJSON Preview`_ - a GeoJSON previewer (``geojson_preview``). -* `WMS Preview`_ - a Web Map Service (WMS) previewer (``wms_preview``). -* `CSW Server`_ - a basic CSW server - to server metadata from the CKAN instance (``cswserver``). **Deprecated:** Please see `ckan-pycsw`_. +This extension contains plugins that add geospatial capabilities to CKAN_, +including: -These snippets (to be used with CKAN>=2.0): +* A spatial field on the default CKAN dataset schema, that uses PostGIS_ + as the backend and allows to perform spatial queries and to display the + dataset extent on the frontend. +* Harvesters to import geospatial metadata into CKAN from other sources + in ISO 19139 format and others. +* Commands to support the CSW standard. +* Plugins to preview spatial formats such as GeoJSON_. -* `Dataset Extent Map`_ - Map widget showing a dataset extent. -* `Spatial Search Widget`_ - Map widget integrated on the search form. +Full documentation, including installation instructions can be found at: + + http://docs.ckan.org/projects/ckanext-spatial -These libraries: -* `CSW Client`_ - a basic client for accessing a CSW server -* `Validators`_ - uses XSD / Schematron to validate geographic metadata XML. Used by the Spatial Harvesters -* Validators for ISO19139/INSPIRE/GEMINI2 metadata. Used by the Validator. - -And these command-line tools: - -* `ckan-pycsw`_ - a command for integrating CKAN with `pycsw `_, a fully compliant CSW server. -* `cswinfo`_ - a command-line tool to help making requests of any CSW server - - -As of October 2012, ckanext-csw and ckanext-inspire were merged into this extension. - -About the components -==================== - -Spatial Search --------------- - -The spatial extension allows to index datasets with spatial information so -they can be filtered via a spatial query. This includes both via the web -interface (see the `Spatial Search Widget`_) or via the `action API`__, e.g.:: - - POST http://localhost:5000/api/action/package_search - { - "q": "Pollution", - "facet": "true", - "facet.field": "country", - "extras": { - "ext_bbox": "-7.535093,49.208494,3.890688,57.372349" - } - } - -__ http://docs.ckan.org/en/latest/apiv3.html - -To enable the spatial query you need to add the ``spatial_query`` plugin to your -ini file (See `Configuration`_). This plugin requires the ``spatial_metadata`` -plugin. - -There are different backends supported for the spatial search, it is important -to understand their differences and the necessary setup required when choosing -which one to use. The backend to use is defined with the configuration option -``ckanext.spatial.search_backend``, eg:: - - ckanext.spatial.search_backend = solr - -The following table summarizes the different spatial search backends: - -+------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ -| Backend | Solr Versions | Supported geometries | Sorting and relevance | Performance with large number of datasets | -+========================+===============+=====================================+===========================================================+===========================================+ -| ``solr`` | 3.1 to 4.x | Bounding Box | Yes, spatial sorting combined with other query parameters | Good | -+------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ -| ``solr-spatial-field`` | 4.x | Bounding Box, Point and Polygon (1) | Not implemented | Good | -+------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ -| ``postgis`` | 1.3 to 4.x | Bounding Box | Partial, only spatial sorting supported (2) | Poor | -+------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+ - -(1) Requires JTS -(2) Needs ``ckanext.spatial.use_postgis_sorting`` set to True - - -We recommend to use the ``solr`` backend whenever possible. Here are more -details about the available options: - -* ``solr`` (Recommended) - This option uses normal Solr fields to index the relevant bits of - information about the geometry and uses an algorithm function to - sort results by relevance, keeping any other non-spatial filtering. It only - supports bounding boxes both for the geometries to be indexed and the input - query shape. It requires `EDisMax`_ query parser, so it will only work on - versions of Solr greater than 3.1 (We recommend using Solr 4.x). - - You will need to add the following fields to your Solr schema file to enable it:: - - - - - - - - - - - -* ``solr-spatial-field`` - This option uses the `spatial field `_ - introduced in Solr 4, which allows to index points, rectangles and more - complex geometries (complex geometries will require `JTS`_, check the - documentation). Sorting has not yet been implemented, users willing to do so - will need to modify the query using the ``before_search`` extension point. - - You will need to add the following field type and field to your Solr schema - file to enable it (Check the Solr documentation for more information on - the different parameters, note that you don't need ``spatialContextFactory`` if - you are not using JTS):: - - - - - - - - - - -* ``postgis`` - This is the original implementation of the spatial search. It does not - require any change in the Solr schema and can run on Solr 1.x, but it is - not as efficient as the previous ones. Basically the bounding box based - query is performed in PostGIS first, and the ids of the matched datasets - are added as a filter to the Solr request. This, apart from being much - less efficient, can led to issues on Solr due to size of the requests (See - `Solr configuration issues on legacy PostGIS backend`_). There is support - for a spatial ranking on this backend (setting - ``ckanext.spatial.use_postgis_sorting`` to True on the ini file), but it - can not be combined with any other filtering. - - -.. _edismax: http://wiki.apache.org/solr/ExtendedDisMax -.. _JTS: http://www.vividsolutions.com/jts/JTSHome.htm - - -Geo-Indexing your datasets -++++++++++++++++++++++++++ - -Regardless of the backend that you are using, in order to make a dataset -queryable by location, an special extra must be defined, with its key named -'spatial'. The value must be a valid GeoJSON_ geometry, for example:: - - {"type":"Polygon","coordinates":[[[2.05827, 49.8625],[2.05827, 55.7447], [-6.41736, 55.7447], [-6.41736, 49.8625], [2.05827, 49.8625]]]} - -or:: - - { "type": "Point", "coordinates": [-3.145,53.078] } - -.. _GeoJSON: http://geojson.org - -Every time a dataset is created, updated or deleted, the extension will synchronize -the information stored in the extra with the geometry table. - - -Spatial Search Widget -+++++++++++++++++++++ - -The extension provides a snippet to add a map widget to the search form, which allows -filtering results by an area of interest. - -To add the map widget to the to the sidebar of the search page, add -this to the dataset search page template -(``myproj/ckanext/myproj/templates/package/search.html``):: - - {% block secondary_content %} - - {% snippet "spatial/snippets/spatial_query.html" %} - - {% endblock %} - -By default the map widget will show the whole world. If you want to set -up a different default extent, you can pass an extra ``default_extent`` to the -snippet, either with a pair of coordinates like this:: - - {% snippet "spatial/snippets/spatial_query.html", default_extent="[[15.62, -139.21], [64.92, -61.87]]" %} - -or with a GeoJSON object describing a bounding box (note the escaped quotes):: - - {% snippet "spatial/snippets/spatial_query.html", default_extent="{ \"type\": \"Polygon\", \"coordinates\": [[[74.89, 29.39],[74.89, 38.45], [60.50, 38.45], [60.50, 29.39], [74.89, 29.39]]]}" %} - -You need to load the `spatial_metadata` and `spatial_query` plugins to use this snippet. - - -Solr configuration issues on legacy PostGIS backend -+++++++++++++++++++++++++++++++++++++++++++++++++++ - -.. warning:: - - If you find any of the issues described in this section it is strongly - suggested that you consider switching to one of the Solr based backends - which are much more efficient. These notes are just kept for informative - purposes. - - -If using Spatial Query functionality then there is an additional SOLR/Lucene setting that should be used to set the limit on number of datasets searchable with a spatial value. - -The setting is ``maxBooleanClauses`` in the solrconfig.xml and the value is the number of datasets spatially searchable. The default is ``1024`` and this could be increased to say ``16384``. For a SOLR single core this will probably be at `/etc/solr/conf/solrconfig.xml`. For a multiple core set-up, there will me several solrconfig.xml files a couple of levels below `/etc/solr`. For that case, *all* of the cores' `solrconfig.xml` should have this setting at the new value. - -Example:: - - 16384 - -This setting is needed because PostGIS spatial query results are fed into SOLR using a Boolean expression, and the parser for that has a limit. So if your spatial area contains more than the limit (of which the default is 1024) then you will get this error:: - - Dataset search error: ('SOLR returned an error running query... - -and in the SOLR logs you see:: - - too many boolean clauses - ... - Caused by: org.apache.lucene.search.BooleanQuery$TooManyClauses: - maxClauseCount is set to 1024 - - -Legacy API -++++++++++ - -The extension adds the following call to the CKAN search API, which returns -datasets with an extent that intersects with the bounding box provided:: - - /api/2/search/dataset/geo?bbox={minx,miny,maxx,maxy}[&crs={srid}] - -If the bounding box coordinates are not in the same projection as the one -defined in the database, a CRS must be provided, in one of the following -forms: - -- urn:ogc:def:crs:EPSG::4326 -- EPSG:4326 -- 4326 - - - -Dataset Extent Map ------------------- - -Using the snippets provided, if datasets contain a 'spatial' extra like the one -described in the previous section, a map will be shown on the dataset details page. - -There are snippets already created to laod the map on the left sidebar or in the main -bdoy of the dataset details page, but these can easily modified to suit your project -needs - -To add a map to the sidebar, add this to the dataset details page template -(eg ``myproj/ckanext/myproj/templates/package/read.html``):: - - {% block secondary_content %} - {{ super() }} - - {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %} - {% if dataset_extent %} - {% snippet "spatial/snippets/dataset_map_sidebar.html", extent=dataset_extent %} - {% endif %} - - {% endblock %} - -For adding the map to the main body, add this:: - - {% block primary_content %} - - - -
- - - - {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %} - {% if dataset_extent %} - {% snippet "spatial/snippets/dataset_map.html", extent=dataset_extent %} - {% endif %} - -
- {% endblock %} - - -You need to load the ``spatial_metadata`` plugin to use these snippets. - -WMS Preview ------------ - -To enable the WMS previewer you need to add the ``wms_preview`` plugin to your -ini file (See `Configuration`_). This plugin also requires the `resource_proxy`_ -plugin (Make sure you load the ``resource_proxy`` plugin before any other -from the spatial extension). - -Please note that this is an experimental plugin and may be unstable. - -When the plugin is enabled, if datasets contain a resource that has 'WMS' format, -the resource page will load simple map viewer that will attempt to load the -remote service layers, based on the GetCapabilities response. - - -GeoJSON Preview ---------------- - -To enable the GeoJSON previewer you need to add the ``geojson_preview`` plugin to your -ini file (See `Configuration`_). This plugin also requires the `resource_proxy`_ -plugin (Make sure you load the ``resource_proxy`` plugin before any other -from the spatial extension). - - -When the plugin is enabled, if datasets contain a resource that has 'gjson' or 'geojson' -format, the resource page will load simple map viewer that will show the features on a map. - -.. _resource_proxy: http://docs.ckan.org/en/latest/data-viewer.html#viewing-remote-resources-the-resource-proxy - -ckan-pycsw ----------- - -The spatial extension offers the ``ckan-pycsw`` command, which allows to expose -the spatial datasets harvested from other sources in a CSW interface. This is -powered by `pycsw `_, which fully implements the OGC CSW -specification. - -How it works -++++++++++++ - - -The current implementation is based on CKAN and pycsw being loosely integrated -via the CKAN API. pycsw will be generally installed in the same server as CKAN -(although it can also be run on a separate one), and the synchronization -command will be run regularly to keep the records on the pycsw repository up to -date. This is done using the CKAN API to get all the datasets identifiers (more -precisely the ones from datasets that have been harvested) and then deciding -which ones need to be created, updated or deleted on the pycsw repository. For -those that need to be created or updated, the original harvested spatial -document (ie ISO 19139) is requested from CKAN, and it is then imported using -pycsw internal functions:: - - Harvested - datasets - + - | - v - +--------+ +---------+ - | | CKAN API | | - | CKAN | +------------> | pycsw | +------> CSW - | | | | - +--------+ +---------+ - - -Remember, only datasets that were harvested with the `Spatial Harvesters`_ -can currently be exposed via pycsw. - -All necessary tasks are done with the ``ckan-pycsw`` command. To get more -details of its usage, run the following:: - - cd /usr/lib/ckan/default/src/ckanext-spatial - paster ckan-pycsw --help - - -Setup -+++++ - -1. Install pycsw. There are several options for this, depending on your - server setup, check the `pycsw documentation `_. - - .. note:: CKAN integration requires at least pycsw version 1.6.1. Make sure - to install at least this version. - - The following instructions assume that you have installed CKAN via a - `package install `_ - and should be run as root, but the steps are the same if you are setting - it up in another location:: - - cd /usr/lib/ckan/default/src - source ../bin/activate - - # From now on the virtualenv should be activated - - git clone https://github.com/geopython/pycsw.git - cd pycsw - # Remember to use at least pycsw 1.6.1 - git checkout 1.6.1 - pip install -e . - python setup.py build - python setup.py install - -2. Create a database for pycsw. In theory you can use the same database that - CKAN is using, but if you want to keep them separated, use the following - command to create a new one (we'll use the same default user though):: - - sudo -u postgres createdb -O ckan_default pycsw -E utf-8 - - It is strongly recommended that you install PostGIS in the pycsw databaset, - so its spatial functions are used. See the `Setting up PostGIS`_ section - for details. - -3. Configure pycsw. An example configuration file is included on the source:: - - cp default-sample.cfg default.cfg - - To keep things tidy we will create a symlink to this file on the CKAN - configuration directory:: - - ln -s /usr/lib/ckan/default/src/pycsw/default.cfg /etc/ckan/default/pycsw.cfg - - Open the file with your favourite editor. The main settings you should tweak - are ``server.home`` and ``repository.database``:: - - [server] - home=/usr/lib/ckan/default/src/pycsw - ... - [repository] - database=postgresql://ckan_default:pass@localhost/pycsw - - The rest of the options are described `here `_. - -4. Setup the pycsw table. This is done with the ``ckan-pycsw`` paster command - (Remember to have the virtualenv activated when running it):: - - cd /usr/lib/ckan/default/src/ckanext-spatial - paster ckan-pycsw setup -p /etc/ckan/default/pycsw.cfg - - At this point you should be ready to run pycsw with the wsgi script that it - includes:: - - cd /usr/lib/ckan/default/src/pycsw - python csw.wsgi - - This will run pycsw at http://localhost:8000. Visiting the following URL - should return you the Capabilities file: - - http://localhost:8000/?service=CSW&version=2.0.2&request=GetCapabilities - -5. Load the CKAN datasets into pycsw. Again we will use the ``ckan-pycsw`` - command for this:: - - cd /usr/lib/ckan/default/src/ckanext-spatial - paster ckan-pycsw load -p /etc/ckan/default/pycsw.cfg - - .. note:: If you get errors similar to this one, this is caused by - limitations on the pycsw model definition. This should be fixed in - future versions of pycsw:: - - ERROR: not inserted f8d48eaf-780b-40b8-a502-7a903fde5b1c Error:ERROR: value too long for type character varying(256) - - - When the loading is finished, check that results are returned when visiting - this link: - - http://localhost:8000/?request=GetRecords&service=CSW&version=2.0.2&resultType=results&outputSchema=http://www.isotc211.org/2005/gmd&typeNames=csw:Record&elementSetName=summary - - The ``numberOfRecordsMatched`` should match the number of harvested datasets - in CKAN (minus import errors). If you run the command again new or udpated - datasets will be synchronized and deleted datasets from CKAN will be removed - from pycsw as well. - -Running it on production site -+++++++++++++++++++++++++++++ - -On a production site you probably want to run the load command regularly to -keep CKAN and pycsw in sync, and serve pycsw with Apache + mod_wsgi like CKAN. - -* To run the load command regularly you can set up a cron job. Type ``crontab -e`` - and copy the following lines:: - - # m h dom mon dow command - 0 * * * * /usr/lib/ckan/default/bin/paster --plugin=ckanext-spatial ckan-pycsw load -p /etc/ckan/default/pycsw.cfg - - This particular example will run the load command every hour. You can of - course modify this periodicity, for instance reducing it for huge instances. - This `Wikipedia page `_ - has a good overview of the crontab syntax. - -* To run pycsw under Apache check the pycsw `installation documentation `_ - or follow this quick steps (they assume the paths used on the previous steps): - - - Edit ``/etc/apache2/sites-available/ckan_default`` and add the following - line just before the existing ``WSGIScriptAlias`` directive:: - - WSGIScriptAlias /csw /usr/lib/ckan/default/src/pycsw/csw.wsgi - - - Edit the ``/usr/lib/ckan/default/src/pycsw/csw.wsgi`` file and add these two - lines just after the imports on the top of the file:: - - activate_this = os.path.join('/usr/lib/ckan/default/bin/activate_this.py') - execfile(activate_this, {"__file__":activate_this}) - - We need these to activate the virtualenv where we installed pycsw into. - - - Restart Apache:: - - service apache2 restart - - pycsw should be now accessible at http://localhost/csw - - - -CSW Server ----------- - -.. note:: **Deprecated:** The old csw plugin has been deprecated, please see `ckan-pycsw`_ - for details on how to integrate with pycsw. - -CSW (Catalogue Service for the Web) is an OGC standard for a web interface that allows you to access metadata (which are records that describe data or services) - -NB Only 'harvested' datasets are served by this CSW Server. This is because the harvested document is the one that is served, not something derived from the CKAN Dataset object. Datasets that are created in CKAN by methods other than harvesting are not served. - -The currently supported methods with this CSW Server are: - * GetCapabilities - * GetRecords - * GetRecordById - -ckanext-csw provides the CSW service at ``/csw``. - -For example you can ask the capabilities of the CSW server installed into CKAN running on 127.0.0.1:5000 like this:: - - curl 'http://127.0.0.1:5000/csw?request=GetCapabilities&service=CSW&version=2.0.2' - -And get a list of the records like this:: - - curl 'http://127.0.0.1:5000/csw?request=GetRecords&service=CSW&resultType=results&elementSetName=full&version=2.0.2' - -The standard CSW response is in XML format. - -Spatial Harvesters ------------------- - -The spatial extension provides some harvesters for importing ISO19139-based -metadata into CKAN, as well as providing a base class for writing new ones. -The harvesters use the interface provided by ckanext-harvest_, so you will need to -install and set it up first. - -Once ckanext-harvest is installed, you can add the following plugins to your -ini file to enable the different harvesters (If you are upgrading from a -previous version to CKAN 2.0 see legacy_harvesters_): - - * ``csw_harvester`` - CSW server - * ``waf_harvester`` - WAF (Web Accessible Folder): An online accessible index page with links to metadata documents - * ``doc_harvester`` - A single online accessible metadata document. - -Have a look at the ckanext-harvest `documentation -`_ if you want to have an -overview of how the CKAN harvesters work, but basically there are three -separate stages: - - * gather_stage - Aggregates all the remote identifiers for a particular source (ie identifiers for a CSW server, files for a WAF). - * fetch_stage - Fetches all the remote documents and stores them on the database. - * import_stage - Performs all the processing for transforming the remote content into a CKAN dataset: validates the document, parses it, converts it to a CKAN dataset dict and saves it in the database. - -The extension provides different XSD and schematron based validators. You can specify which validators to use for the remote documents with the following configuration option:: - - ckan.spatial.validator.profiles = iso19193eden - -By default, the import stage will stop if the validation of the harvested document fails. This can be -modified setting the ``ckanext.spatial.harvest.continue_on_validation_errors`` to True. The setting can -also be applied at the source level setting to True the ``continue_on_validation_errors`` key on the source -configuration object. - -By default the harvesting actions (eg creating or updating datasets) will be performed by the internal site admin user. -This is the recommended setting, but if necessary, it can be overridden with the -``ckanext.spatial.harvest.user_name`` config option, eg to support the old hardcoded 'harvest' user:: - - ckanext.spatial.harvest.user_name = harvest - -Customizing the harvesters -++++++++++++++++++++++++++ - -The default harvesters provided in this extension can be overriden from -extensions to customize to your needs. You can either extend ``CswHarvester`` or -``WAFfHarverster`` or the main ``SpatialHarvester`` class. There are some extension points that can be safely overriden from your extension. Probably the most useful is ``get_package_dict``, which allows to tweak the dataset fields before creating or updating them. ``transform_to_iso`` allows to hook into transformation mechanisms to transform other formats into ISO1939, the only one directly supported byt he spatial harvesters. Finally, the whole ``import_stage`` can be overriden if the default logic does not suit your needs. - -Check the source code of ``ckanext/spatial/harvesters/base.py`` for more details on these functions. - -The `ckanext-geodatagov `_ extension contains live examples on how to extend the default spatial harvesters and create new ones for other spatial services. - - - - -.. _legacy_harvesters: - -Legacy harvesters -+++++++++++++++++ - -Prior to CKAN 2.0, the spatial harvesters available on this extension were -based on the GEMINI2 format, an ISO19139 profile used by the UK Location Programme, and the logic for creating or updating datasets and the resulting fields were somehow adapted to the needs for this particular project. The harvesters were still generic enough and should work fine with other ISO19139 based sources, but extra care has been put to make the new harvesters more generic and robust, so these ones should only be used on existing instances: - - * ``gemini_csw_harvester`` - * ``gemini_waf_harvester`` - * ``gemini_doc_harvester`` - -If you are using these harvesters please consider upgrading to the new versions described on the previous section. - -.. _ckanext-harvest: https://github.com/okfn/ckanext-harvest - -Harvest Metadata API --------------------- - -Enabled with the ``ckan.plugins = spatial_harvest_metadata_api`` (previous known as ``inspire_api``) - -To view the harvest objects (containing the harvested metadata) in the web interface, these controller locations are added: - -* raw XML document: /harvest/object/{id} -* HTML representation: /harvest/object/{id}/html - -.. note:: - The old URLs are now deprecated and redirect to the previously defined. - - /api/2/rest/harvestobject//xml - /api/2/rest/harvestobject//html - - -For those harvest objects that have an original document (which was transformed to ISO), this can be accessed via: - -* raw XML document: /harvest/object/{id}/original -* HTML representation: /harvest/object/{id}/html/original - -The HTML representation is created via an XSLT transformation. The extension provides an XSLT file that should work -on ISO 19139 based documents, but if you want to use your own on your extension, you can override it using -the following configuration options:: - - ckanext.spatial.harvest.xslt_html_content = ckanext.myext:templates/xslt/custom.xslt - ckanext.spatial.harvest.xslt_html_content_original = ckanext.myext:templates/xslt/custom2.xslt - -If your project does not transform different metadata types you can ignore the second option. - - -CSW Client ----------- - -CswService is a client for python software (such as the CSW Harvester in ckanext-inspire) to conveniently access a CSW server, using the same three methods as the CSW Server supports. It is a wrapper around OWSLib's tool, dealing with the details of the calls and responses to make it very convenient to use, whereas OWSLib on its own is more complicated. - -Validators ----------- - -This library can validate metadata records. It currently supports ISO19139 / INSPIRE / GEMINI2 formats, validating them with XSD and Schematron schemas. It is easily extensible. - -To specify which validators to use during harvesting, specify their names in CKAN config. e.g.:: - - ckan.spatial.validator.profiles = iso19139,gemini2,constraints - - -cswinfo -------- - -The command-line tool ``cswinfo`` allows to make queries on CSW servers and returns the info in nicely formatted JSON. This may be more convenient to type than using, for example, curl. - -Currently available queries are: - * getcapabilities - * getidentifiers - * getrecords - * getrecordbyid - -For details, type:: - - cswinfo csw -h - -There are options for querying by only certain types, keywords and typenames as well as configuring the ElementSetName. - -The equivalent example to the one above for asking the cabailities is:: - - $ cswinfo csw getcapabilities http://127.0.0.1:5000/csw - -OWSLib is the library used to actually perform the queries. - -Validator +Community --------- -This python library uses Schematron and other schemas to validate the XML. +* Developer mailing list: `ckan-dev@lists.okfn.org `_ +* Developer IRC channel: `#ckan on irc.freenode.net `_ +* `Issue tracker `_ -Here is a simple example of using the Validator library:: - from ckanext.csw.validation import Validator - xml = etree.fromstring(gemini_string) - validator = Validator(profiles=('iso19139', 'gemini2', 'constraints')) - valid, messages = validator.isvalid(xml) - if not valid: - print "Validation error: " + messages[0] + ':\n' + '\n'.join(messages[1:]) +Contributing +------------ -In DGU, the Validator is integrated here: -https://github.com/okfn/ckanext-inspire/blob/master/ckanext/inspire/harvesters.py#L88 +For contributing to ckanext-spatial or its documentation, follow the same +guidelines that apply to CKAN core, described in +`CONTRIBUTING `_. -NOTE: The ISO19139 XSD Validator requires system library ``libxml2`` v2.9 (released Sept 2012). If you intend to use this validator then see the section below about installing libxml2. +Copying and License +------------------- -Setup -===== +This material is copyright (c) 2006-2011 Open Knowledge Foundation. -Install Python --------------- +It is open and licensed under the GNU Affero General Public License (AGPL) v3.0 +whose full text may be found at: -1. Install this extension into your python environment (where CKAN is also installed). +http://www.fsf.org/licensing/licenses/agpl-3.0.html - *Note:* Depending on the CKAN core version you are targeting you will need to - use a different branch from the extension. +.. _CKAN: http://ckan.org +.. _PostGIS: http://postgis.org +.. _GeoJSON: http://geojson.org - For a production site, use the `stable` branch, unless there is a specific - branch that targets the CKAN core version that you are using. - - To target the latest CKAN core release:: - - (pyenv) $ pip install -e git+https://github.com/okfn/ckanext-spatial.git@stable#egg=ckanext-spatial - - To target an old release (if a release branch exists, otherwise use `stable`):: - - (pyenv) $ pip install -e git+https://github.com/okfn/ckanext-spatial.git@release-v1.8#egg=ckanext-spatial - - To target CKAN `master`, use the extension `master` branch (ie no branch defined):: - - (pyenv) $ pip install -e git+https://github.com/okfn/ckanext-spatial.git#egg=ckanext-spatial - - ``cswserver`` requires that ckanext-harvest is also installed (and enabled) - see https://github.com/okfn/ckanext-harvest - -2. Install the rest of python modules required by the extension:: - - (pyenv) $ pip install -r pip-requirements.txt - -Install System Packages ------------------------ - -There are also some system packages that are required: - -* PostGIS must be installed and the database needs spatial features enabling to be able to use Spatial Search. See the `Setting up PostGIS`_ section for details. - -* Shapely requires libgeos to be installed. If you installed PostGIS on - the same machine you have already got it, but if PostGIS is located on another server - you will need to install GEOS on it:: - - sudo apt-get install libgeos-c1 - -* The Validator for ISO19139 requires the install of a particular version of libxml2 - see "Installing libxml2" for full details. - -Configuration -------------- - -Once PostGIS is installed and configured in your database (see the "Setting up PostGIS" section for details), you need to create some DB tables for the spatial search, by running the following command (with your python env activated):: - - (pyenv) $ paster --plugin=ckanext-spatial spatial initdb [srid] --config=mysite.ini - -You can define the SRID of the geometry column. Default is 4326. If you -are not familiar with projections, we recommend to use the default value. - -Check the Troubleshooting_ section if you get errors at this stage. - -Each plugin can be enabled by adding its name to the ``ckan.plugins`` in the CKAN ini file. For example:: - - ckan.plugins = spatial_metadata spatial_query wms_preview - -**Note:** Plugin ``spatial_query`` depends on the ``spatial_metadata`` plugin also being enabled. - -When enabling the spatial metadata, you can define the projection -in which extents are stored in the database with the following option. Use -the EPSG code as an integer (e.g 4326, 4258, 27700, etc). It defaults to -4326:: - - ckan.spatial.srid = 4326 - - -Configuration - CSW Server --------------------------- - -.. note:: **Deprecated:** The old csw plugin has been deprecated, please see `ckan-pycsw`_ - for details on how to integrate with pycsw. - -Configure the CSW Server with the following keys in your CKAN config file (default values are shown):: - - cswservice.title = Untitled Service - set cswservice.title in config - cswservice.abstract = Unspecified service description - set cswservice.abstract in config - cswservice.keywords = - cswservice.keyword_type = theme - cswservice.provider_name = Unnamed provider - set cswservice.provider_name in config - cswservice.contact_name = No contact - set cswservice.contact_name in config - cswservice.contact_position = - cswservice.contact_voice = - cswservice.contact_fax = - cswservice.contact_address = - cswservice.contact_city = - cswservice.contact_region = - cswservice.contact_pcode = - cswservice.contact_country = - cswservice.contact_email = - cswservice.contact_hours = - cswservice.contact_instructions = - cswservice.contact_role = - cswservice.rndlog_threshold = 0.01 - cswservice.log_xml_length = 1000 - -cswservice.rndlog_threshold is the percentage of interactions to store in the log file. - - - -SOLR Configuration ------------------- - -If using Spatial Query functionality then there is an additional SOLR/Lucene setting that should be used to set the limit on number of datasets searchable with a spatial value. - -The setting is ``maxBooleanClauses`` in the solrconfig.xml and the value is the number of datasets spatially searchable. The default is ``1024`` and this could be increased to say ``16384``. For a SOLR single core this will probably be at ``/etc/solr/conf/solrconfig.xml``. For a multiple core set-up, there will me several solrconfig.xml files a couple of levels below ``/etc/solr``. For that case, *all* of the cores' ``solrconfig.xml`` should have this setting at the new value. - -Example:: - - 16384 - -This setting is needed because PostGIS spatial query results are fed into SOLR using a Boolean expression, and the parser for that has a limit. So if your spatial area contains more than the limit (of which the default is 1024) then you will get this error:: - - Dataset search error: ('SOLR returned an error running query... - -and in the SOLR logs you see:: - - too many boolean clauses - ... - Caused by: org.apache.lucene.search.BooleanQuery$TooManyClauses: - maxClauseCount is set to 1024 - - -Troubleshooting -=============== - -Here are some common problems you may find when installing or using the -extension: - -* When initializing the spatial tables:: - - LINE 1: SELECT AddGeometryColumn('package_extent','the_geom', E'4326... - ^ - HINT: No function matches the given name and argument types. You might need to add explicit type casts. - "SELECT AddGeometryColumn('package_extent','the_geom', %s, 'GEOMETRY', 2)" ('4326',) - - - PostGIS was not installed correctly. Please check the "Setting up PostGIS" section. - :: - - sqlalchemy.exc.ProgrammingError: (ProgrammingError) permission denied for relation spatial_ref_sys - - - The user accessing the ckan database needs to be owner (or have permissions) of the geometry_columns and spatial_ref_sys tables. - -* When performing a spatial query:: - - InvalidRequestError: SQL expression, column, or mapped entity expected - got '' - - The spatial model has not been loaded. You probably forgot to add the ``spatial_metadata`` plugin to your ini configuration file. - :: - - InternalError: (InternalError) Operation on two geometries with different SRIDs - - The spatial reference system of the database geometry column and the one used by CKAN differ. Remember, if you are using a different spatial reference system from the default one (WGS 84 lat/lon, EPSG:4326), you must define it in the configuration file as follows:: - - ckan.spatial.srid = 4258 - -Tests -===== - -All of the tests need access to the spatial model in Postgres, so to run the tests, specify ``test-core.ini``:: - - (pyenv) $ nosetests --ckan --with-pylons=test-core.ini -l ckanext ckanext/spatial/tests - -In some places in this extension, ALL exceptions get caught and reported as errors. Since these could be basic coding errors, to aid debugging these during development, you can request exceptions are reraised by setting the DEBUG environment variable:: - - export DEBUG=1 - -Command line interface -====================== - -The following operations can be run from the command line using the -``paster spatial`` command:: - - initdb [srid] - - Creates the necessary tables. You must have PostGIS installed - and configured in the database. - You can privide the SRID of the geometry column. Default is 4326. - - extents - - creates or updates the extent geometry column for datasets with - an extent defined in the 'spatial' extra. - -The commands should be run from the ckanext-spatial directory and expect -a development.ini file to be present. Most of the time you will specify -the config explicitly though:: - - paster spatial extents --config=../ckan/development.ini - - -Setting up PostGIS -================== - -PostGIS Configuration ---------------------- - -* Install PostGIS:: - - sudo apt-get install postgresql-8.4-postgis - - (or ``postgresql-9.1-postgis``, depending on your postgres version) - -* Create a new PostgreSQL database:: - - sudo -u postgres createdb [database] - - (If you just want to spatially enable an exisiting database, you can - ignore this point, but it's a good idea to create a template to - make easier to create new databases) - -* Many of the PostGIS functions are written in the PL/pgSQL language, - so we need to enable it in our database:: - - sudo -u postgres createlang plpgsql [database] - -* Run the following commands. The first one will create the necessary - tables and functions in the database, and the second will populate - the spatial reference table:: - - sudo -u postgres psql -d [database] -f /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql - sudo -u postgres psql -d [database] -f /usr/share/postgresql/8.4/contrib/postgis-1.5/spatial_ref_sys.sql - - **Note**: depending on your distribution and PostGIS version, the - scripts may be located on a slightly different location, e.g.:: - - /usr/share/postgresql/8.4/contrib/postgis.sql - -* Execute the following command to see if PostGIS was properly - installed:: - - sudo -u postgres psql -d [database] -c "SELECT postgis_full_version()" - - You should get something like:: - - postgis_full_version - ------------------------------------------------------------------------------------------------------ - POSTGIS="1.5.2" GEOS="3.2.2-CAPI-1.6.2" PROJ="Rel. 4.7.1, 23 September 2009" LIBXML="2.7.7" USE_STATS - (1 row) - - Also, if you log into the database, you should see two tables, - ``geometry_columns`` and ``spatial_ref_sys`` (and probably a view - called ``geography_columns``). - - Note: This commands will create the two tables owned by the postgres - user. You probably should make owner the user that will access the - database from ckan:: - - ALTER TABLE spatial_ref_sys OWNER TO [your_user]; - ALTER TABLE geometry_columns OWNER TO [your_user]; - -More information on PostGIS installation can be found here: - -http://postgis.refractions.net/docs/ch02.html#PGInstall - -Migrating to an existing PostGIS database ------------------------------------------ - -If you are loading a database dump to an existing PostGIS database, you may -find errors like :: - - ERROR: type "spheroid" already exists - -This means that the PostGIS functions are installed, but you may need to -create the necessary tables anyway. You can force psql to ignore these -errors and continue the transaction with the ON_ERROR_ROLLBACK=on:: - - sudo -u postgres psql -d [database] -f /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql -v ON_ERROR_ROLLBACK=on - -You will still need to populate the spatial_ref_sys table and change the -tables permissions. Refer to the previous section for details on how to do -it. - - -Setting up a spatial table --------------------------- - -**Note:** If you run the ``initdb`` command, the table was already created for -you. This section just describes what's going on for those who want to know -more. - -To be able to store geometries and perform spatial operations, PostGIS -needs to work with geometry fields. Geometry fields should always be -added via the ``AddGeometryColumn`` function:: - - CREATE TABLE package_extent( - package_id text PRIMARY KEY - ); - - ALTER TABLE package_extent OWNER TO [your_user]; - - SELECT AddGeometryColumn('package_extent','the_geom', 4326, 'GEOMETRY', 2); - -This will add a geometry column in the ``package_extent`` table called -``the_geom``, with the spatial reference system EPSG:4326. The stored -geometries will be polygons, with 2 dimensions (The actual table on CKAN -uses the GEOMETRY type to support multiple geometry types). - -Have a look a the table definition, and see how PostGIS has created -three constraints to ensure that the geometries follow the parameters -defined in the geometry column creation:: - - # \d package_extent - - Table "public.package_extent" - Column | Type | Modifiers - ------------+----------+----------- - package_id | text | not null - the_geom | geometry | - Indexes: - "package_extent_pkey" PRIMARY KEY, btree (package_id) - Check constraints: - "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2) - "enforce_srid_the_geom" CHECK (st_srid(the_geom) = 4326) - -Installing libxml2 -================== - -Version 2.9 is required for the ISO19139 XSD validation. - -With CKAN you would probably have installed an older version from your distribution. (e.g. with ``sudo apt-get install libxml2-dev``). You need to find the SO files for the old version:: - - $ find /usr -name "libxml2.so" - -For example, it may show it here: ``/usr/lib/x86_64-linux-gnu/libxml2.so``. The directory of the SO file is used as a parameter to the ``configure`` next on. - -Download the libxml2 source:: - - $ cd ~ - $ wget ftp://xmlsoft.org/libxml2/libxml2-2.9.0.tar.gz - -Unzip it:: - - $ tar zxvf libxml2-2.9.0.tar.gz - $ cd libxml2-2.9.0/ - -Configure with the SO directory you found before:: - - $ ./configure --libdir=/usr/lib/x86_64-linux-gnu - -Now make it and install it:: - - $ make - $ sudo make install - -Now check the install by running xmllint:: - - $ xmllint --version - xmllint: using libxml version 20900 - compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP DTDValid HTML Legacy C14N Catalog XPath XPointer XInclude Iconv ISO8859X Unicode Regexps Automata Expr Schemas Schematron Modules Debug Zlib - -Licence -======= - -This code falls under different copyrights, depending on when it was contributed and by whom:: -* (c) Copyright 2011-2012 Open Knowledge Foundation -* Crown Copyright -* XML/XSD files: copyright of their respective owners, held in the files themselves - -All of this code is licensed for reuse under the Open Government Licence -http://www.nationalarchives.gov.uk/doc/open-government-licence/ From 75e795e1bc99d5e638e374d21bd3464f7bc9b2fe Mon Sep 17 00:00:00 2001 From: amercader Date: Mon, 9 Sep 2013 09:45:44 +0100 Subject: [PATCH 073/114] [#39] README tweaks --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index f9abb71..4b5b294 100644 --- a/README.rst +++ b/README.rst @@ -14,9 +14,9 @@ including: * Commands to support the CSW standard. * Plugins to preview spatial formats such as GeoJSON_. -Full documentation, including installation instructions can be found at: +Full documentation, including installation instructions, can be found at: - http://docs.ckan.org/projects/ckanext-spatial +http://docs.ckan.org/projects/ckanext-spatial Community From c1fe37647f1bb9b3a45f70735e76de0c0fb11965 Mon Sep 17 00:00:00 2001 From: fxia Date: Mon, 9 Sep 2013 14:47:14 -0400 Subject: [PATCH 074/114] change progress multiplicity to * --- ckanext/spatial/harvesters/base.py | 5 ++++- ckanext/spatial/harvesters/gemini.py | 6 +++++- ckanext/spatial/model/harvested_metadata.py | 2 +- ckanext/spatial/tests/test_harvest.py | 1 + 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ckanext/spatial/harvesters/base.py b/ckanext/spatial/harvesters/base.py index b01d022..245ead6 100644 --- a/ckanext/spatial/harvesters/base.py +++ b/ckanext/spatial/harvesters/base.py @@ -234,11 +234,14 @@ class SpatialHarvester(HarvesterBase): 'coupled-resource', 'contact-email', 'frequency-of-update', - 'progress', 'spatial-data-service-type', ]: extras[name] = iso_values[name] + if len(iso_values.get('progress', [])): + extras['progress'] = iso_values['progress'][0] + else: + extras['progress'] = '' if len(iso_values.get('resource-type', [])): extras['resource-type'] = iso_values['resource-type'][0] diff --git a/ckanext/spatial/harvesters/gemini.py b/ckanext/spatial/harvesters/gemini.py index e9bcd9e..e293376 100644 --- a/ckanext/spatial/harvesters/gemini.py +++ b/ckanext/spatial/harvesters/gemini.py @@ -200,11 +200,15 @@ class GeminiHarvester(SpatialHarvester): 'coupled-resource', 'contact-email', 'frequency-of-update', - 'progress', 'spatial-data-service-type', ]: extras[name] = gemini_values[name] + if len(iso_values.get('progress', [])): + extras['progress'] = iso_values['progress'][0] + else: + extras['progress'] = '' + extras['resource-type'] = gemini_values['resource-type'][0] # Use-constraints can contain values which are: diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index cf02467..0b424b1 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -489,7 +489,7 @@ class ISODocument(MappedXmlDocument): "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:status/gmd:MD_ProgressCode/text()", "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:status/gmd:MD_ProgressCode/text()", ], - multiplicity="0..1", + multiplicity="*", ), ISOElement( name="keyword-inspire-theme", diff --git a/ckanext/spatial/tests/test_harvest.py b/ckanext/spatial/tests/test_harvest.py index 3deda2a..559a089 100644 --- a/ckanext/spatial/tests/test_harvest.py +++ b/ckanext/spatial/tests/test_harvest.py @@ -329,6 +329,7 @@ class TestHarvest(HarvestFixtureBase): 'spatial': u'{"type": "Polygon", "coordinates": [[[0.205857204, 54.529947158], [0.205857204, 61.06066944], [-8.97114288, 61.06066944], [-8.97114288, 54.529947158], [0.205857204, 54.529947158]]]}', # Other 'coupled-resource': u'[]', + 'progress': u'["completed"]', 'dataset-reference-date': u'[{"type": "creation", "value": "2004-02"}, {"type": "revision", "value": "2006-07-03"}]', 'frequency-of-update': u'irregular', 'licence': u'["Reference and PSMA Only", "http://www.test.gov.uk/licenseurl"]', From f7f1a72df8282528f9950ced1f70d6c1c3e78525 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 10 Sep 2013 11:08:06 +0100 Subject: [PATCH 075/114] Remove progress field from tests --- ckanext/spatial/tests/test_harvest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ckanext/spatial/tests/test_harvest.py b/ckanext/spatial/tests/test_harvest.py index 559a089..3deda2a 100644 --- a/ckanext/spatial/tests/test_harvest.py +++ b/ckanext/spatial/tests/test_harvest.py @@ -329,7 +329,6 @@ class TestHarvest(HarvestFixtureBase): 'spatial': u'{"type": "Polygon", "coordinates": [[[0.205857204, 54.529947158], [0.205857204, 61.06066944], [-8.97114288, 61.06066944], [-8.97114288, 54.529947158], [0.205857204, 54.529947158]]]}', # Other 'coupled-resource': u'[]', - 'progress': u'["completed"]', 'dataset-reference-date': u'[{"type": "creation", "value": "2004-02"}, {"type": "revision", "value": "2006-07-03"}]', 'frequency-of-update': u'irregular', 'licence': u'["Reference and PSMA Only", "http://www.test.gov.uk/licenseurl"]', From a19010d8e56883347a45864227fa32bafc354396 Mon Sep 17 00:00:00 2001 From: fxia Date: Tue, 10 Sep 2013 10:57:15 -0400 Subject: [PATCH 076/114] for progress, use gemini_values not iso_values --- ckanext/spatial/harvesters/gemini.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ckanext/spatial/harvesters/gemini.py b/ckanext/spatial/harvesters/gemini.py index e293376..52faff6 100644 --- a/ckanext/spatial/harvesters/gemini.py +++ b/ckanext/spatial/harvesters/gemini.py @@ -204,8 +204,8 @@ class GeminiHarvester(SpatialHarvester): ]: extras[name] = gemini_values[name] - if len(iso_values.get('progress', [])): - extras['progress'] = iso_values['progress'][0] + if len(gemini_values.get('progress', [])): + extras['progress'] = gemini_values['progress'][0] else: extras['progress'] = '' From 2f28c8c5c7a1a94b25752f94528fce7f2e105dc0 Mon Sep 17 00:00:00 2001 From: amercader Date: Sun, 6 Oct 2013 23:18:59 +0100 Subject: [PATCH 077/114] [#37] Add support for MapBox tiles and others The common map function has been extended to allow configuring different options for the base layer. There are default presets for MapQuest and MapBox, but any XYZ layer can be added configuration options. The options are passed to the templates via a helper function and to the js modules via data-module attributes. Full docs included. --- ckanext/spatial/helpers.py | 10 ++ ckanext/spatial/nongeos_plugin.py | 13 ++ ckanext/spatial/plugin.py | 1 + ckanext/spatial/public/js/common_map.js | 58 +++++--- ckanext/spatial/public/js/dataset_map.js | 2 +- ckanext/spatial/public/js/geojson_preview.js | 2 +- ckanext/spatial/public/js/spatial_query.js | 2 +- .../spatial/templates/dataviewer/geojson.html | 3 +- .../spatial/snippets/dataset_map_base.html | 7 +- .../spatial/snippets/map_attribution.html | 7 + .../spatial/snippets/spatial_query.html | 6 +- doc/_static/base-map-mapbox.png | Bin 0 -> 204132 bytes doc/_static/base-map-mapquest.png | Bin 0 -> 226658 bytes doc/index.rst | 1 + doc/map-widgets.rst | 131 ++++++++++++++++++ 15 files changed, 216 insertions(+), 27 deletions(-) create mode 100644 ckanext/spatial/templates/spatial/snippets/map_attribution.html create mode 100644 doc/_static/base-map-mapbox.png create mode 100644 doc/_static/base-map-mapquest.png create mode 100644 doc/map-widgets.rst diff --git a/ckanext/spatial/helpers.py b/ckanext/spatial/helpers.py index 2368b0f..f27d000 100644 --- a/ckanext/spatial/helpers.py +++ b/ckanext/spatial/helpers.py @@ -1,4 +1,6 @@ import logging +from pylons import config + from ckan import plugins as p from ckan.lib import helpers as h @@ -56,3 +58,11 @@ def get_responsible_party(value): return '; '.join(out) except (ValueError, TypeError): return value + +def get_common_map_config(): + ''' + Returns a dict with all configuration options related to the common + base map (ie those starting with 'ckanext.spatial.common_map.') + ''' + namespace = 'ckanext.spatial.common_map.' + return dict([(k.replace(namespace, ''), v) for k, v in config.iteritems() if k.startswith(namespace)]) diff --git a/ckanext/spatial/nongeos_plugin.py b/ckanext/spatial/nongeos_plugin.py index a1baeeb..a66bf73 100644 --- a/ckanext/spatial/nongeos_plugin.py +++ b/ckanext/spatial/nongeos_plugin.py @@ -55,6 +55,7 @@ class WMSPreview(p.SingletonPlugin): class GeoJSONPreview(p.SingletonPlugin): p.implements(p.IConfigurer, inherit=True) p.implements(p.IResourcePreview, inherit=True) + p.implements(p.ITemplateHelpers, inherit=True) GeoJSON = ['gjson', 'geojson'] @@ -100,3 +101,15 @@ class GeoJSONPreview(p.SingletonPlugin): def preview_template(self, context, data_dict): return 'dataviewer/geojson.html' + + ## ITemplateHelpers + + def get_helpers(self): + from ckanext.spatial import helpers as spatial_helpers + + # CKAN does not allow to define two helpers with the same name + # As this plugin can be loaded independently of the main spatial one + # We define a different helper pointing to the same function + return { + 'get_common_map_config_geojson' : spatial_helpers.get_common_map_config, + } diff --git a/ckanext/spatial/plugin.py b/ckanext/spatial/plugin.py index 9131337..daca6b8 100644 --- a/ckanext/spatial/plugin.py +++ b/ckanext/spatial/plugin.py @@ -114,6 +114,7 @@ class SpatialMetadata(p.SingletonPlugin): return { 'get_reference_date' : spatial_helpers.get_reference_date, 'get_responsible_party': spatial_helpers.get_responsible_party, + 'get_common_map_config' : spatial_helpers.get_common_map_config, } class SpatialQuery(p.SingletonPlugin): diff --git a/ckanext/spatial/public/js/common_map.js b/ckanext/spatial/public/js/common_map.js index 8b326d1..37d35ba 100644 --- a/ckanext/spatial/public/js/common_map.js +++ b/ckanext/spatial/public/js/common_map.js @@ -5,36 +5,60 @@ * All Leaflet based maps should use this constructor to provide consistent * look and feel and avoid duplication. * - * container - HTML element or id of the map container - * mapOptions - (Optional) Options to pass to the map constructor - * baseLayerOptions - (Optional) Options to pass to the base layer constructor + * container - HTML element or id of the map container + * mapConfig - (Optional) CKAN config related to the base map. + * These are defined in the config ini file (eg + * map type, API keys if necessary, etc). + * leafletMapOptions - (Optional) Options to pass to the Leaflet Map constructor + * leafletBaseLayerOptions - (Optional) Options to pass to the Leaflet TileLayer constructor * * Examples * * // Will return a map with attribution control - * var map = ckan.commonLeafletMap('map'); + * var map = ckan.commonLeafletMap('map', mapConfig); * * // For smaller maps where the attribution is shown outside the map, pass * // the following option: - * var map = ckan.commonLeafletMap('map', {attributionControl: false}); + * var map = ckan.commonLeafletMap('map', mapConfig, {attributionControl: false}); * * Returns a Leaflet map object. */ - ckan.commonLeafletMap = function (container, mapOptions, baseLayerOptions) { - - var mapOptions = mapOptions || {}; - var baseLayerOptions = jQuery.extend(baseLayerOptions, { - maxZoom: 18, - attribution: 'Map data © OpenStreetMap contributors' + ckan.commonLeafletMap = function (container, + mapConfig, + leafletMapOptions, + leafletBaseLayerOptions) { + + var mapConfig = mapConfig || {type: 'mapquest'}; + var leafletMapOptions = leafletMapOptions || {}; + var leafletBaseLayerOptions = jQuery.extend(leafletBaseLayerOptions, { + maxZoom: 18 }); - map = new L.Map(container, mapOptions); + map = new L.Map(container, leafletMapOptions); - // MapQuest OpenStreetMap base map - baseLayerUrl = '//otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png'; - baseLayerOptions.subdomains = '1234'; - baseLayerOptions.attribution += ', Tiles Courtesy of MapQuest '; - var baseLayer = new L.TileLayer(baseLayerUrl, baseLayerOptions); + if (mapConfig.type == 'mapbox') { + // MapBox base map + if (!mapConfig['mapbox.map_id']) { + throw '[CKAN Map Widgets] You need to provide a map ID ([account].[handle]) when using a MapBox layer. ' + + 'See http://www.mapbox.com/developers/api-overview/ for details'; + } + baseLayerUrl = '//{s}.tiles.mapbox.com/v3/{handle}/{z}/{x}/{y}.png'; + leafletBaseLayerOptions.handle = mapConfig['mapbox.map_id']; + leafletBaseLayerOptions.subdomains = mapConfig.subdomains || 'abcd'; + leafletBaseLayerOptions.attribution = mapConfig.attribution || 'Map data © OpenStreetMap contributors, Tiles Courtesy of MapBox'; + } else if (mapConfig.type == 'custom') { + // Custom XYZ layer + baseLayerUrl = mapConfig['custom.url']; + if (mapConfig.subdomains) leafletBaseLayerOptions.subdomains = mapConfig.subdomains; + leafletBaseLayerOptions.attribution = mapConfig.attribution; + } else { + // MapQuest OpenStreetMap base map + baseLayerUrl = '//otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png'; + leafletBaseLayerOptions.subdomains = mapConfig.subdomains || '1234'; + leafletBaseLayerOptions.attribution = mapConfig.attribution || 'Map data © OpenStreetMap contributors, Tiles Courtesy of MapQuest '; + } + + var baseLayer = new L.TileLayer(baseLayerUrl, leafletBaseLayerOptions); map.addLayer(baseLayer); return map; diff --git a/ckanext/spatial/public/js/dataset_map.js b/ckanext/spatial/public/js/dataset_map.js index 4f28d06..90c3988 100644 --- a/ckanext/spatial/public/js/dataset_map.js +++ b/ckanext/spatial/public/js/dataset_map.js @@ -41,7 +41,7 @@ this.ckan.module('dataset-map', function (jQuery, _) { return false; } - map = ckan.commonLeafletMap('dataset-map-container', {attributionControl: false}); + map = ckan.commonLeafletMap('dataset-map-container', this.options.map_config, {attributionControl: false}); var ckanIcon = L.Icon.extend({options: this.options.styles.point}); diff --git a/ckanext/spatial/public/js/geojson_preview.js b/ckanext/spatial/public/js/geojson_preview.js index 33b2ddd..2af7879 100644 --- a/ckanext/spatial/public/js/geojson_preview.js +++ b/ckanext/spatial/public/js/geojson_preview.js @@ -18,7 +18,7 @@ ckan.module('geojsonpreview', function (jQuery, _) { self.el.empty(); self.el.append($("
").attr("id","map")); - self.map = ckan.commonLeafletMap('map'); + self.map = ckan.commonLeafletMap('map', this.options.map_config); // hack to make leaflet use a particular location to look for images L.Icon.Default.imagePath = this.options.site_url + 'js/vendor/leaflet/images'; diff --git a/ckanext/spatial/public/js/spatial_query.js b/ckanext/spatial/public/js/spatial_query.js index dbdd0d5..0aed44e 100644 --- a/ckanext/spatial/public/js/spatial_query.js +++ b/ckanext/spatial/public/js/spatial_query.js @@ -86,7 +86,7 @@ this.ckan.module('spatial-query', function ($, _) { }); // OK map time - map = ckan.commonLeafletMap('dataset-map-container', {attributionControl: false}); + map = ckan.commonLeafletMap('dataset-map-container', this.options.map_config, {attributionControl: false}); // Initialize the draw control map.addControl(new L.Control.Draw({ diff --git a/ckanext/spatial/templates/dataviewer/geojson.html b/ckanext/spatial/templates/dataviewer/geojson.html index db1c6bd..1620889 100644 --- a/ckanext/spatial/templates/dataviewer/geojson.html +++ b/ckanext/spatial/templates/dataviewer/geojson.html @@ -5,7 +5,8 @@ {% resource g.main_css[6:] %} {% endblock %} -
+ {% set map_config = h.get_common_map_config_geojson() %} +

{{ _('Loading...') }}
diff --git a/ckanext/spatial/templates/spatial/snippets/dataset_map_base.html b/ckanext/spatial/templates/spatial/snippets/dataset_map_base.html index 0bb9df4..2d42230 100644 --- a/ckanext/spatial/templates/spatial/snippets/dataset_map_base.html +++ b/ckanext/spatial/templates/spatial/snippets/dataset_map_base.html @@ -9,11 +9,12 @@ extent {% snippet "spatial/snippets/dataset_map_base.html", extent=extent %} #} -
+ +{% set map_config = h.get_common_map_config() %} +
-
Map data CC-BY-SA by OpenStreetMap
-
Tiles by MapQuest
+ {% snippet "spatial/snippets/map_attribution.html", map_config=map_config %}
diff --git a/ckanext/spatial/templates/spatial/snippets/map_attribution.html b/ckanext/spatial/templates/spatial/snippets/map_attribution.html new file mode 100644 index 0000000..cb40429 --- /dev/null +++ b/ckanext/spatial/templates/spatial/snippets/map_attribution.html @@ -0,0 +1,7 @@ +
Map data CC-BY-SA by OpenStreetMap
+{% if map_config.type == 'mapbox' %} +
Tiles by MapBox
+{% else %} +
Tiles by MapQuest
+{% endif %} + diff --git a/ckanext/spatial/templates/spatial/snippets/spatial_query.html b/ckanext/spatial/templates/spatial/snippets/spatial_query.html index aa92c6c..f847f06 100644 --- a/ckanext/spatial/templates/spatial/snippets/spatial_query.html +++ b/ckanext/spatial/templates/spatial/snippets/spatial_query.html @@ -17,12 +17,12 @@ e.g. {{ _('Filter by location') }} {{ _('Clear') }}

-
+ {% set map_config = h.get_common_map_config() %} +
-
Map data CC-BY-SA by OpenStreetMap
-
Tiles by MapQuest
+ {% snippet "spatial/snippets/map_attribution.html", map_config=map_config %}
diff --git a/doc/_static/base-map-mapbox.png b/doc/_static/base-map-mapbox.png new file mode 100644 index 0000000000000000000000000000000000000000..1c5f28ec4d090dce584adf4999591c6329576aee GIT binary patch literal 204132 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

y3I5j>s!iK2#TVu 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

VJd%8MhM3S6r((#MMeTm?m4 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ƻ_jpPpzC_NHi{g) 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

P z2Q7JS2cB9-u0eHQe?(lPMvWRZYCK=CR)4g1q1oZNJ+S?KS$isiU7N_Zc0Alqv5;$) z%o!*Aul4?GjT$v-)OfzGU{AJH+Am$tz6H73Z?%G5yEI-)yamr44cGRZ8Z~OvsPTLy zS#y#FXP;=l?LO?c6FHS@?&~j;Jx+{<*REV^lC4prMvWTJ7jlJ@dt!@qx8IS-sXr#} zlk0jG??1Ra$;!1R*BUiy)Tr@%C0TQl)$ICI!@nbR`gTDR>lu9QsH09HlO{TeZ*!kG1)+r$6> literal 0 HcmV?d00001 diff --git a/doc/_static/base-map-mapquest.png b/doc/_static/base-map-mapquest.png new file mode 100644 index 0000000000000000000000000000000000000000..2f62b2be9a0f897c52d0d6c3ca9d012cfeec8c26 GIT binary patch literal 226658 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 literal 0 HcmV?d00001 diff --git a/doc/index.rst b/doc/index.rst index 9a6010f..ef77ae8 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -25,6 +25,7 @@ Contents: harvesters csw previews + map-widgets .. _CKAN: http://ckan.org .. _CKAN Documentation: http://docs.ckan.org diff --git a/doc/map-widgets.rst b/doc/map-widgets.rst new file mode 100644 index 0000000..fd17128 --- /dev/null +++ b/doc/map-widgets.rst @@ -0,0 +1,131 @@ +Common base layers for Map Widgets +================================== + +To provide a consistent look and feel and avoiding code duplication, the map +widgets (at least the ones based on `Leaflet`_) can use a common function to +create the map. The base layer that the map will use can be configured via +configuration options. + +Configuring the base layer +-------------------------- + +The main configuration option to manage the base layer used is +``ckanext.spatial.common_map.type``. Depending on the map type additional +options may be required. The spatial extension provides default settings for +popular tiles providers based on `OpenStreetMap`_, but you can use any tileset +that follows the `XYZ convention`_. + + +.. note:: All tile providers have Terms of Use and will most likely require + proper attribution. Make sure to read and understand the terms and add + the relevant attribution before using them on your CKAN instance. + +MapQuest-OSM +++++++++++++ + +The `MapQuest-OSM`_ tiles are provided by `MapQuest`_, and are based on data by +OpenStreetMap. This is the default base layer used by the map widgets, and you +don't need to add any configuration option to use them. If you want to define +it explicitly though, use the following setting:: + + ckanext.spatial.common_map.type = mapquest + +.. image:: _static/base-map-mapquest.png + +MapBox +++++++ + +MapBox`_ allows to define your custom maps based on OpenStreetMap data, using +their online editor or the more advanced `TileMill`_ desktop tool. You will +need to provide a map id with the ``[account].[handle]`` form (Check `here`_ +for more details):: + + ckanext.spatial.common_map.type = mapbox + ckanext.spatial.common_map.mapbox.map_id = youraccount.map-xxxxxxxx + +.. image:: _static/base-map-mapbox.png + +Custom +++++++ + +You can use any tileset that follows the `XYZ convention`_ using the ``custom`` +type:: + + ckanext.spatial.common_map.type = custom + +You will need to define the tileset URL using +``ckanext.spatial.common_map.custom.url``. This follows the `Leaflet URL +template`_ format (ie {s} for subdomains if any, {z} for zoom and {x} {y} for +tile coordinates). Additionally you can use +``ckanext.spatial.common_map.subdomains`` and +``ckanext.spatial.common_map.attribution`` if needed (these two will also work +for MapQuest and MapBox layers if you want to tweak the defaults. + +This is a complete example that uses `Stamen`_'s famous `watercolor maps`_:: + + ckanext.spatial.common_map.type = custom + ckanext.spatial.common_map.custom.url = http://tile.stamen.com/watercolor/{z}/{x}/{y}.jpg + ckanext.spatial.common_map.attribution = Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA. + +.. note:: For custom base layers you need to manually modify the attribution + link on the templates for widgets on the sidebar, like the spatial query + and dataset map widgets. + + + +For developers +-------------- + +To pass the base map configuration options to the relevant Javascript module +that will initialize the map widget, use the ``h.get_common_map_config()`` +helper function. This is available when loading the ``spatial_metadata`` +plugin. If you don't want to require this plugin, create a new helper function +that points to it to avoid duplicating the names, which CKAN won't allow (see +for instance how the GeoJSON preview plugin does it). + +The function will return a dictionary with all configuration options that +relate to the common base layer (that's all that start with +``ckanext.spatial.common_map.``) + +You will need to dump the dict as JSON on the ``data-module-map_config`` +attribute (see for instance the ``dataset_map_base.html`` and +``spatial_query.html`` snippets):: + + {% set map_config = h.get_common_map_config() %} +

+
+
+
+ {% snippet "spatial/snippets/map_attribution.html", map_config=map_config %} +
+ +Once at the Javascript module level, all Leaflet based map widgets should use +the ``ckan.commonLeafletMap`` constructor to initialize the map. It accepts the +following parameters: + +* ``container``: HTML element or id of the map container +* ``mapConfig``: (Optional) CKAN config related to the common base layer +* ``leafletMapOptions``: (Optional) Options to pass to the Leaflet Map constructor +* ``leafletBaseLayerOptions``: (Optional) Options to pass to the Leaflet TileLayer + constructor + +Most of the times you will want to do something like this for a sidebar map:: + + var map = ckan.commonLeafletMap('dataset-map-container', this.options.map_config, {attributionControl: false}); + +And this for a primary content map:: + + var map = ckan.commonLeafletMap('map', this.options.map_config); + + +.. _Leaflet: http://leafletjs.com +.. _OpenStreetMap: http://openstreetmap.org +.. _`XYZ convention`: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames +.. _MapQuest-OSM: http://developer.mapquest.com/web/products/open/map +.. _MapQuest: http://www.mapquest.com/ +.. _MapBox: http://www.mapbox.com/ +.. _TileMill: http://www.mapbox.com/tilemill/ +.. _here: http://www.mapbox.com/developers/api-overview/ +.. _`Leaflet URL template`: http://leafletjs.com/reference.html#url-template +.. _Stamen: http://stamen.com/ +.. _`watercolor maps`: http://maps.stamen.com/watercolor/ From aaaca61632554137c2046fe257d2dc781a8113f5 Mon Sep 17 00:00:00 2001 From: amercader Date: Mon, 7 Oct 2013 19:04:12 +0100 Subject: [PATCH 078/114] [#37] Fix broken link on map widgets docs --- doc/map-widgets.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/map-widgets.rst b/doc/map-widgets.rst index fd17128..8bde2f7 100644 --- a/doc/map-widgets.rst +++ b/doc/map-widgets.rst @@ -35,7 +35,7 @@ it explicitly though, use the following setting:: MapBox ++++++ -MapBox`_ allows to define your custom maps based on OpenStreetMap data, using +`MapBox`_ allows to define your custom maps based on OpenStreetMap data, using their online editor or the more advanced `TileMill`_ desktop tool. You will need to provide a map id with the ``[account].[handle]`` form (Check `here`_ for more details):: From 70c4a8cddfffb552a0d5ffe54863e5812e2b94ea Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Thu, 10 Oct 2013 08:15:50 -0400 Subject: [PATCH 079/114] Update csw.rst --- doc/csw.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/csw.rst b/doc/csw.rst index 0bbd792..e00b507 100644 --- a/doc/csw.rst +++ b/doc/csw.rst @@ -112,7 +112,7 @@ Setup [repository] database=postgresql://ckan_default:pass@localhost/pycsw - The rest of the options are described `here `_. + The rest of the options are described `here `_. 4. Setup the pycsw table. This is done with the ``ckan-pycsw`` paster command (Remember to have the virtualenv activated when running it):: @@ -171,7 +171,7 @@ keep CKAN and pycsw in sync, and serve pycsw with Apache + mod_wsgi like CKAN. This `Wikipedia page `_ has a good overview of the crontab syntax. -* To run pycsw under Apache check the pycsw `installation documentation `_ +* To run pycsw under Apache check the pycsw `installation documentation `_ or follow this quick steps (they assume the paths used on the previous steps): - Edit ``/etc/apache2/sites-available/ckan_default`` and add the following @@ -254,7 +254,7 @@ The equivalent example to the one above for asking the cabailities is:: OWSLib is the library used to actually perform the queries. .. _pycsw: http://pycsw.org -.. _pycsw documentation: http://pycsw.org/docs/installation.html +.. _pycsw documentation: http://pycsw.org/docs/latest/installation.html .. _package install: http://docs.ckan.org/en/latest/install-from-package.html .. _CSW: http://www.opengeospatial.org/standards/cat From 45ebb5a13e7f3790c3c27064e9c75a95d4739c9a Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 10 Oct 2013 17:56:23 +0100 Subject: [PATCH 080/114] [#37] Update attributions --- ckanext/spatial/public/js/common_map.js | 2 +- .../spatial/templates/spatial/snippets/map_attribution.html | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ckanext/spatial/public/js/common_map.js b/ckanext/spatial/public/js/common_map.js index 37d35ba..c0acd60 100644 --- a/ckanext/spatial/public/js/common_map.js +++ b/ckanext/spatial/public/js/common_map.js @@ -45,7 +45,7 @@ baseLayerUrl = '//{s}.tiles.mapbox.com/v3/{handle}/{z}/{x}/{y}.png'; leafletBaseLayerOptions.handle = mapConfig['mapbox.map_id']; leafletBaseLayerOptions.subdomains = mapConfig.subdomains || 'abcd'; - leafletBaseLayerOptions.attribution = mapConfig.attribution || 'Map data © OpenStreetMap contributors, Tiles Courtesy of MapBox'; + leafletBaseLayerOptions.attribution = mapConfig.attribution || 'Data: OpenStreetMap, Design: MapBox'; } else if (mapConfig.type == 'custom') { // Custom XYZ layer baseLayerUrl = mapConfig['custom.url']; diff --git a/ckanext/spatial/templates/spatial/snippets/map_attribution.html b/ckanext/spatial/templates/spatial/snippets/map_attribution.html index cb40429..c30164d 100644 --- a/ckanext/spatial/templates/spatial/snippets/map_attribution.html +++ b/ckanext/spatial/templates/spatial/snippets/map_attribution.html @@ -1,4 +1,5 @@ -
Map data CC-BY-SA by OpenStreetMap
+
Map data © OpenStreetMap contributors
{% if map_config.type == 'mapbox' %}
Tiles by MapBox
{% else %} From 1fdf0cde4c6feed2b3f0675ff88145dd4b626e6e Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Mon, 14 Oct 2013 09:18:42 -0400 Subject: [PATCH 081/114] s/owslib.csw.getrecords/owslib.csw.getrecords2/g --- ckanext/spatial/lib/csw_client.py | 23 +++++++++++++++++------ ckanext/spatial/tests/test_csw_client.py | 10 ++++++---- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/ckanext/spatial/lib/csw_client.py b/ckanext/spatial/lib/csw_client.py index d4e2403..a052072 100644 --- a/ckanext/spatial/lib/csw_client.py +++ b/ckanext/spatial/lib/csw_client.py @@ -65,13 +65,19 @@ class CswService(OwsService): Perform various operations on a CSW service """ from owslib.csw import CatalogueServiceWeb as _Implementation + from owslib.fes import PropertyIsEqualTo def getrecords(self, qtype=None, keywords=[], typenames="csw:Record", esn="brief", skip=0, count=10, outputschema="gmd", **kw): from owslib.csw import namespaces + constraints = [] csw = self._ows(**kw) + + if qtype is not None: + constraints.append(PropertyIsEqualTo("dc:type", qtype)) + kwa = { - "qtype": qtype, + "constraints": constraints, "keywords": keywords, "typenames": typenames, "esn": esn, @@ -79,8 +85,8 @@ class CswService(OwsService): "maxrecords": count, "outputschema": namespaces[outputschema], } - log.info('Making CSW request: getrecords %r', kwa) - csw.getrecords(**kwa) + log.info('Making CSW request: getrecords2 %r', kwa) + csw.getrecords2(**kwa) if csw.exceptionreport: err = 'Error getting records: %r' % \ csw.exceptionreport.exceptions @@ -92,9 +98,14 @@ class CswService(OwsService): keywords=[], limit=None, page=10, outputschema="gmd", startposition=0, **kw): from owslib.csw import namespaces + constraints = [] csw = self._ows(**kw) + + if qtype is not None: + constraints.append(PropertyIsEqualTo("dc:type", qtype)) + kwa = { - "qtype": qtype, + "constraints": constraints, "keywords": keywords, "typenames": typenames, "esn": esn, @@ -105,9 +116,9 @@ class CswService(OwsService): i = 0 matches = 0 while True: - log.info('Making CSW request: getrecords %r', kwa) + log.info('Making CSW request: getrecords2 %r', kwa) - csw.getrecords(**kwa) + csw.getrecords2(**kwa) if csw.exceptionreport: err = 'Error getting identifiers: %r' % \ csw.exceptionreport.exceptions diff --git a/ckanext/spatial/tests/test_csw_client.py b/ckanext/spatial/tests/test_csw_client.py index d64214b..5a6ef85 100644 --- a/ckanext/spatial/tests/test_csw_client.py +++ b/ckanext/spatial/tests/test_csw_client.py @@ -4,6 +4,7 @@ from urllib2 import urlopen import os from owslib.csw import CatalogueServiceWeb +from owslib.fes import PropertyIsEqualTo from owslib.iso import MD_Metadata from pylons import config from nose.plugins.skip import SkipTest @@ -137,7 +138,7 @@ class TestCswClient(CkanProcess): # NB: This test fails because no records have been setup... raise SkipTest() # therefore skip csw = CatalogueServiceWeb(service) - csw.getrecords(outputschema=GMD, startposition=1, maxrecords=5) + csw.getrecords2(outputschema=GMD, startposition=1, maxrecords=5) nrecords = len(csw.records) #print csw.response[:1024] assert nrecords == 5, nrecords @@ -147,19 +148,20 @@ class TestCswClient(CkanProcess): def test_GetRecords_dataset(self): csw = CatalogueServiceWeb(service) - csw.getrecords(qtype="dataset", outputschema=GMD, startposition=1, maxrecords=5) + constraints = [PropertyIsEqualTo("dc:type", "dataset")] + csw.getrecords2(constraints=constraints, outputschema=GMD, startposition=1, maxrecords=5) nrecords = len(csw.records) # TODO def test_GetRecords_brief(self): csw = CatalogueServiceWeb(service) - csw.getrecords(outputschema=GMD, startposition=1, maxrecords=5, esn="brief") + csw.getrecords2(outputschema=GMD, startposition=1, maxrecords=5, esn="brief") nrecords = len(csw.records) # TODO def test_GetRecords_summary(self): csw = CatalogueServiceWeb(service) - csw.getrecords(outputschema=GMD, startposition=1, maxrecords=5, esn="summary") + csw.getrecords2(outputschema=GMD, startposition=1, maxrecords=5, esn="summary") nrecords = len(csw.records) # TODO From 0c880115d9cc33a3de65661ad2a6f33eb1769dc7 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Mon, 14 Oct 2013 15:28:33 -0400 Subject: [PATCH 082/114] peg OWSLib at 0.8.2 --- pip-requirements.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pip-requirements.txt b/pip-requirements.txt index 34c4b4e..5681cb5 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -1,8 +1,6 @@ GeoAlchemy>=0.6 Shapely>=1.2.13 -# Temporal requirement until there is an OWSLib release -# that requires python-dateutil<2.0 --e git+https://github.com/geopython/OWSLib.git@4b0a62cd37a5a03aafc5c0cd9606e0658d5ac664#egg=owslib +OWSLib==0.8.2 lxml>=2.3 argparse pyparsing==1.5.6 From ffc5121c6da5ddda87583aa14ef542d92b7e1053 Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 16 Oct 2013 13:58:14 +0100 Subject: [PATCH 083/114] Fix csw client to properly use getrecords2 --- ckanext/spatial/lib/csw_client.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ckanext/spatial/lib/csw_client.py b/ckanext/spatial/lib/csw_client.py index a052072..62cbafa 100644 --- a/ckanext/spatial/lib/csw_client.py +++ b/ckanext/spatial/lib/csw_client.py @@ -6,6 +6,7 @@ for convenience. import logging from owslib.etree import etree +from owslib.fes import PropertyIsEqualTo log = logging.getLogger(__name__) @@ -64,8 +65,6 @@ class CswService(OwsService): """ Perform various operations on a CSW service """ - from owslib.csw import CatalogueServiceWeb as _Implementation - from owslib.fes import PropertyIsEqualTo def getrecords(self, qtype=None, keywords=[], typenames="csw:Record", esn="brief", skip=0, count=10, outputschema="gmd", **kw): @@ -78,7 +77,6 @@ class CswService(OwsService): kwa = { "constraints": constraints, - "keywords": keywords, "typenames": typenames, "esn": esn, "startposition": skip, @@ -106,7 +104,6 @@ class CswService(OwsService): kwa = { "constraints": constraints, - "keywords": keywords, "typenames": typenames, "esn": esn, "startposition": startposition, From dac18b69b156810b3cec8d6604e97246805a506f Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 23 Oct 2013 13:02:22 +0100 Subject: [PATCH 084/114] Revert accidental deletion from ffc5121c --- ckanext/spatial/lib/csw_client.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ckanext/spatial/lib/csw_client.py b/ckanext/spatial/lib/csw_client.py index 62cbafa..3de37cc 100644 --- a/ckanext/spatial/lib/csw_client.py +++ b/ckanext/spatial/lib/csw_client.py @@ -65,6 +65,7 @@ class CswService(OwsService): """ Perform various operations on a CSW service """ + from owslib.csw import CatalogueServiceWeb as _Implementation def getrecords(self, qtype=None, keywords=[], typenames="csw:Record", esn="brief", skip=0, count=10, outputschema="gmd", **kw): From 60781def516c54124baa4342c422a0388ad91e74 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Thu, 7 Nov 2013 10:05:44 -0800 Subject: [PATCH 085/114] typo --- doc/previews.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/previews.rst b/doc/previews.rst index 7b0d737..58dad92 100644 --- a/doc/previews.rst +++ b/doc/previews.rst @@ -15,7 +15,7 @@ GeoJSON Preview The GeoJSON previewer is based on Leaflet_. It will render GeoJSON_ files on a map and add a popup showing the features properties, for those resources that -have a format of ``geojson`` or ``gjosn``. +have a format of ``geojson`` or ``gjson``. To enable the GeoJSON previewer you need to add the ``geojson_preview`` plugin to your ini file. This plugin also requires the `resource_proxy`_ From d22e36e19b37ac1dfdbce9e098d8fc5027da7f39 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Fri, 15 Nov 2013 09:43:22 -0500 Subject: [PATCH 086/114] add requests to deps --- pip-requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/pip-requirements.txt b/pip-requirements.txt index 5681cb5..913ea46 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -4,3 +4,4 @@ OWSLib==0.8.2 lxml>=2.3 argparse pyparsing==1.5.6 +requests From 6549964b8380fc2b77cb248e1c54f716cd992a3b Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Fri, 15 Nov 2013 10:02:20 -0500 Subject: [PATCH 087/114] add editorial fixes --- doc/csw.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/csw.rst b/doc/csw.rst index e00b507..ac1459d 100644 --- a/doc/csw.rst +++ b/doc/csw.rst @@ -10,8 +10,8 @@ This support consists of: * Ability to import records from CSW servers with the CSW harvester. See :doc:`harvesters` for more details. -* Integration with pycsw_ to provide a fully compliat CSW interface for - harvested records. This integration is described on the following sections. +* Integration with pycsw_ to provide a fully compliant CSW interface for + harvested records. This integration is described in the following sections. ckan-pycsw @@ -172,7 +172,7 @@ keep CKAN and pycsw in sync, and serve pycsw with Apache + mod_wsgi like CKAN. has a good overview of the crontab syntax. * To run pycsw under Apache check the pycsw `installation documentation `_ - or follow this quick steps (they assume the paths used on the previous steps): + or follow these quick steps (they assume the paths used in previous steps): - Edit ``/etc/apache2/sites-available/ckan_default`` and add the following line just before the existing ``WSGIScriptAlias`` directive:: From af695826e8d22666ce66008cb2ad82b2faa04f68 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Mon, 18 Nov 2013 16:32:23 -0500 Subject: [PATCH 088/114] add functionality to set CSW keywords from CKAN tag counts --- bin/ckan_pycsw.py | 33 ++++++++++++++++++++++++++++++--- ckanext/spatial/commands/csw.py | 10 ++++++++-- doc/csw.rst | 12 ++++++++++++ pip-requirements.txt | 1 + 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py index 642dbfa..6b72008 100644 --- a/bin/ckan_pycsw.py +++ b/bin/ckan_pycsw.py @@ -33,6 +33,26 @@ def setup_db(pycsw_config): extra_columns=ckan_columns) +def set_keywords(pycsw_config_file, pycsw_config, ckan_url, limit=20): + """set pycsw service metadata keywords from top 10 CKAN tags""" + + log.info('Fetching tags from %s', ckan_url) + url = ckan_url + 'api/tag_counts' + response = requests.get(url) + tags = response.json() + + log.info('Deriving top %d tags', limit) + # uniquify and sort by top limit + tags_unique = [list(x) for x in set(tuple(x) for x in tags)] + tags_sorted = sorted(tags_unique, key=lambda x: x[1], reverse=1)[0:limit] + keywords = ','.join('%s' % tn[0] for tn in tags_sorted) + + log.info('Setting tags in pycsw configuration file %s', pycsw_config_file) + pycsw_config.set('metadata:main', 'identification_keywords', keywords) + with open(pycsw_config_file, 'wb') as configfile: + pycsw_config.write(configfile) + + def load(pycsw_config, ckan_url): database = pycsw_config.get('repository', 'database') @@ -40,7 +60,6 @@ def load(pycsw_config, ckan_url): context = pycsw.config.StaticContext() repo = repository.Repository(database, context, table=table_name) - ckan_url = ckan_url.lstrip('/') + '/' log.info('Started gathering CKAN datasets identifiers: {0}'.format(str(datetime.datetime.now()))) @@ -85,6 +104,7 @@ def load(pycsw_config, ckan_url): deleted = set(existing_records) - set(gathered_records) changed = set() + sys.exit(1) for key in set(gathered_records) & set(existing_records): if gathered_records[key]['metadata_modified'] > existing_records[key]: changed.add(key) @@ -179,6 +199,9 @@ Manages the CKAN-pycsw integration python ckan-pycsw.py setup [-p] Setups the necessary pycsw table on the db. + python ckan-pycsw.py set_keywords [-p] -u + Sets pycsw server metadata keywords from CKAN site tag list. + python ckan-pycsw.py load [-p] -u Loads CKAN datasets as records into the pycsw db. @@ -237,10 +260,14 @@ if __name__ == '__main__': if arg.command == 'setup': setup_db(pycsw_config) - elif arg.command == 'load': + elif arg.command in ['load', 'set_keywords']: if not arg.ckan_url: raise AssertionError('You need to provide a CKAN URL with -u or --ckan_url') - load(pycsw_config, arg.ckan_url) + ckan_url = arg.ckan_url.rstrip('/') + '/' + if arg.command == 'load': + load(pycsw_config, ckan_url) + else: + set_keywords(arg.pycsw_config, pycsw_config, ckan_url) elif arg.command == 'clear': clear(pycsw_config) else: diff --git a/ckanext/spatial/commands/csw.py b/ckanext/spatial/commands/csw.py index 3375d8b..7d53b9d 100644 --- a/ckanext/spatial/commands/csw.py +++ b/ckanext/spatial/commands/csw.py @@ -11,6 +11,9 @@ class Pycsw(script.command.Command): ckan-pycsw setup [-p] Setups the necessary pycsw table on the db. + ckan-pycsw set_keywords [-p] [-u] + Sets pycsw server metadata keywords from CKAN site tag list. + ckan-pycsw load [-p] [-u] Loads CKAN datasets as records into the pycsw db. @@ -51,9 +54,12 @@ option: cmd = self.args[0] if cmd == 'setup': ckan_pycsw.setup_db(config) - elif cmd == 'load': + elif cmd in ['load', 'set_keywords']: ckan_url = self.options.ckan_url - ckan_pycsw.load(config, ckan_url) + if cmd == 'load': + ckan_pycsw.load(config, ckan_url) + else: + ckan_pycsw.set_keywords(self.options.pycsw_config, config, ckan_url) elif cmd == 'clear': ckan_pycsw.clear(config) else: diff --git a/doc/csw.rst b/doc/csw.rst index ac1459d..857fd73 100644 --- a/doc/csw.rst +++ b/doc/csw.rst @@ -154,6 +154,17 @@ Setup datasets will be synchronized and deleted datasets from CKAN will be removed from pycsw as well. +Setting Service Metadata Keywords ++++++++++++++++++++++++++++++++++ + +The CSW standard allows for administrators to set CSW service metadata. These +values can be set in the pycsw configuration ``metadata:main`` section. If you +would like the CSW service metadata keywords to be reflective of the CKAN +tags, run the following: + + paster ckan-pycsw set_keywords -p /etc/ckan/default/pycsw.cfg + + Running it on production site +++++++++++++++++++++++++++++ @@ -165,6 +176,7 @@ keep CKAN and pycsw in sync, and serve pycsw with Apache + mod_wsgi like CKAN. # m h dom mon dow command 0 * * * * /usr/lib/ckan/default/bin/paster --plugin=ckanext-spatial ckan-pycsw load -p /etc/ckan/default/pycsw.cfg + 0 0 * * * /usr/lib/ckan/default/bin/paster --plugin=ckanext-spatial ckan-pycsw set_keywords -p /etc/ckan/default/pycsw.cfg This particular example will run the load command every hour. You can of course modify this periodicity, for instance reducing it for huge instances. diff --git a/pip-requirements.txt b/pip-requirements.txt index 913ea46..1042bd4 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -5,3 +5,4 @@ lxml>=2.3 argparse pyparsing==1.5.6 requests +jinja2 From 82e61c95ad12a4aa13da01b2794ff0e50b61a39e Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Mon, 18 Nov 2013 16:34:07 -0500 Subject: [PATCH 089/114] remove debugging --- bin/ckan_pycsw.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py index 6b72008..cbe7d6b 100644 --- a/bin/ckan_pycsw.py +++ b/bin/ckan_pycsw.py @@ -104,7 +104,6 @@ def load(pycsw_config, ckan_url): deleted = set(existing_records) - set(gathered_records) changed = set() - sys.exit(1) for key in set(gathered_records) & set(existing_records): if gathered_records[key]['metadata_modified'] > existing_records[key]: changed.add(key) From d825f5daea1d52ff10cb2f2041a81255fe2c1362 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Mon, 18 Nov 2013 16:35:48 -0500 Subject: [PATCH 090/114] remove unused lib --- pip-requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/pip-requirements.txt b/pip-requirements.txt index 1042bd4..913ea46 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -5,4 +5,3 @@ lxml>=2.3 argparse pyparsing==1.5.6 requests -jinja2 From 81e9d3f119cee3691fa18cb0d7e14bce1c763bf4 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Fri, 22 Nov 2013 07:41:36 -0500 Subject: [PATCH 091/114] Update pip-requirements.txt --- pip-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pip-requirements.txt b/pip-requirements.txt index 913ea46..849155b 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -4,4 +4,4 @@ OWSLib==0.8.2 lxml>=2.3 argparse pyparsing==1.5.6 -requests +requests==1.1.0 From 2e1c82aa19c87ea2352cf31c69eaee21e8615bf7 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Fri, 22 Nov 2013 08:01:00 -0500 Subject: [PATCH 092/114] update docstring --- bin/ckan_pycsw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/ckan_pycsw.py b/bin/ckan_pycsw.py index cbe7d6b..471c71c 100644 --- a/bin/ckan_pycsw.py +++ b/bin/ckan_pycsw.py @@ -34,7 +34,7 @@ def setup_db(pycsw_config): def set_keywords(pycsw_config_file, pycsw_config, ckan_url, limit=20): - """set pycsw service metadata keywords from top 10 CKAN tags""" + """set pycsw service metadata keywords from top limit CKAN tags""" log.info('Fetching tags from %s', ckan_url) url = ckan_url + 'api/tag_counts' From 0f8fa75b089064ef38b1c8bb33b1c501c12e3a48 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Fri, 22 Nov 2013 08:52:32 -0500 Subject: [PATCH 093/114] small doc fixes --- doc/csw.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/csw.rst b/doc/csw.rst index 857fd73..405b56c 100644 --- a/doc/csw.rst +++ b/doc/csw.rst @@ -160,10 +160,12 @@ Setting Service Metadata Keywords The CSW standard allows for administrators to set CSW service metadata. These values can be set in the pycsw configuration ``metadata:main`` section. If you would like the CSW service metadata keywords to be reflective of the CKAN -tags, run the following: +tags, run the following convenience command: paster ckan-pycsw set_keywords -p /etc/ckan/default/pycsw.cfg +Note that you must have privileges to write to the pycsw configuration file. + Running it on production site +++++++++++++++++++++++++++++ @@ -176,7 +178,6 @@ keep CKAN and pycsw in sync, and serve pycsw with Apache + mod_wsgi like CKAN. # m h dom mon dow command 0 * * * * /usr/lib/ckan/default/bin/paster --plugin=ckanext-spatial ckan-pycsw load -p /etc/ckan/default/pycsw.cfg - 0 0 * * * /usr/lib/ckan/default/bin/paster --plugin=ckanext-spatial ckan-pycsw set_keywords -p /etc/ckan/default/pycsw.cfg This particular example will run the load command every hour. You can of course modify this periodicity, for instance reducing it for huge instances. From ae60adf48651ff235da1582032271594a28917da Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Wed, 18 Dec 2013 09:46:10 -0500 Subject: [PATCH 094/114] editorial: identify pycsw --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 4b5b294..cc0fed5 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ including: dataset extent on the frontend. * Harvesters to import geospatial metadata into CKAN from other sources in ISO 19139 format and others. -* Commands to support the CSW standard. +* Commands to support the CSW standard using pycsw_. * Plugins to preview spatial formats such as GeoJSON_. Full documentation, including installation instructions, can be found at: @@ -47,5 +47,6 @@ http://www.fsf.org/licensing/licenses/agpl-3.0.html .. _CKAN: http://ckan.org .. _PostGIS: http://postgis.org +.. _pycsw: http://pycsw.org .. _GeoJSON: http://geojson.org From b43652405471b19d55fbe666a91a9e347eeb9b52 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Sat, 21 Dec 2013 08:10:30 -0500 Subject: [PATCH 095/114] Update csw.rst --- doc/csw.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/csw.rst b/doc/csw.rst index 405b56c..8385725 100644 --- a/doc/csw.rst +++ b/doc/csw.rst @@ -160,7 +160,7 @@ Setting Service Metadata Keywords The CSW standard allows for administrators to set CSW service metadata. These values can be set in the pycsw configuration ``metadata:main`` section. If you would like the CSW service metadata keywords to be reflective of the CKAN -tags, run the following convenience command: +tags, run the following convenience command:: paster ckan-pycsw set_keywords -p /etc/ckan/default/pycsw.cfg From 3f91a4411bf82040786e05f836961a0c52bb7211 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Thu, 26 Dec 2013 18:18:15 -0500 Subject: [PATCH 096/114] Update csw.py --- ckanext/spatial/commands/csw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ckanext/spatial/commands/csw.py b/ckanext/spatial/commands/csw.py index 7d53b9d..88517a6 100644 --- a/ckanext/spatial/commands/csw.py +++ b/ckanext/spatial/commands/csw.py @@ -55,7 +55,7 @@ option: if cmd == 'setup': ckan_pycsw.setup_db(config) elif cmd in ['load', 'set_keywords']: - ckan_url = self.options.ckan_url + ckan_url = self.options.ckan_url.rstrip('/') + '/' if cmd == 'load': ckan_pycsw.load(config, ckan_url) else: From c352fbdadb485246268901cae0f0490f1610f91e Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 9 Jan 2014 17:46:45 +0000 Subject: [PATCH 097/114] [#52] Show dataset map correctly on all 2.x versions --- ckanext/spatial/public/css/dataset_map.css | 27 +++++++------------ .../spatial/snippets/dataset_map.html | 11 ++++---- doc/spatial-search.rst | 20 +++++--------- 3 files changed, 22 insertions(+), 36 deletions(-) diff --git a/ckanext/spatial/public/css/dataset_map.css b/ckanext/spatial/public/css/dataset_map.css index e43a760..576d2c1 100644 --- a/ckanext/spatial/public/css/dataset_map.css +++ b/ckanext/spatial/public/css/dataset_map.css @@ -1,30 +1,23 @@ +/* Side bar */ .module-narrow #dataset-map-container{ height: 200px; } -.module-content #dataset-map-container{ +/* Primary content */ + +.dataset-map-section-20x { + padding: 0 25px; + margin: 20px 0; +} + +.dataset-map #dataset-map-container{ height: 250px; } #dataset-map-attribution{ - font-size: x-small; + font-size: x-small; } .module-narrow #dataset-map-attribution{ margin-left: 3px; } - -.olControlAttribution { - left: 5px; - right: inherit; - bottom: 3px !important; -} - -#dataset-map-container div.olControlAttribution { - font-size: 9px; - font-family: helvetica,tahoma,verdana,sans-serif; - line-height: 12px; - left: 5px; - bottom: 3px; - color: #666; -} diff --git a/ckanext/spatial/templates/spatial/snippets/dataset_map.html b/ckanext/spatial/templates/spatial/snippets/dataset_map.html index 6128e35..7034f50 100644 --- a/ckanext/spatial/templates/spatial/snippets/dataset_map.html +++ b/ckanext/spatial/templates/spatial/snippets/dataset_map.html @@ -12,9 +12,8 @@ extent {% endif %} #} -
-
-

{{ _('Dataset extent') }}

- {% snippet "spatial/snippets/dataset_map_base.html", extent=extent %} -
-
+ +
+

{{ _('Dataset extent') }}

+ {% snippet "spatial/snippets/dataset_map_base.html", extent=extent %} +
diff --git a/doc/spatial-search.rst b/doc/spatial-search.rst index 2223dff..dabca99 100644 --- a/doc/spatial-search.rst +++ b/doc/spatial-search.rst @@ -197,7 +197,7 @@ the main body of the dataset details page, but these can be easily modified to suit your project needs To add a map to the sidebar, add this to the dataset details page template (eg -``myproj/ckanext/myproj/templates/package/read.html``):: +``ckanext-myproj/ckanext/myproj/templates/package/read.html``):: {% block secondary_content %} {{ super() }} @@ -211,23 +211,17 @@ To add a map to the sidebar, add this to the dataset details page template (eg For adding the map to the main body, add this:: - {% block primary_content %} + {% block primary_content_inner %} - + {{ super() }} -
+ {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %} + {% if dataset_extent %} + {% snippet "spatial/snippets/dataset_map.html", extent=dataset_extent %} + {% endif %} - - - {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %} - {% if dataset_extent %} - {% snippet "spatial/snippets/dataset_map.html", extent=dataset_extent %} - {% endif %} - -
{% endblock %} - You need to load the ``spatial_metadata`` plugin to use these snippets. Legacy Search From 15461acff74a4aed3a7e17c1cf0655bb5cbcb842 Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 9 Jan 2014 17:49:18 +0000 Subject: [PATCH 098/114] [#52] Add class for link removed on 2.2 --- ckanext/spatial/public/css/spatial_query.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ckanext/spatial/public/css/spatial_query.css b/ckanext/spatial/public/css/spatial_query.css index 2a683ea..a195cb8 100644 --- a/ckanext/spatial/public/css/spatial_query.css +++ b/ckanext/spatial/public/css/spatial_query.css @@ -8,6 +8,13 @@ font-size: 11px; line-height: 1.5; } +.module-heading .action { + float: right; + color: #888888; + font-size: 12px; + line-height: 20px; + text-decoration: underline; +} .module-narrow #dataset-map-attribution { margin: 5px 8px; color: #666; From a3524a6b7da5d955d16368a058447de0bd1dff18 Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 9 Jan 2014 17:49:37 +0000 Subject: [PATCH 099/114] [#52] Add note about WMS urls for preview --- doc/previews.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/previews.rst b/doc/previews.rst index 58dad92..cf1b562 100644 --- a/doc/previews.rst +++ b/doc/previews.rst @@ -30,10 +30,14 @@ WMS Preview .. image:: _static/preview-wms.png -The WMS previewer is based o OpenLayers_. When the plugin is enabled, if +The WMS previewer is based on OpenLayers_. When the plugin is enabled, if datasets contain a resource that has ``wms`` format, the resource page will load a simple map viewer that will attempt to load the remote service layers, -based on the GetCapabilities response. +based on the GetCapabilities response. In order for the proxy to get correct +response, the URL of the resource must be a full GetCapabilities request, not +just the main WMS service endpoint, for example: + +http://vmap0.tiles.osgeo.org/wms/vmap0?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.1 To enable the WMS previewer you need to add the ``wms_preview`` plugin to your ini file. This plugin also requires the `resource_proxy`_ From 9116a6fd1f94d3fbb779f0f90f535c6e285f5ac7 Mon Sep 17 00:00:00 2001 From: etj Date: Sun, 2 Mar 2014 23:12:54 +0100 Subject: [PATCH 100/114] [#55] Allow CSW harvesters to define CQL filters (2nd try) --- ckanext/spatial/harvesters/base.py | 2 ++ ckanext/spatial/harvesters/csw.py | 5 ++++- ckanext/spatial/lib/csw_client.py | 3 ++- pip-requirements.txt | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ckanext/spatial/harvesters/base.py b/ckanext/spatial/harvesters/base.py index 245ead6..9122b61 100644 --- a/ckanext/spatial/harvesters/base.py +++ b/ckanext/spatial/harvesters/base.py @@ -613,6 +613,8 @@ class SpatialHarvester(HarvesterBase): if config_str: self.source_config = json.loads(config_str) log.debug('Using config: %r', self.source_config) + else: + self.source_config = {} def _get_validator(self): ''' diff --git a/ckanext/spatial/harvesters/csw.py b/ckanext/spatial/harvesters/csw.py index 769a1af..464842d 100644 --- a/ckanext/spatial/harvesters/csw.py +++ b/ckanext/spatial/harvesters/csw.py @@ -86,10 +86,13 @@ class CSWHarvester(SpatialHarvester, SingletonPlugin): guids_in_db = set(guid_to_package_id.keys()) + # extract cql filter if any + cql = self.source_config.get('cql') + log.debug('Starting gathering for %s' % url) guids_in_harvest = set() try: - for identifier in self.csw.getidentifiers(page=10, outputschema=self.output_schema()): + for identifier in self.csw.getidentifiers(page=10, outputschema=self.output_schema(), cql=cql): try: log.info('Got identifier %s from the CSW', identifier) if identifier is None: diff --git a/ckanext/spatial/lib/csw_client.py b/ckanext/spatial/lib/csw_client.py index 3de37cc..6da2062 100644 --- a/ckanext/spatial/lib/csw_client.py +++ b/ckanext/spatial/lib/csw_client.py @@ -95,7 +95,7 @@ class CswService(OwsService): def getidentifiers(self, qtype=None, typenames="csw:Record", esn="brief", keywords=[], limit=None, page=10, outputschema="gmd", - startposition=0, **kw): + startposition=0, cql=None, **kw): from owslib.csw import namespaces constraints = [] csw = self._ows(**kw) @@ -110,6 +110,7 @@ class CswService(OwsService): "startposition": startposition, "maxrecords": page, "outputschema": namespaces[outputschema], + "cql":cql, } i = 0 matches = 0 diff --git a/pip-requirements.txt b/pip-requirements.txt index 849155b..2f9df16 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -1,6 +1,6 @@ GeoAlchemy>=0.6 Shapely>=1.2.13 -OWSLib==0.8.2 +OWSLib==0.8.6 lxml>=2.3 argparse pyparsing==1.5.6 From 93e07fe98731d7a950789690099bbb8fee310420 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 7 Mar 2014 16:26:50 +0000 Subject: [PATCH 101/114] [#61] Add media types for GeoJSON and GML --- ckanext/spatial/nongeos_plugin.py | 3 +++ ckanext/spatial/plugin.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/ckanext/spatial/nongeos_plugin.py b/ckanext/spatial/nongeos_plugin.py index a66bf73..1597e01 100644 --- a/ckanext/spatial/nongeos_plugin.py +++ b/ckanext/spatial/nongeos_plugin.py @@ -1,3 +1,4 @@ +import mimetypes from logging import getLogger from ckan import plugins as p @@ -71,6 +72,8 @@ class GeoJSONPreview(p.SingletonPlugin): self.proxy_enabled = config.get( 'ckan.resource_proxy_enabled', False) + mimetypes.add_type('application/json', '.geojson') + def can_preview(self, data_dict): format_lower = data_dict['resource']['format'].lower() diff --git a/ckanext/spatial/plugin.py b/ckanext/spatial/plugin.py index daca6b8..7e62485 100644 --- a/ckanext/spatial/plugin.py +++ b/ckanext/spatial/plugin.py @@ -1,5 +1,6 @@ import os import re +import mimetypes from logging import getLogger from pylons import config @@ -56,6 +57,11 @@ class SpatialMetadata(p.SingletonPlugin): p.toolkit.add_template_directory(config, 'templates') p.toolkit.add_resource('public', 'ckanext-spatial') + # Add media types for common extensions not included in the mimetypes + # module + mimetypes.add_type('application/json', '.geojson') + mimetypes.add_type('application/gml+xml', '.gml') + def create(self, package): self.check_spatial_extra(package) From 239b8313e9fe2e56ae148e8ab14bf9718e82e6f6 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 11 Mar 2014 14:07:01 +0000 Subject: [PATCH 102/114] [#62] Add links to organization parties --- ckanext/spatial/model/harvested_metadata.py | 94 +++++++++++---------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index 0b424b1..b71c08a 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -158,49 +158,6 @@ class ISOElement(MappedXmlElement): } -class ISOResponsibleParty(ISOElement): - - elements = [ - ISOElement( - name="organisation-name", - search_paths=[ - "gmd:organisationName/gco:CharacterString/text()", - ], - multiplicity="0..1", - ), - ISOElement( - name="position-name", - search_paths=[ - "gmd:positionName/gco:CharacterString/text()", - ], - multiplicity="0..1", - ), - ISOElement( - name="contact-info", - search_paths=[ - "gmd:contactInfo/gmd:CI_Contact", - ], - multiplicity="0..1", - elements = [ - ISOElement( - name="email", - search_paths=[ - "gmd:address/gmd:CI_Address/gmd:electronicMailAddress/gco:CharacterString/text()", - ], - multiplicity="0..1", - ), - ] - ), - ISOElement( - name="role", - search_paths=[ - "gmd:role/gmd:CI_RoleCode/@codeListValue", - ], - multiplicity="0..1", - ), - ] - - class ISOResourceLocator(ISOElement): elements = [ @@ -242,6 +199,57 @@ class ISOResourceLocator(ISOElement): ] +class ISOResponsibleParty(ISOElement): + + elements = [ + ISOElement( + name="organisation-name", + search_paths=[ + "gmd:organisationName/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), + ISOElement( + name="position-name", + search_paths=[ + "gmd:positionName/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), + ISOElement( + name="contact-info", + search_paths=[ + "gmd:contactInfo/gmd:CI_Contact", + ], + multiplicity="0..1", + elements = [ + ISOElement( + name="email", + search_paths=[ + "gmd:address/gmd:CI_Address/gmd:electronicMailAddress/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), + ISOResourceLocator( + name="online-resource", + search_paths=[ + "gmd:onlineResource/gmd:CI_OnlineResource", + ], + multiplicity="0..1", + ), + + ] + ), + ISOElement( + name="role", + search_paths=[ + "gmd:role/gmd:CI_RoleCode/@codeListValue", + ], + multiplicity="0..1", + ), + ] + + class ISODataFormat(ISOElement): elements = [ From ee77800111d0fc10314aae81d8b0c722322740d0 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 11 Mar 2014 14:09:55 +0000 Subject: [PATCH 103/114] [#62] Clean up keywords parsing Keywords were extracted via 3 different elements `keyword-inspire-theme`, `keyword-controlled-other` and `keyword-free-text`. The latter didn't actually do anything and the second duplicated xpaths from the first and added a non-standard one. A new `keywords` key has been added which contains all keyword objects, including type. This is not used to modify the `tags` key right now. --- ckanext/spatial/model/harvested_metadata.py | 42 ++++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index b71c08a..a84cc97 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -379,6 +379,29 @@ class ISOBrowseGraphic(ISOElement): ] +class ISOKeyword(ISOElement): + + elements = [ + ISOElement( + name="keyword", + search_paths=[ + "gmd:keyword/gco:CharacterString/text()", + ], + multiplicity="*", + ), + ISOElement( + name="type", + search_paths=[ + "gmd:type/gmd:MD_KeywordTypeCode/@codeListValue", + "gmd:type/gmd:MD_KeywordTypeCode/text()", + ], + multiplicity="0..1", + ), + # If Thesaurus information is needed at some point, this is the + # place to add it + ] + + class ISODocument(MappedXmlDocument): # Attribute specifications from "XPaths for GEMINI" by Peter Parslow. @@ -499,6 +522,14 @@ class ISODocument(MappedXmlDocument): ], multiplicity="*", ), + ISOKeyword( + name="keywords", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:descriptiveKeywords/gmd:MD_Keywords", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:descriptiveKeywords/gmd:MD_Keywords", + ], + multiplicity="*" + ), ISOElement( name="keyword-inspire-theme", search_paths=[ @@ -507,21 +538,14 @@ class ISODocument(MappedXmlDocument): ], multiplicity="*", ), + # Deprecated: kept for backwards compatibilty ISOElement( name="keyword-controlled-other", search_paths=[ - "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:keyword/gco:CharacterString/text()", - "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:keyword/gco:CharacterString/text()", "gmd:identificationInfo/srv:SV_ServiceIdentification/srv:keywords/gmd:MD_Keywords/gmd:keyword/gco:CharacterString/text()", ], multiplicity="*", ), - ISOElement( - name="keyword-free-text", - search_paths=[ - ], - multiplicity="*", - ), ISOElement( name="limitations-on-public-access", search_paths=[ @@ -762,7 +786,7 @@ class ISODocument(MappedXmlDocument): def infer_tags(self, values): tags = [] - for key in ['keyword-inspire-theme', 'keyword-controlled-other', 'keyword-free-text']: + for key in ['keyword-inspire-theme', 'keyword-controlled-other']: for item in values[key]: if item not in tags: tags.append(item) From 8b4d23a3153e599fb3e812932ab273728a98fddf Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 11 Mar 2014 17:05:08 +0000 Subject: [PATCH 104/114] [#62] Add new fields to the ISO parser * Metadata standard name / version * Unique resource identifier (reenabled and fixed) * Presentation form * Purpose * Maintenance note * Access constraints * Distributor * Usage * Aggregation info --- ckanext/spatial/model/harvested_metadata.py | 148 ++++++++++++++++++-- 1 file changed, 137 insertions(+), 11 deletions(-) diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index a84cc97..d0ecfcd 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -402,6 +402,63 @@ class ISOKeyword(ISOElement): ] +class ISOUsage(ISOElement): + + elements = [ + ISOElement( + name="usage", + search_paths=[ + "gmd:specificUsage/gco:CharacterString/text()", + ], + multiplicity="1", + ), + ISOResponsibleParty( + name="contact-info", + search_paths=[ + "gmd:userContactInfo/gmd:CI_ResponsibleParty", + ], + multiplicity="1", + ), + + ] + + +class ISOAggregationInfo(ISOElement): + + elements = [ + ISOElement( + name="aggregate-dataset-name", + search_paths=[ + "gmd:aggregateDatasetName/gmd:CI_Citation/gmd:title/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), + ISOElement( + name="aggregate-dataset-identifier", + search_paths=[ + "gmd:aggregateDatasetIdentifier/gmd:MD_Identifier/gmd:code/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), + ISOElement( + name="association-type", + search_paths=[ + "gmd:associationType/gmd:DS_AssociationTypeCode/@codeListValue", + "gmd:associationType/gmd:DS_AssociationTypeCode/text()", + ], + multiplicity="0..1", + ), + ISOElement( + name="initiative-type", + search_paths=[ + "gmd:initiativeType/gmd:DS_InitiativeTypeCode/@codeListValue", + "gmd:initiativeType/gmd:DS_InitiativeTypeCode/text()", + ], + multiplicity="0..1", + ), + ] + + class ISODocument(MappedXmlDocument): # Attribute specifications from "XPaths for GEMINI" by Peter Parslow. @@ -420,6 +477,16 @@ class ISODocument(MappedXmlDocument): ], multiplicity="0..1", ), + ISOElement( + name="metadata-standard-name", + search_paths="gmd:metadataStandardName/gco:CharacterString/text()", + multiplicity="0..1", + ), + ISOElement( + name="metadata-standard-version", + search_paths="gmd:metadataStandardVersion/gco:CharacterString/text()", + multiplicity="0..1", + ), ISOElement( name="resource-type", search_paths=[ @@ -475,15 +542,25 @@ class ISODocument(MappedXmlDocument): ], multiplicity="1..*", ), - ## Todo: Suggestion from PP not to bother pulling this into the package. - #ISOElement( - # name="unique-resource-identifier", - # search_paths=[ - # "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier", - # "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier", - # ], - # multiplicity="1", - #), + ISOElement( + name="unique-resource-identifier", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:MD_Identifier/gmd:code/gco:CharacterString/text()", + "gmd:identificationInfo/gmd:SV_ServiceIdentification/gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:MD_Identifier/gmd:code/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), + ISOElement( + name="presentation-form", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:presentationForm/gmd:CI_PresentationFormCode/text()", + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:presentationForm/gmd:CI_PresentationFormCode/@codeListValue", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:citation/gmd:CI_Citation/gmd:presentationForm/gmd:CI_PresentationFormCode/text()", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:citation/gmd:CI_Citation/gmd:presentationForm/gmd:CI_PresentationFormCode/@codeListValue", + + ], + multiplicity="*", + ), ISOElement( name="abstract", search_paths=[ @@ -492,6 +569,14 @@ class ISODocument(MappedXmlDocument): ], multiplicity="1", ), + ISOElement( + name="purpose", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:purpose/gco:CharacterString/text()", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:purpose/gco:CharacterString/text()", + ], + multiplicity="1", + ), ISOResponsibleParty( name="responsible-organisation", search_paths=[ @@ -506,12 +591,19 @@ class ISODocument(MappedXmlDocument): search_paths=[ "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceMaintenance/gmd:MD_MaintenanceInformation/gmd:maintenanceAndUpdateFrequency/gmd:MD_MaintenanceFrequencyCode/@codeListValue", "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:resourceMaintenance/gmd:MD_MaintenanceInformation/gmd:maintenanceAndUpdateFrequency/gmd:MD_MaintenanceFrequencyCode/@codeListValue", - "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceMaintenance/gmd:MD_MaintenanceInformation/gmd:maintenanceAndUpdateFrequency/gmd:MD_MaintenanceFrequencyCode/text()", "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:resourceMaintenance/gmd:MD_MaintenanceInformation/gmd:maintenanceAndUpdateFrequency/gmd:MD_MaintenanceFrequencyCode/text()", ], multiplicity="0..1", ), + ISOElement( + name="maintenance-note", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceMaintenance/gmd:MD_MaintenanceInformation/gmd:maintenanceNote/gco:CharacterString/text()", + "gmd:identificationInfo/gmd:SV_ServiceIdentification/gmd:resourceMaintenance/gmd:MD_MaintenanceInformation/gmd:maintenanceNote/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), ISOElement( name="progress", search_paths=[ @@ -546,14 +638,33 @@ class ISODocument(MappedXmlDocument): ], multiplicity="*", ), + ISOUsage( + name="usage", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceSpecificUsage/gmd:MD_Usage", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:resourceSpecificUsage/gmd:MD_Usage", + ], + multiplicity="*" + ), ISOElement( name="limitations-on-public-access", search_paths=[ "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:otherConstraints/gco:CharacterString/text()", "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:otherConstraints/gco:CharacterString/text()", ], - multiplicity="1..*", + multiplicity="*", ), + ISOElement( + name="access-constraints", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_RestrictionCode/@codeListValue", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_RestrictionCode/@codeListValue", + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_RestrictionCode/text()", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_RestrictionCode/text()", + ], + multiplicity="*", + ), + ISOElement( name="use-constraints", search_paths=[ @@ -562,6 +673,14 @@ class ISODocument(MappedXmlDocument): ], multiplicity="*", ), + ISOAggregationInfo( + name="aggregation-info", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:aggregationInfo/gmd:MD_AggregateInformation", + "gmd:identificationInfo/gmd:SV_ServiceIdentification/gmd:aggregationInfo/gmd:MD_AggregateInformation", + ], + multiplicity="*" + ), ISOElement( name="spatial-data-service-type", search_paths=[ @@ -678,6 +797,13 @@ class ISODocument(MappedXmlDocument): ], multiplicity="*", ), + ISOResponsibleParty( + name="distributor", + search_paths=[ + "gmd:distributionInfo/gmd:MD_Distribution/gmd:distributor/gmd:MD_Distributor/gmd:distributorContact/gmd:CI_ResponsibleParty", + ], + multiplicity="*", + ), ISOResourceLocator( name="resource-locator", search_paths=[ From 4551efdddb27fe007f23be75ee127a393ff0ad19 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 14 Mar 2014 10:19:57 +0000 Subject: [PATCH 105/114] [#62] Relax multiplicities --- ckanext/spatial/model/harvested_metadata.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index d0ecfcd..a2f2463 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -410,14 +410,14 @@ class ISOUsage(ISOElement): search_paths=[ "gmd:specificUsage/gco:CharacterString/text()", ], - multiplicity="1", + multiplicity="0..1", ), ISOResponsibleParty( name="contact-info", search_paths=[ "gmd:userContactInfo/gmd:CI_ResponsibleParty", ], - multiplicity="1", + multiplicity="0..1", ), ] @@ -575,7 +575,7 @@ class ISODocument(MappedXmlDocument): "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:purpose/gco:CharacterString/text()", "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:purpose/gco:CharacterString/text()", ], - multiplicity="1", + multiplicity="0..1", ), ISOResponsibleParty( name="responsible-organisation", From 1fa72f4c16a4c645986d0b9a2f4d70cc31daab93 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 14 Mar 2014 12:36:01 +0000 Subject: [PATCH 106/114] [#64] Fix validation exception when resource-type was missing --- ckanext/spatial/validation/validation.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ckanext/spatial/validation/validation.py b/ckanext/spatial/validation/validation.py index b9db45b..397dd11 100644 --- a/ckanext/spatial/validation/validation.py +++ b/ckanext/spatial/validation/validation.py @@ -120,7 +120,13 @@ class ISO19139EdenSchema(XsdValidator): xml - etree of the ISO19139 XML record ''' iso_parser = ISODocument(xml_tree=xml) - return iso_parser.read_value('resource-type')[0] + record_types = iso_parser.read_value('resource-type') + if len(record_types): + return record_types[0] + else: + return 'dataset' + + class ISO19139NGDCSchema(XsdValidator): ''' From 26763218bcbd1089f1b921de39d143387fb583f9 Mon Sep 17 00:00:00 2001 From: amercader Date: Fri, 14 Mar 2014 14:12:05 +0000 Subject: [PATCH 107/114] [#62] Fix spatial-resolution parsing --- ckanext/spatial/model/harvested_metadata.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index a2f2463..412fbd5 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -691,19 +691,19 @@ class ISODocument(MappedXmlDocument): ISOElement( name="spatial-resolution", search_paths=[ - "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance", - "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance", + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance/text()", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance/text()", + ], + multiplicity="0..1", + ), + ISOElement( + name="spatial-resolution-units", + search_paths=[ + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance/@uom", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance/@uom", ], multiplicity="0..1", ), - #ISOElement( - # name="spatial-resolution-units", - # search_paths=[ - # "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance/@uom", - # "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance/@uom", - # ], - # multiplicity="0..1", - #), ISOElement( name="equivalent-scale", search_paths=[ From bbe412525796473824d42c28cc940682765e7af4 Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 19 Mar 2014 11:59:08 +0000 Subject: [PATCH 108/114] [#65] Add individualName to ResponsibleParty --- ckanext/spatial/model/harvested_metadata.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index 412fbd5..0c3a82c 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -202,6 +202,13 @@ class ISOResourceLocator(ISOElement): class ISOResponsibleParty(ISOElement): elements = [ + ISOElement( + name="individual-name", + search_paths=[ + "gmd:individualName/gco:CharacterString/text()", + ], + multiplicity="0..1", + ), ISOElement( name="organisation-name", search_paths=[ From b72a94de02091b8aefdb0e7aff27302f6a6787da Mon Sep 17 00:00:00 2001 From: Tobias Preuss Date: Wed, 9 Apr 2014 10:26:07 +0200 Subject: [PATCH 109/114] Avoid that url is interpretated as a pattern by zsh. --- doc/install.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/install.rst b/doc/install.rst index af67b06..ca2356c 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -75,17 +75,17 @@ Install the extension To target the latest CKAN core release:: - (pyenv) $ pip install -e git+https://github.com/okfn/ckanext-spatial.git@stable#egg=ckanext-spatial + (pyenv) $ pip install -e "git+https://github.com/okfn/ckanext-spatial.git@stable#egg=ckanext-spatial" To target an old release (if a release branch exists, otherwise use ``stable``):: - (pyenv) $ pip install -e git+https://github.com/okfn/ckanext-spatial.git@release-v1.8#egg=ckanext-spatial + (pyenv) $ pip install -e "git+https://github.com/okfn/ckanext-spatial.git@release-v1.8#egg=ckanext-spatial" To target CKAN ``master``, use the extension ``master`` branch (ie no branch defined):: - (pyenv) $ pip install -e git+https://github.com/okfn/ckanext-spatial.git#egg=ckanext-spatial + (pyenv) $ pip install -e "git+https://github.com/okfn/ckanext-spatial.git#egg=ckanext-spatial" 2. Install the rest of python modules required by the extension:: From d047a90a2cc492f289beafee6165d717d86ed347 Mon Sep 17 00:00:00 2001 From: Tobias Preuss Date: Wed, 9 Apr 2014 10:43:26 +0200 Subject: [PATCH 110/114] Describe how to change ownership in more detail. --- doc/install.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/install.rst b/doc/install.rst index af67b06..af07be1 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -39,6 +39,16 @@ All commands assume an existing CKAN database named ``ckan_default``. #. Change the owner to spatial tables to the CKAN user to avoid errors later on:: + + Open the Postgres console:: + + $ sudo -u postgres psql + + Connect to the ``ckan_default`` database:: + + postgres=# \c ckan_default + + Change the ownership for two spatial tables:: ALTER TABLE spatial_ref_sys OWNER TO ckan_default; ALTER TABLE geometry_columns OWNER TO ckan_default; From 2c87e31721bd6cc36ea1877eddc80227fd5c5026 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Wed, 9 Apr 2014 07:41:15 -0400 Subject: [PATCH 111/114] bump pycsw requirement to 1.8.0 which eliminates the pycsw model definition issue --- doc/csw.rst | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/doc/csw.rst b/doc/csw.rst index 8385725..0b728ce 100644 --- a/doc/csw.rst +++ b/doc/csw.rst @@ -64,7 +64,7 @@ Setup 1. Install pycsw. There are several options for this, depending on your server setup, check the `pycsw documentation`_. - .. note:: CKAN integration requires at least pycsw version 1.6.1. Make sure + .. note:: CKAN integration requires at least pycsw version 1.8.0. Make sure to install at least this version. The following instructions assume that you have installed CKAN via a @@ -78,8 +78,8 @@ Setup git clone https://github.com/geopython/pycsw.git cd pycsw - # Remember to use at least pycsw 1.6.1 - git checkout 1.6.1 + # Remember to use at least pycsw 1.8.0 + git checkout 1.8.0 pip install -e . python setup.py build python setup.py install @@ -137,13 +137,6 @@ Setup cd /usr/lib/ckan/default/src/ckanext-spatial paster ckan-pycsw load -p /etc/ckan/default/pycsw.cfg - .. note:: If you get errors similar to this one, this is caused by - limitations on the pycsw model definition. This should be fixed in - future versions of pycsw:: - - ERROR: not inserted f8d48eaf-780b-40b8-a502-7a903fde5b1c Error:ERROR: value too long for type character varying(256) - - When the loading is finished, check that results are returned when visiting this link: From e19ed8100f5e527779ca0d7c9a0362d4e24ecc53 Mon Sep 17 00:00:00 2001 From: amercader Date: Mon, 28 Apr 2014 17:25:17 +0100 Subject: [PATCH 112/114] [#62] Fix xpath for Alternate Title --- ckanext/spatial/model/harvested_metadata.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ckanext/spatial/model/harvested_metadata.py b/ckanext/spatial/model/harvested_metadata.py index 0c3a82c..aa15b82 100644 --- a/ckanext/spatial/model/harvested_metadata.py +++ b/ckanext/spatial/model/harvested_metadata.py @@ -534,10 +534,10 @@ class ISODocument(MappedXmlDocument): multiplicity="1", ), ISOElement( - name="alternative-title", + name="alternate-title", search_paths=[ - "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:alternativeTitle/gco:CharacterString/text()", - "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:citation/gmd:CI_Citation/gmd:alternativeTitle/gco:CharacterString/text()", + "gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:alternateTitle/gco:CharacterString/text()", + "gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:citation/gmd:CI_Citation/gmd:alternateTitle/gco:CharacterString/text()", ], multiplicity="*", ), From ab241d2530400008925b585640d23d4c2fea643c Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 13 May 2014 15:30:34 +0100 Subject: [PATCH 113/114] Pass defer_commit in context on get_site_user calls See ckan/ckan#1714. Until that is fixed properly, the `defer_commit` flag avoids some `DetachedInstanceErrors` happening during the harvesting. --- ckanext/spatial/harvesters/base.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ckanext/spatial/harvesters/base.py b/ckanext/spatial/harvesters/base.py index 9122b61..7fb946b 100644 --- a/ckanext/spatial/harvesters/base.py +++ b/ckanext/spatial/harvesters/base.py @@ -655,7 +655,11 @@ class SpatialHarvester(HarvesterBase): if self._user_name: return self._user_name - self._site_user = p.toolkit.get_action('get_site_user')({'model': model, 'ignore_auth': True}, {}) + context = {'model': model, + 'ignore_auth': True, + 'defer_commit': True, # See ckan/ckan#1714 + } + self._site_user = p.toolkit.get_action('get_site_user')(context, {}) config_user_name = config.get('ckanext.spatial.harvest.user_name') if config_user_name: From fa4161af8714106e10b724afe775674473993e9c Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 13 May 2014 17:53:18 +0100 Subject: [PATCH 114/114] [#70] Fix deletion of harvested CSW records The object id was pushed to the list returned by gather_stage before being saved on the db, so None was added, causing an exception in the Redis queue --- ckanext/spatial/harvesters/csw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ckanext/spatial/harvesters/csw.py b/ckanext/spatial/harvesters/csw.py index 464842d..b33ecf6 100644 --- a/ckanext/spatial/harvesters/csw.py +++ b/ckanext/spatial/harvesters/csw.py @@ -130,11 +130,11 @@ class CSWHarvester(SpatialHarvester, SingletonPlugin): obj = HarvestObject(guid=guid, job=harvest_job, package_id=guid_to_package_id[guid], extras=[HOExtra(key='status', value='delete')]) - ids.append(obj.id) model.Session.query(HarvestObject).\ filter_by(guid=guid).\ update({'current': False}, False) obj.save() + ids.append(obj.id) if len(ids) == 0: self._save_gather_error('No records received from the CSW server', harvest_job)

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 E2SfY&RsaA1 literal 0 HcmV?d00001 diff --git a/doc/_static/spatial-search-widget.png b/doc/_static/spatial-search-widget.png new file mode 100644 index 0000000000000000000000000000000000000000..6b83ce6d464a6143eebb3ebb1e54c67e97243a21 GIT binary patch literal 80182 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 Open Knowledge Foundation project.