Repository: geopython/pycsw Branch: master Commit: 0f25925c59ee Files: 1359 Total size: 9.3 MB Directory structure: gitextract_p9bcr3yi/ ├── .coveragerc ├── .dockerignore ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE.md │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows/ │ ├── docker.yml │ ├── ghcr.yml │ ├── main.yml │ ├── stale.yml │ └── vulnerabilities.yml ├── .gitignore ├── .readthedocs.yaml ├── CODE_OF_CONDUCT.md ├── COMMITTERS.txt ├── CONTRIBUTING.rst ├── Dockerfile ├── HISTORY.txt ├── LICENSE.txt ├── MANIFEST.in ├── README.md ├── SECURITY.md ├── csw.py ├── default-sample.yml ├── docker/ │ ├── compose/ │ │ ├── docker-compose.scale.yml │ │ ├── docker-compose.yml │ │ └── pycsw.yml │ ├── entrypoint.py │ ├── helm/ │ │ ├── Chart.yaml │ │ ├── README.md │ │ ├── templates/ │ │ │ ├── db-data-persistentvolumeclaim.yaml │ │ │ ├── db-service.yaml │ │ │ ├── db-statefulset.yaml │ │ │ ├── pycsw-configmap.yaml │ │ │ ├── pycsw-deployment.yaml │ │ │ └── pycsw-service.yaml │ │ └── values.yaml │ ├── kubernetes/ │ │ ├── Makefile │ │ ├── db-data-persistentvolumeclaim.yaml │ │ ├── db-deployment.yaml │ │ ├── db-service.yaml │ │ ├── pycsw-configmap.yaml │ │ ├── pycsw-deployment.yaml │ │ └── pycsw-service.yaml │ ├── min-apk │ └── pycsw.yml ├── docs/ │ ├── Makefile │ ├── _static/ │ │ └── favicon/ │ │ └── browserconfig.xml │ ├── _templates/ │ │ ├── indexsidebar.html │ │ └── layout.html │ ├── administration.rst │ ├── api.rst │ ├── ckan.rst │ ├── committers.rst │ ├── conf.py │ ├── configuration.rst │ ├── contributing.rst │ ├── csw-support.rst │ ├── distributedsearching.rst │ ├── docker.rst │ ├── geonode.rst │ ├── hhypermap.rst │ ├── html-templating.rst │ ├── index.rst │ ├── installation.rst │ ├── introduction.rst │ ├── json.rst │ ├── license.rst │ ├── locale/ │ │ ├── el/ │ │ │ └── LC_MESSAGES/ │ │ │ └── .gitkeep │ │ ├── fr/ │ │ │ └── LC_MESSAGES/ │ │ │ └── .gitkeep │ │ └── zh/ │ │ └── LC_MESSAGES/ │ │ ├── administration.po │ │ ├── api.po │ │ ├── ckan.po │ │ ├── committers.po │ │ ├── configuration.po │ │ ├── contributing.po │ │ ├── csw-support.po │ │ ├── distributedsearching.po │ │ ├── docker.po │ │ ├── geonode.po │ │ ├── hhypermap.po │ │ ├── index.po │ │ ├── installation.po │ │ ├── introduction.po │ │ ├── json.po │ │ ├── license.po │ │ ├── migration-guide.po │ │ ├── oaipmh.po │ │ ├── oarec-support.po │ │ ├── odc.po │ │ ├── opensearch.po │ │ ├── outputschemas.po │ │ ├── profiles.po │ │ ├── repofilters.po │ │ ├── repositories.po │ │ ├── sitemaps.po │ │ ├── soap.po │ │ ├── sru.po │ │ ├── stac.po │ │ ├── support.po │ │ ├── testing.po │ │ ├── tools.po │ │ └── transactions.po │ ├── metadata-model-reference.rst │ ├── migration-guide.rst │ ├── oaipmh.rst │ ├── oarec-support.rst │ ├── odc.rst │ ├── opensearch.rst │ ├── outputschemas.rst │ ├── profiles.rst │ ├── pubsub.rst │ ├── repofilters.rst │ ├── repositories.rst │ ├── requirements-mocked.txt │ ├── sitemaps.rst │ ├── soap.rst │ ├── sru.rst │ ├── stac.rst │ ├── support.rst │ ├── testing.rst │ ├── tools.rst │ ├── transactions.rst │ └── xslt.rst ├── etc/ │ ├── harvest-all.cron │ ├── mappings.py │ ├── migrations/ │ │ └── 2.x-3.0/ │ │ └── migrate.sql │ ├── pycsw │ ├── pycsw.conf │ └── pycsw.desktop ├── pycsw/ │ ├── __init__.py │ ├── broker/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── http.py │ │ └── mqtt.py │ ├── core/ │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── config.py │ │ ├── etree.py │ │ ├── formats/ │ │ │ ├── __init__.py │ │ │ └── fmt_json.py │ │ ├── log.py │ │ ├── metadata.py │ │ ├── pygeofilter_evaluate.py │ │ ├── repository.py │ │ ├── schemas/ │ │ │ ├── catalog.xml │ │ │ ├── ogc/ │ │ │ │ ├── OGC-SOFTWARE-NOTICE.txt │ │ │ │ ├── README.txt │ │ │ │ ├── cat/ │ │ │ │ │ └── csw/ │ │ │ │ │ └── 3.0/ │ │ │ │ │ ├── README.txt │ │ │ │ │ ├── _wrapper.xsd │ │ │ │ │ ├── cswAll.xsd │ │ │ │ │ ├── cswCommon.xsd │ │ │ │ │ ├── cswGetCapabilities.xsd │ │ │ │ │ ├── cswGetDomain.xsd │ │ │ │ │ ├── cswGetRecordById.xsd │ │ │ │ │ ├── cswGetRecords.xsd │ │ │ │ │ ├── cswHarvest.xsd │ │ │ │ │ ├── cswTransaction.xsd │ │ │ │ │ ├── cswUnHarvest.xsd │ │ │ │ │ ├── rec-dcmes.xsd │ │ │ │ │ ├── rec-dcterms.xsd │ │ │ │ │ └── record.xsd │ │ │ │ ├── csw/ │ │ │ │ │ └── 2.0.2/ │ │ │ │ │ ├── CSW-discovery.xsd │ │ │ │ │ ├── CSW-publication.xsd │ │ │ │ │ ├── rec-dcmes.xsd │ │ │ │ │ ├── rec-dcterms.xsd │ │ │ │ │ └── record.xsd │ │ │ │ ├── filter/ │ │ │ │ │ ├── 1.1.0/ │ │ │ │ │ │ ├── expr.xsd │ │ │ │ │ │ ├── filter.xsd │ │ │ │ │ │ ├── filterCapabilities.xsd │ │ │ │ │ │ └── sort.xsd │ │ │ │ │ └── 2.0/ │ │ │ │ │ ├── _wrapper.xsd │ │ │ │ │ ├── expr.xsd │ │ │ │ │ ├── filter.xsd │ │ │ │ │ ├── filterAll.xsd │ │ │ │ │ ├── filterCapabilities.xsd │ │ │ │ │ ├── query.xsd │ │ │ │ │ └── sort.xsd │ │ │ │ ├── gml/ │ │ │ │ │ ├── 3.1.1/ │ │ │ │ │ │ ├── base/ │ │ │ │ │ │ │ ├── basicTypes.xsd │ │ │ │ │ │ │ ├── coordinateOperations.xsd │ │ │ │ │ │ │ ├── coordinateReferenceSystems.xsd │ │ │ │ │ │ │ ├── coordinateSystems.xsd │ │ │ │ │ │ │ ├── coverage.xsd │ │ │ │ │ │ │ ├── dataQuality.xsd │ │ │ │ │ │ │ ├── datums.xsd │ │ │ │ │ │ │ ├── defaultStyle.xsd │ │ │ │ │ │ │ ├── dictionary.xsd │ │ │ │ │ │ │ ├── direction.xsd │ │ │ │ │ │ │ ├── dynamicFeature.xsd │ │ │ │ │ │ │ ├── feature.xsd │ │ │ │ │ │ │ ├── geometryAggregates.xsd │ │ │ │ │ │ │ ├── geometryBasic0d1d.xsd │ │ │ │ │ │ │ ├── geometryBasic2d.xsd │ │ │ │ │ │ │ ├── geometryComplexes.xsd │ │ │ │ │ │ │ ├── geometryPrimitives.xsd │ │ │ │ │ │ │ ├── gml.xsd │ │ │ │ │ │ │ ├── gmlBase.xsd │ │ │ │ │ │ │ ├── grids.xsd │ │ │ │ │ │ │ ├── measures.xsd │ │ │ │ │ │ │ ├── observation.xsd │ │ │ │ │ │ │ ├── referenceSystems.xsd │ │ │ │ │ │ │ ├── temporal.xsd │ │ │ │ │ │ │ ├── temporalReferenceSystems.xsd │ │ │ │ │ │ │ ├── temporalTopology.xsd │ │ │ │ │ │ │ ├── topology.xsd │ │ │ │ │ │ │ ├── units.xsd │ │ │ │ │ │ │ └── valueObjects.xsd │ │ │ │ │ │ └── smil/ │ │ │ │ │ │ ├── smil20-language.xsd │ │ │ │ │ │ └── smil20.xsd │ │ │ │ │ └── 3.2.1/ │ │ │ │ │ ├── SchematronConstraints.xml │ │ │ │ │ ├── basicTypes.xsd │ │ │ │ │ ├── coordinateOperations.xsd │ │ │ │ │ ├── coordinateReferenceSystems.xsd │ │ │ │ │ ├── coordinateSystems.xsd │ │ │ │ │ ├── coverage.xsd │ │ │ │ │ ├── datums.xsd │ │ │ │ │ ├── defaultStyle.xsd │ │ │ │ │ ├── deprecatedTypes.xsd │ │ │ │ │ ├── dictionary.xsd │ │ │ │ │ ├── direction.xsd │ │ │ │ │ ├── dynamicFeature.xsd │ │ │ │ │ ├── feature.xsd │ │ │ │ │ ├── geometryAggregates.xsd │ │ │ │ │ ├── geometryBasic0d1d.xsd │ │ │ │ │ ├── geometryBasic2d.xsd │ │ │ │ │ ├── geometryComplexes.xsd │ │ │ │ │ ├── geometryPrimitives.xsd │ │ │ │ │ ├── gml.xsd │ │ │ │ │ ├── gmlBase.xsd │ │ │ │ │ ├── gml_32_geometries.rdf │ │ │ │ │ ├── gml_3_2_1-ReadMe.txt │ │ │ │ │ ├── grids.xsd │ │ │ │ │ ├── measures.xsd │ │ │ │ │ ├── observation.xsd │ │ │ │ │ ├── referenceSystems.xsd │ │ │ │ │ ├── temporal.xsd │ │ │ │ │ ├── temporalReferenceSystems.xsd │ │ │ │ │ ├── temporalTopology.xsd │ │ │ │ │ ├── topology.xsd │ │ │ │ │ ├── units.xsd │ │ │ │ │ └── valueObjects.xsd │ │ │ │ ├── ogcapi/ │ │ │ │ │ └── records/ │ │ │ │ │ └── part1/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ └── ogcapi-records-1.yaml │ │ │ │ └── ows/ │ │ │ │ ├── 1.0.0/ │ │ │ │ │ ├── ows19115subset.xsd │ │ │ │ │ ├── owsAll.xsd │ │ │ │ │ ├── owsCommon.xsd │ │ │ │ │ ├── owsDataIdentification.xsd │ │ │ │ │ ├── owsExceptionReport.xsd │ │ │ │ │ ├── owsGetCapabilities.xsd │ │ │ │ │ ├── owsOperationsMetadata.xsd │ │ │ │ │ ├── owsServiceIdentification.xsd │ │ │ │ │ └── owsServiceProvider.xsd │ │ │ │ ├── 1.1.0/ │ │ │ │ │ ├── ows19115subset.xsd │ │ │ │ │ ├── owsAll.xsd │ │ │ │ │ ├── owsCommon.xsd │ │ │ │ │ ├── owsContents.xsd │ │ │ │ │ ├── owsDataIdentification.xsd │ │ │ │ │ ├── owsDomainType.xsd │ │ │ │ │ ├── owsExceptionReport.xsd │ │ │ │ │ ├── owsGetCapabilities.xsd │ │ │ │ │ ├── owsGetResourceByID.xsd │ │ │ │ │ ├── owsInputOutputData.xsd │ │ │ │ │ ├── owsManifest.xsd │ │ │ │ │ ├── owsOperationsMetadata.xsd │ │ │ │ │ ├── owsServiceIdentification.xsd │ │ │ │ │ └── owsServiceProvider.xsd │ │ │ │ └── 2.0/ │ │ │ │ ├── ows19115subset.xsd │ │ │ │ ├── owsAdditionalParameters.xsd │ │ │ │ ├── owsAll.xsd │ │ │ │ ├── owsCommon.xsd │ │ │ │ ├── owsContents.xsd │ │ │ │ ├── owsDataIdentification.xsd │ │ │ │ ├── owsDomainType.xsd │ │ │ │ ├── owsExceptionReport.xsd │ │ │ │ ├── owsGetCapabilities.xsd │ │ │ │ ├── owsGetResourceByID.xsd │ │ │ │ ├── owsInputOutputData.xsd │ │ │ │ ├── owsManifest.xsd │ │ │ │ ├── owsOperationsMetadata.xsd │ │ │ │ ├── owsServiceIdentification.xsd │ │ │ │ └── owsServiceProvider.xsd │ │ │ └── w3c/ │ │ │ ├── 1999/ │ │ │ │ └── xlink.xsd │ │ │ └── 2001/ │ │ │ └── xml.xsd │ │ └── util.py │ ├── oaipmh.py │ ├── ogc/ │ │ ├── __init__.py │ │ ├── api/ │ │ │ ├── __init__.py │ │ │ ├── oapi.py │ │ │ ├── records.py │ │ │ └── util.py │ │ ├── csw/ │ │ │ ├── __init__.py │ │ │ ├── cql.py │ │ │ ├── csw2.py │ │ │ └── csw3.py │ │ ├── fes/ │ │ │ ├── __init__.py │ │ │ ├── fes1.py │ │ │ └── fes2.py │ │ ├── gml/ │ │ │ ├── __init__.py │ │ │ ├── gml3.py │ │ │ └── gml32.py │ │ └── pubsub/ │ │ └── __init__.py │ ├── opensearch.py │ ├── plugins/ │ │ ├── __init__.py │ │ ├── outputschemas/ │ │ │ ├── __init__.py │ │ │ ├── atom.py │ │ │ ├── datacite.py │ │ │ ├── dif.py │ │ │ ├── fgdc.py │ │ │ └── gm03.py │ │ ├── profiles/ │ │ │ ├── __init__.py │ │ │ ├── apiso/ │ │ │ │ ├── __init__.py │ │ │ │ ├── apiso.py │ │ │ │ ├── docs/ │ │ │ │ │ └── apiso.rst │ │ │ │ └── schemas/ │ │ │ │ └── ogc/ │ │ │ │ ├── csw/ │ │ │ │ │ └── 2.0.2/ │ │ │ │ │ └── profiles/ │ │ │ │ │ └── apiso/ │ │ │ │ │ └── 1.0.0/ │ │ │ │ │ ├── ReadMe.txt │ │ │ │ │ └── apiso.xsd │ │ │ │ └── iso/ │ │ │ │ └── 19139/ │ │ │ │ ├── 20060504/ │ │ │ │ │ ├── ReadMe.txt │ │ │ │ │ ├── Version.txt │ │ │ │ │ ├── gco/ │ │ │ │ │ │ ├── basicTypes.xsd │ │ │ │ │ │ ├── gco.xsd │ │ │ │ │ │ └── gcoBase.xsd │ │ │ │ │ ├── gmd/ │ │ │ │ │ │ ├── applicationSchema.xsd │ │ │ │ │ │ ├── citation.xsd │ │ │ │ │ │ ├── constraints.xsd │ │ │ │ │ │ ├── content.xsd │ │ │ │ │ │ ├── dataQuality.xsd │ │ │ │ │ │ ├── distribution.xsd │ │ │ │ │ │ ├── extent.xsd │ │ │ │ │ │ ├── freeText.xsd │ │ │ │ │ │ ├── gmd.xsd │ │ │ │ │ │ ├── identification.xsd │ │ │ │ │ │ ├── maintenance.xsd │ │ │ │ │ │ ├── metadataApplication.xsd │ │ │ │ │ │ ├── metadataEntity.xsd │ │ │ │ │ │ ├── metadataExtension.xsd │ │ │ │ │ │ ├── portrayalCatalogue.xsd │ │ │ │ │ │ ├── referenceSystem.xsd │ │ │ │ │ │ └── spatialRepresentation.xsd │ │ │ │ │ ├── gml/ │ │ │ │ │ │ ├── ReadMe.txt │ │ │ │ │ │ ├── basicTypes.xsd │ │ │ │ │ │ ├── coordinateOperations.xsd │ │ │ │ │ │ ├── coordinateReferenceSystems.xsd │ │ │ │ │ │ ├── coordinateSystems.xsd │ │ │ │ │ │ ├── coverage.xsd │ │ │ │ │ │ ├── datums.xsd │ │ │ │ │ │ ├── dictionary.xsd │ │ │ │ │ │ ├── direction.xsd │ │ │ │ │ │ ├── dynamicFeature.xsd │ │ │ │ │ │ ├── feature.xsd │ │ │ │ │ │ ├── geometryAggregates.xsd │ │ │ │ │ │ ├── geometryBasic0d1d.xsd │ │ │ │ │ │ ├── geometryBasic2d.xsd │ │ │ │ │ │ ├── geometryComplexes.xsd │ │ │ │ │ │ ├── geometryPrimitives.xsd │ │ │ │ │ │ ├── gml.xsd │ │ │ │ │ │ ├── gmlBase.xsd │ │ │ │ │ │ ├── grids.xsd │ │ │ │ │ │ ├── measures.xsd │ │ │ │ │ │ ├── observation.xsd │ │ │ │ │ │ ├── referenceSystems.xsd │ │ │ │ │ │ ├── temporal.xsd │ │ │ │ │ │ ├── temporalReferenceSystems.xsd │ │ │ │ │ │ ├── temporalTopology.xsd │ │ │ │ │ │ ├── topology.xsd │ │ │ │ │ │ ├── units.xsd │ │ │ │ │ │ └── valueObjects.xsd │ │ │ │ │ ├── gmx/ │ │ │ │ │ │ ├── catalogues.xsd │ │ │ │ │ │ ├── codelistItem.xsd │ │ │ │ │ │ ├── crsItem.xsd │ │ │ │ │ │ ├── extendedTypes.xsd │ │ │ │ │ │ ├── gmx.xsd │ │ │ │ │ │ ├── gmxUsage.xsd │ │ │ │ │ │ └── uomItem.xsd │ │ │ │ │ ├── gsr/ │ │ │ │ │ │ ├── gsr.xsd │ │ │ │ │ │ └── spatialReferencing.xsd │ │ │ │ │ ├── gss/ │ │ │ │ │ │ ├── geometry.xsd │ │ │ │ │ │ └── gss.xsd │ │ │ │ │ ├── gts/ │ │ │ │ │ │ ├── gts.xsd │ │ │ │ │ │ └── temporalObjects.xsd │ │ │ │ │ ├── resources/ │ │ │ │ │ │ ├── Codelist/ │ │ │ │ │ │ │ ├── ML_gmxCodelists.xml │ │ │ │ │ │ │ └── gmxCodelists.xml │ │ │ │ │ │ ├── crs/ │ │ │ │ │ │ │ ├── ML_gmxCrs.xml │ │ │ │ │ │ │ └── gmxCrs.xml │ │ │ │ │ │ ├── example/ │ │ │ │ │ │ │ └── fr-fr.xml │ │ │ │ │ │ └── uom/ │ │ │ │ │ │ ├── ML_gmxUom.xml │ │ │ │ │ │ └── gmxUom.xml │ │ │ │ │ └── srv/ │ │ │ │ │ ├── serviceMetadata.xsd │ │ │ │ │ ├── serviceModel.xsd │ │ │ │ │ └── srv.xsd │ │ │ │ └── 20070417/ │ │ │ │ ├── ReadMe.txt │ │ │ │ ├── gco/ │ │ │ │ │ ├── ReadMe.txt │ │ │ │ │ ├── basicTypes.xsd │ │ │ │ │ ├── gco.xsd │ │ │ │ │ └── gcoBase.xsd │ │ │ │ ├── gmd/ │ │ │ │ │ ├── ReadMe.txt │ │ │ │ │ ├── applicationSchema.xsd │ │ │ │ │ ├── citation.xsd │ │ │ │ │ ├── constraints.xsd │ │ │ │ │ ├── content.xsd │ │ │ │ │ ├── dataQuality.xsd │ │ │ │ │ ├── distribution.xsd │ │ │ │ │ ├── extent.xsd │ │ │ │ │ ├── freeText.xsd │ │ │ │ │ ├── gmd.xsd │ │ │ │ │ ├── identification.xsd │ │ │ │ │ ├── maintenance.xsd │ │ │ │ │ ├── metadataApplication.xsd │ │ │ │ │ ├── metadataEntity.xsd │ │ │ │ │ ├── metadataExtension.xsd │ │ │ │ │ ├── portrayalCatalogue.xsd │ │ │ │ │ ├── referenceSystem.xsd │ │ │ │ │ └── spatialRepresentation.xsd │ │ │ │ ├── gmx/ │ │ │ │ │ ├── ReadMe.txt │ │ │ │ │ ├── catalogues.xsd │ │ │ │ │ ├── codelistItem.xsd │ │ │ │ │ ├── crsItem.xsd │ │ │ │ │ ├── extendedTypes.xsd │ │ │ │ │ ├── gmx.xsd │ │ │ │ │ ├── gmxUsage.xsd │ │ │ │ │ └── uomItem.xsd │ │ │ │ ├── gsr/ │ │ │ │ │ ├── ReadMe.txt │ │ │ │ │ ├── gsr.xsd │ │ │ │ │ └── spatialReferencing.xsd │ │ │ │ ├── gss/ │ │ │ │ │ ├── ReadMe.txt │ │ │ │ │ ├── geometry.xsd │ │ │ │ │ └── gss.xsd │ │ │ │ ├── gts/ │ │ │ │ │ ├── ReadMe.txt │ │ │ │ │ ├── gts.xsd │ │ │ │ │ └── temporalObjects.xsd │ │ │ │ └── resources/ │ │ │ │ ├── ReadMe.txt │ │ │ │ ├── codelist/ │ │ │ │ │ ├── ML_gmxCodelists.xml │ │ │ │ │ ├── gmxCodelists.xml │ │ │ │ │ └── tcCodelists.xml │ │ │ │ ├── crs/ │ │ │ │ │ ├── ML_gmxCrs.xml │ │ │ │ │ └── gmxCrs.xml │ │ │ │ ├── example/ │ │ │ │ │ └── fr-fr.xml │ │ │ │ └── uom/ │ │ │ │ ├── ML_gmxUom.xml │ │ │ │ └── gmxUom.xml │ │ │ ├── ebrim/ │ │ │ │ ├── __init__.py │ │ │ │ ├── docs/ │ │ │ │ │ └── ebrim.rst │ │ │ │ ├── ebrim.py │ │ │ │ └── schemas/ │ │ │ │ └── ogc/ │ │ │ │ └── csw/ │ │ │ │ └── 2.0.2/ │ │ │ │ └── profiles/ │ │ │ │ └── ebrim/ │ │ │ │ └── 1.0/ │ │ │ │ ├── csw-ebrim-iri.xsd │ │ │ │ ├── csw-ebrim.xsd │ │ │ │ └── wsdl/ │ │ │ │ ├── 1.1/ │ │ │ │ │ ├── csw-ebrim-binding.wsdl │ │ │ │ │ ├── csw-ebrim-interface.wsdl │ │ │ │ │ └── csw-ebrim-service.wsdl │ │ │ │ └── 2.0/ │ │ │ │ └── csw-ebrim-interface.wsdl │ │ │ ├── iso19115p3/ │ │ │ │ ├── __init__.py │ │ │ │ ├── iso19115p3.py │ │ │ │ └── schemas/ │ │ │ │ └── ogc/ │ │ │ │ └── iso/ │ │ │ │ └── iso19115-3/ │ │ │ │ ├── cat/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── cat.xsd │ │ │ │ │ ├── catalogues.xsd │ │ │ │ │ ├── codelistItem.xsd │ │ │ │ │ ├── crsItem.xsd │ │ │ │ │ └── uomItem.xsd │ │ │ │ ├── cit/ │ │ │ │ │ ├── 1.0/ │ │ │ │ │ │ ├── cit.sch │ │ │ │ │ │ ├── cit.xsd │ │ │ │ │ │ └── citation.xsd │ │ │ │ │ └── 2.0/ │ │ │ │ │ ├── cit.xsd │ │ │ │ │ └── citation.xsd │ │ │ │ ├── gco/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── baseTypes2014.xsd │ │ │ │ │ └── gco.xsd │ │ │ │ ├── gcx/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── extendedTypes.xsd │ │ │ │ │ ├── extendedTypes_autoFromShapeChange.xsd │ │ │ │ │ └── gcx.xsd │ │ │ │ ├── gex/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── extent.xsd │ │ │ │ │ ├── gex.sch │ │ │ │ │ └── gex.xsd │ │ │ │ ├── gmw/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── gmlWrapperTypes2014.xsd │ │ │ │ │ └── gmw.xsd │ │ │ │ ├── lan/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── lan.xsd │ │ │ │ │ └── language.xsd │ │ │ │ ├── mac/ │ │ │ │ │ ├── 1.0/ │ │ │ │ │ │ ├── acquisitionInformationImagery.xsd │ │ │ │ │ │ └── mac.xsd │ │ │ │ │ └── 2.0/ │ │ │ │ │ ├── acquisitionInformationImagery.xsd │ │ │ │ │ ├── event.xsd │ │ │ │ │ └── mac.xsd │ │ │ │ ├── mas/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── applicationSchema.xsd │ │ │ │ │ └── mas.xsd │ │ │ │ ├── mcc/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── AbstractCommonClasses.xsd │ │ │ │ │ ├── commonClasses.xsd │ │ │ │ │ └── mcc.xsd │ │ │ │ ├── mco/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── constraints.xsd │ │ │ │ │ ├── mco.sch │ │ │ │ │ └── mco.xsd │ │ │ │ ├── md1/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── md1.xsd │ │ │ │ │ └── metadataWExtendedType.xsd │ │ │ │ ├── md2/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── md2.xsd │ │ │ │ │ └── metadataWithExtensions.xsd │ │ │ │ ├── mda/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── mda.xsd │ │ │ │ │ └── metadataApplication.xsd │ │ │ │ ├── mdb/ │ │ │ │ │ ├── 1.0/ │ │ │ │ │ │ ├── mdb.sch │ │ │ │ │ │ ├── mdb.xsd │ │ │ │ │ │ └── metadataBase.xsd │ │ │ │ │ └── 2.0/ │ │ │ │ │ ├── mdb.sch │ │ │ │ │ ├── mdb.xsd │ │ │ │ │ └── metadataBase.xsd │ │ │ │ ├── mds/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── mds.xsd │ │ │ │ │ └── metadataDataServices.xsd │ │ │ │ ├── mdt/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── mdt.xsd │ │ │ │ │ └── metadataTransfer.xsd │ │ │ │ ├── mex/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── metadataExtension.xsd │ │ │ │ │ ├── mex.sch │ │ │ │ │ └── mex.xsd │ │ │ │ ├── mmi/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── maintenance.xsd │ │ │ │ │ ├── mmi.sch │ │ │ │ │ └── mmi.xsd │ │ │ │ ├── mpc/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── mpc.xsd │ │ │ │ │ └── portrayalCatalogue.xsd │ │ │ │ ├── mrc/ │ │ │ │ │ ├── 1.0/ │ │ │ │ │ │ ├── content.xsd │ │ │ │ │ │ ├── contentInformationImagery.xsd │ │ │ │ │ │ ├── mrc.sch │ │ │ │ │ │ └── mrc.xsd │ │ │ │ │ └── 2.0/ │ │ │ │ │ ├── content.xsd │ │ │ │ │ ├── contentInformationImagery.xsd │ │ │ │ │ └── mrc.xsd │ │ │ │ ├── mrd/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── distribution.xsd │ │ │ │ │ ├── mrd.sch │ │ │ │ │ └── mrd.xsd │ │ │ │ ├── mri/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── identification.xsd │ │ │ │ │ ├── mri.sch │ │ │ │ │ └── mri.xsd │ │ │ │ ├── mrl/ │ │ │ │ │ ├── 1.0/ │ │ │ │ │ │ ├── lineage.xsd │ │ │ │ │ │ ├── lineageImagery.xsd │ │ │ │ │ │ └── mrl.xsd │ │ │ │ │ └── 2.0/ │ │ │ │ │ ├── lineage.xsd │ │ │ │ │ ├── lineageImagery.xsd │ │ │ │ │ └── mrl.xsd │ │ │ │ ├── mrs/ │ │ │ │ │ └── 1.0/ │ │ │ │ │ ├── mrs.sch │ │ │ │ │ ├── mrs.xsd │ │ │ │ │ └── referenceSystem.xsd │ │ │ │ ├── msr/ │ │ │ │ │ ├── 1.0/ │ │ │ │ │ │ ├── msr.xsd │ │ │ │ │ │ ├── spatialRepresentation.xsd │ │ │ │ │ │ └── spatialRepresentationImagery.xsd │ │ │ │ │ └── 2.0/ │ │ │ │ │ ├── msr.xsd │ │ │ │ │ ├── spatialRepresentation.xsd │ │ │ │ │ └── spatialRepresentationImagery.xsd │ │ │ │ └── srv/ │ │ │ │ ├── 2.0/ │ │ │ │ │ ├── serviceInformation.xsd │ │ │ │ │ ├── srv.sch │ │ │ │ │ └── srv.xsd │ │ │ │ └── 2.1/ │ │ │ │ ├── serviceInformation.xsd │ │ │ │ └── srv.xsd │ │ │ └── profile.py │ │ └── repository/ │ │ ├── __init__.py │ │ └── odc/ │ │ ├── __init__.py │ │ └── odc.py │ ├── server.py │ ├── sru.py │ ├── stac/ │ │ ├── __init__.py │ │ └── api.py │ ├── templates/ │ │ ├── _base.html │ │ ├── collection.html │ │ ├── collections.html │ │ ├── conformance.html │ │ ├── exception.html │ │ ├── federatedcatalog.html │ │ ├── federatedcatalogs.html │ │ ├── item.html │ │ ├── items.html │ │ ├── landing_page.html │ │ ├── openapi.html │ │ ├── queryables.html │ │ └── stac_items.html │ ├── wsgi.py │ └── wsgi_flask.py ├── pyproject.toml ├── requirements-dev.txt ├── requirements-pg.txt ├── requirements-pubsub.txt ├── requirements-standalone.txt ├── requirements.txt ├── setup.py ├── tests/ │ ├── README.txt │ ├── conftest.py │ ├── functionaltests/ │ │ ├── conftest.py │ │ ├── suites/ │ │ │ ├── apiso/ │ │ │ │ ├── data/ │ │ │ │ │ ├── 3e9a8c05.xml │ │ │ │ │ ├── README.txt │ │ │ │ │ ├── T_aerfo_RAS_1991_GR800P001800000012.xml │ │ │ │ │ ├── T_aerfo_RAS_1991_GR800P001800000013.xml │ │ │ │ │ ├── T_aerfo_RAS_1991_GR800P001800000014.xml │ │ │ │ │ ├── T_aerfo_RAS_1991_GR800P001800000015.xml │ │ │ │ │ ├── T_ortho_RAS_1998_284404.xml │ │ │ │ │ ├── T_ortho_RAS_1998_288395.xml │ │ │ │ │ ├── T_ortho_RAS_1998_288398.xml │ │ │ │ │ ├── T_ortho_RAS_1998_288401.xml │ │ │ │ │ ├── T_ortho_RAS_1998_288404.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_276395.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_276398.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_276401.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_276404.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_280395.xml │ │ │ │ │ ├── iso_19115-2_Sentinel-2-scene.xml │ │ │ │ │ ├── pacioos-NS06agg.xml │ │ │ │ │ └── test.xml │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── post_DescribeRecord.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ ├── post_GetDomain-property.xml │ │ │ │ │ ├── post_GetRecordById-brief.xml │ │ │ │ │ ├── post_GetRecordById-full-dc.xml │ │ │ │ │ ├── post_GetRecordById-full.xml │ │ │ │ │ ├── post_GetRecordById-srv-brief.xml │ │ │ │ │ ├── post_GetRecords-all-csw-output.xml │ │ │ │ │ ├── post_GetRecords-all.xml │ │ │ │ │ ├── post_GetRecords-cql-title.xml │ │ │ │ │ ├── post_GetRecords-elementname.xml │ │ │ │ │ ├── post_GetRecords-filter-and-nested-spatial-or-dateline.xml │ │ │ │ │ ├── post_GetRecords-filter-anytext.xml │ │ │ │ │ ├── post_GetRecords-filter-bbox-csw-output.xml │ │ │ │ │ ├── post_GetRecords-filter-bbox.xml │ │ │ │ │ └── post_GetRecords-filter-servicetype.xml │ │ │ │ └── post/ │ │ │ │ ├── DescribeRecord.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ ├── GetDomain-property.xml │ │ │ │ ├── GetRecordById-brief.xml │ │ │ │ ├── GetRecordById-full-dc.xml │ │ │ │ ├── GetRecordById-full.xml │ │ │ │ ├── GetRecordById-srv-brief.xml │ │ │ │ ├── GetRecords-all-csw-output.xml │ │ │ │ ├── GetRecords-all.xml │ │ │ │ ├── GetRecords-cql-title.xml │ │ │ │ ├── GetRecords-elementname.xml │ │ │ │ ├── GetRecords-filter-and-nested-spatial-or-dateline.xml │ │ │ │ ├── GetRecords-filter-anytext.xml │ │ │ │ ├── GetRecords-filter-bbox-csw-output.xml │ │ │ │ ├── GetRecords-filter-bbox.xml │ │ │ │ └── GetRecords-filter-servicetype.xml │ │ │ ├── apiso-inspire/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_GetCapabilities-lang.xml │ │ │ │ │ └── get_GetCapabilities.xml │ │ │ │ └── get/ │ │ │ │ └── requests.txt │ │ │ ├── atom/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_opensearch-description.xml │ │ │ │ │ ├── get_opensearch-ogc-bbox-and-time.xml │ │ │ │ │ ├── get_opensearch-ogc-bbox.xml │ │ │ │ │ ├── get_opensearch-ogc-count-and-page1.xml │ │ │ │ │ ├── get_opensearch-ogc-count-and-page2.xml │ │ │ │ │ ├── get_opensearch-ogc-q-and-bbox.xml │ │ │ │ │ ├── get_opensearch-ogc-q-and-time.xml │ │ │ │ │ ├── get_opensearch-ogc-q.xml │ │ │ │ │ ├── get_opensearch-ogc-time.xml │ │ │ │ │ ├── get_opensearch-ogc-timeend.xml │ │ │ │ │ ├── get_opensearch-ogc-timestart.xml │ │ │ │ │ ├── get_opensearch.xml │ │ │ │ │ ├── post_DescribeRecord.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ └── post_GetRecords-filter-bbox.xml │ │ │ │ ├── get/ │ │ │ │ │ └── requests.txt │ │ │ │ └── post/ │ │ │ │ ├── DescribeRecord.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ └── GetRecords-filter-bbox.xml │ │ │ ├── cite/ │ │ │ │ ├── data/ │ │ │ │ │ ├── README.txt │ │ │ │ │ ├── Record_19887a8a-f6b0-4a63-ae56-7fba0e17801f.xml │ │ │ │ │ ├── Record_1ef30a8b-876d-4828-9246-c37ab4510bbd.xml │ │ │ │ │ ├── Record_66ae76b7-54ba-489b-a582-0f0633d96493.xml │ │ │ │ │ ├── Record_6a3de50b-fa66-4b58-a0e6-ca146fdd18d4.xml │ │ │ │ │ ├── Record_784e2afd-a9fd-44a6-9a92-a3848371c8ec.xml │ │ │ │ │ ├── Record_829babb0-b2f1-49e1-8cd5-7b489fe71a1e.xml │ │ │ │ │ ├── Record_88247b56-4cbc-4df9-9860-db3f8042e357.xml │ │ │ │ │ ├── Record_94bc9c83-97f6-4b40-9eb8-a8e8787a5c63.xml │ │ │ │ │ ├── Record_9a669547-b69b-469f-a11f-2d875366bbdc.xml │ │ │ │ │ ├── Record_a06af396-3105-442d-8b40-22b57a90d2f2.xml │ │ │ │ │ ├── Record_ab42a8c4-95e8-4630-bf79-33e59241605a.xml │ │ │ │ │ └── Record_e9330592-0932-474b-be34-c3a3bb67c7db.xml │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_27e17158-c57a-4493-92ac-dba8934cf462.xml │ │ │ │ │ ├── get_27f69b66-5f05-4311-a89c-73ca55c2686b.xml │ │ │ │ │ ├── get_2ab7d1fa-885b-459f-80e4-b6282eab4f8c.xml │ │ │ │ │ ├── get_37aa90e2-6ff0-420c-af15-8b9463099a73.xml │ │ │ │ │ ├── get_3a8a3c47-455f-4f49-9078-03119f3e70b3.xml │ │ │ │ │ ├── get_4515831f-834a-4699-95f6-ab0c2cbfcfd0.xml │ │ │ │ │ ├── get_477b23a3-baa9-47c8-9541-5fe27735ed49.xml │ │ │ │ │ ├── get_48f26761-3a9d-48db-bee1-da089f5fb857.xml │ │ │ │ │ ├── get_4e38092f-1586-44b8-988e-0acfa5855916.xml │ │ │ │ │ ├── get_55c38f00-2553-42c1-99ab-33edbb561ad7.xml │ │ │ │ │ ├── get_5ab5db18-c87a-4fbf-a8d8-b7289b09ac81.xml │ │ │ │ │ ├── get_6a4f57ca-a1bd-4802-89c2-44860dbdb0f0.xml │ │ │ │ │ ├── get_6c375703-9c00-4aef-bec7-d2e964f849eb.xml │ │ │ │ │ ├── get_80f31def-4185-48b9-983a-960566918eae.xml │ │ │ │ │ ├── get_8e2232ed-05d9-44ae-8b04-0911cbe6a507.xml │ │ │ │ │ ├── get_9697f0aa-3b6a-4125-83a5-61e8826127c4.xml │ │ │ │ │ ├── get_9bfd17fa-15dc-4a10-8fa7-b3cff7013dd7.xml │ │ │ │ │ ├── get_b81c3595-06d6-4693-82ea-1ff8650755ac.xml │ │ │ │ │ ├── get_ba5fc729-3b71-47a0-b7d0-42ec565cd185.xml │ │ │ │ │ ├── get_c4ea754f-c158-4d8d-8253-dc8f86021b52.xml │ │ │ │ │ ├── get_f4692ec5-9547-4a05-88ab-e6154af2640a.xml │ │ │ │ │ ├── get_f997f25e-c865-4d53-a362-0ed1846337f2.xml │ │ │ │ │ ├── post_0c976d98-c896-4b10-b1fe-a22ef50434e7.xml │ │ │ │ │ ├── post_19d2a6ed-be28-4866-ae15-e3bb634486cb.xml │ │ │ │ │ ├── post_1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml │ │ │ │ │ ├── post_1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml │ │ │ │ │ ├── post_1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml │ │ │ │ │ ├── post_2102a460-5d62-465f-9668-d70b3faafbfa.xml │ │ │ │ │ ├── post_225f455a-0035-486b-a94e-fee7ae881b2b.xml │ │ │ │ │ ├── post_2d53ffea-60e4-4652-abf5-36eb23042fd5.xml │ │ │ │ │ ├── post_34a019a9-1581-42cb-9827-fbfdda2773b7.xml │ │ │ │ │ ├── post_3e76fd38-e035-41c9-83dc-61356f680c97.xml │ │ │ │ │ ├── post_418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml │ │ │ │ │ ├── post_420b745e-0c4b-404e-9f2d-61fa580ff05a.xml │ │ │ │ │ ├── post_4735d649-a2b1-42fd-a101-14e1d7e4607f.xml │ │ │ │ │ ├── post_5c5861bc-f742-40a5-9998-5342615d674b.xml │ │ │ │ │ ├── post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml │ │ │ │ │ ├── post_73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml │ │ │ │ │ ├── post_78297c88-4850-4927-adc6-511cd9a3d539.xml │ │ │ │ │ ├── post_7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml │ │ │ │ │ ├── post_7e2cd105-daec-4d25-bc8e-d49d21364912.xml │ │ │ │ │ ├── post_87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml │ │ │ │ │ ├── post_88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml │ │ │ │ │ ├── post_898cd63b-2585-4ec0-8720-d554bd324174.xml │ │ │ │ │ ├── post_8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml │ │ │ │ │ ├── post_928c1896-52d4-4ac7-9832-f98e3eb65f02.xml │ │ │ │ │ ├── post_93bdbb9d-2734-4f01-92fb-48634cca41de.xml │ │ │ │ │ ├── post_948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml │ │ │ │ │ ├── post_9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml │ │ │ │ │ ├── post_a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml │ │ │ │ │ ├── post_ad61686c-d304-42d1-b845-8c1f3070c83e.xml │ │ │ │ │ ├── post_af39c020-7b1d-429c-b474-f45c3164cb79.xml │ │ │ │ │ ├── post_b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml │ │ │ │ │ ├── post_ba9b0107-dcee-46ef-823a-a2e25a911a96.xml │ │ │ │ │ ├── post_bb66ebc5-7121-48b5-9f53-b56537d9561b.xml │ │ │ │ │ ├── post_c02d1c85-df9f-45ee-bea7-345c35e02a98.xml │ │ │ │ │ ├── post_c311a342-72e3-4983-be39-868e6ed9740f.xml │ │ │ │ │ ├── post_c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml │ │ │ │ │ ├── post_c8588f47-8e65-45f5-ad34-ff4524cad84d.xml │ │ │ │ │ ├── post_da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml │ │ │ │ │ ├── post_dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml │ │ │ │ │ ├── post_dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml │ │ │ │ │ ├── post_e308f030-c097-4036-a838-44bad74c9ef7.xml │ │ │ │ │ ├── post_e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml │ │ │ │ │ ├── post_f7976c55-a156-4421-8199-bc0487da4b0f.xml │ │ │ │ │ ├── post_f7d79701-f10b-4087-a33c-f62df0a04fd1.xml │ │ │ │ │ ├── post_fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml │ │ │ │ │ └── post_fe20960f-a26c-4f13-852d-470a0d3233f9.xml │ │ │ │ ├── get/ │ │ │ │ │ └── requests.txt │ │ │ │ └── post/ │ │ │ │ ├── 0c976d98-c896-4b10-b1fe-a22ef50434e7.xml │ │ │ │ ├── 19d2a6ed-be28-4866-ae15-e3bb634486cb.xml │ │ │ │ ├── 1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml │ │ │ │ ├── 1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml │ │ │ │ ├── 1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml │ │ │ │ ├── 2102a460-5d62-465f-9668-d70b3faafbfa.xml │ │ │ │ ├── 225f455a-0035-486b-a94e-fee7ae881b2b.xml │ │ │ │ ├── 2d53ffea-60e4-4652-abf5-36eb23042fd5.xml │ │ │ │ ├── 34a019a9-1581-42cb-9827-fbfdda2773b7.xml │ │ │ │ ├── 3e76fd38-e035-41c9-83dc-61356f680c97.xml │ │ │ │ ├── 418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml │ │ │ │ ├── 420b745e-0c4b-404e-9f2d-61fa580ff05a.xml │ │ │ │ ├── 4735d649-a2b1-42fd-a101-14e1d7e4607f.xml │ │ │ │ ├── 5c5861bc-f742-40a5-9998-5342615d674b.xml │ │ │ │ ├── 6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml │ │ │ │ ├── 73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml │ │ │ │ ├── 78297c88-4850-4927-adc6-511cd9a3d539.xml │ │ │ │ ├── 7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml │ │ │ │ ├── 7e2cd105-daec-4d25-bc8e-d49d21364912.xml │ │ │ │ ├── 87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml │ │ │ │ ├── 88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml │ │ │ │ ├── 898cd63b-2585-4ec0-8720-d554bd324174.xml │ │ │ │ ├── 8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml │ │ │ │ ├── 928c1896-52d4-4ac7-9832-f98e3eb65f02.xml │ │ │ │ ├── 93bdbb9d-2734-4f01-92fb-48634cca41de.xml │ │ │ │ ├── 948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml │ │ │ │ ├── 9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml │ │ │ │ ├── a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml │ │ │ │ ├── ad61686c-d304-42d1-b845-8c1f3070c83e.xml │ │ │ │ ├── af39c020-7b1d-429c-b474-f45c3164cb79.xml │ │ │ │ ├── b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml │ │ │ │ ├── ba9b0107-dcee-46ef-823a-a2e25a911a96.xml │ │ │ │ ├── bb66ebc5-7121-48b5-9f53-b56537d9561b.xml │ │ │ │ ├── c02d1c85-df9f-45ee-bea7-345c35e02a98.xml │ │ │ │ ├── c311a342-72e3-4983-be39-868e6ed9740f.xml │ │ │ │ ├── c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml │ │ │ │ ├── c8588f47-8e65-45f5-ad34-ff4524cad84d.xml │ │ │ │ ├── da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml │ │ │ │ ├── dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml │ │ │ │ ├── dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml │ │ │ │ ├── e308f030-c097-4036-a838-44bad74c9ef7.xml │ │ │ │ ├── e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml │ │ │ │ ├── f7976c55-a156-4421-8199-bc0487da4b0f.xml │ │ │ │ ├── f7d79701-f10b-4087-a33c-f62df0a04fd1.xml │ │ │ │ ├── fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml │ │ │ │ └── fe20960f-a26c-4f13-852d-470a0d3233f9.xml │ │ │ ├── csw30/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_002258f0-627f-457f-b2ad-025777c77ac8.xml │ │ │ │ │ ├── get_045c600d-973d-41eb-9f60-eba1b717b720.xml │ │ │ │ │ ├── get_0bbcf862-5211-4351-9988-63f8bec49c98.xml │ │ │ │ │ ├── get_0bdf8457-971e-4ed1-be4a-5feca4dcd8fa.xml │ │ │ │ │ ├── get_0d8bbdec-0846-42ca-8dc8-b7f4cba41d67.xml │ │ │ │ │ ├── get_0e1dca37-477a-4060-99fe-7799b52d656c.xml │ │ │ │ │ ├── get_13c87956-51a4-4780-a8e9-6e0b5c0bb473.xml │ │ │ │ │ ├── get_151d982f-ebd3-4cb2-b507-a667713a1e92.xml │ │ │ │ │ ├── get_1869e495-1a61-4713-8285-76d1336ee1a6.xml │ │ │ │ │ ├── get_1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6.xml │ │ │ │ │ ├── get_22f44168-2ccf-4801-ad96-204212566d56.xml │ │ │ │ │ ├── get_2499a9c9-8d33-449c-bc92-d494adfcc84d.xml │ │ │ │ │ ├── get_27f4f39c-d92a-4e3c-b961-c6aa8c24e513.xml │ │ │ │ │ ├── get_28e569df-8596-4128-8d9a-29ad03138915.xml │ │ │ │ │ ├── get_2b06a5c8-0df2-4af1-8d2e-a425de11c845.xml │ │ │ │ │ ├── get_2ba1418a-444d-4cce-9cfe-4c94efcf8b55.xml │ │ │ │ │ ├── get_397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a.xml │ │ │ │ │ ├── get_3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4.xml │ │ │ │ │ ├── get_405e1ff1-5c75-4846-a28b-cfaff2a6921a.xml │ │ │ │ │ ├── get_43cd6471-6ac7-45bd-8ff9-148cb2de9a52.xml │ │ │ │ │ ├── get_4566d2ec-1283-4a02-baed-a74fc5b47e37.xml │ │ │ │ │ ├── get_461bd4c5-6623-490d-9036-d91a2201e87b.xml │ │ │ │ │ ├── get_5496894a-3877-4f62-a20b-5d7126f94925.xml │ │ │ │ │ ├── get_5a015f6a-bf14-4977-b1e3-6577eb0223c8.xml │ │ │ │ │ ├── get_5c3a2390-1fb9-43f0-b96c-f48c7a69c990.xml │ │ │ │ │ ├── get_5e9e67dc-18d6-4645-8111-c6263c88a61f.xml │ │ │ │ │ ├── get_604d9379-741c-42e5-b4cf-92e56c87fa64.xml │ │ │ │ │ ├── get_60e6af95-d5fc-465a-82e2-fd2e6d85e4af.xml │ │ │ │ │ ├── get_62ad94c2-b558-4265-a427-23d6677975d6.xml │ │ │ │ │ ├── get_6a5e247b-0961-4b8a-a0d6-35a491d9cfe7.xml │ │ │ │ │ ├── get_6a9d0558-9d87-495b-b999-b49a3ef1cf99.xml │ │ │ │ │ ├── get_6bd790c9-6019-4652-9c91-330a894d6700.xml │ │ │ │ │ ├── get_6e9cba43-5e27-415d-adbd-a92851c2c173.xml │ │ │ │ │ ├── get_7630d230-e142-4a09-accf-f091000b90cd.xml │ │ │ │ │ ├── get_7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf.xml │ │ │ │ │ ├── get_8025978e-1a35-4d70-80c2-e8329e0c7864.xml │ │ │ │ │ ├── get_8184ae4f-536d-4978-8b28-ad703be96967.xml │ │ │ │ │ ├── get_88f63a89-664f-4315-b4f8-04a0b33803a7.xml │ │ │ │ │ ├── get_8987f8f0-4d93-4481-968c-a2ccbd6b8be2.xml │ │ │ │ │ ├── get_8e5fa0f6-3f29-4d1f-abe2-d9866f3def98.xml │ │ │ │ │ ├── get_9000ec29-5649-474e-b2d6-55c00f8a52c0.xml │ │ │ │ │ ├── get_91914d35-7bbf-45e6-9b37-5ef484869a4e.xml │ │ │ │ │ ├── get_92d4844d-57d5-4cf3-8f47-ba50e369dc04.xml │ │ │ │ │ ├── get_9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3.xml │ │ │ │ │ ├── get_9d7ffac8-9798-428d-8e27-3cd12497ee6b.xml │ │ │ │ │ ├── get_Exception-GetDomain-value-reference.xml │ │ │ │ │ ├── get_Exception-GetDomain.xml │ │ │ │ │ ├── get_Exception-GetRecordById-404.xml │ │ │ │ │ ├── get_Exception-GetRecordById-dc.xml.xml │ │ │ │ │ ├── get_Exception-GetRepositoryItem-notfound.xml │ │ │ │ │ ├── get_Exception-invalid-request.xml │ │ │ │ │ ├── get_GetCapabilities-base-url.xml │ │ │ │ │ ├── get_GetCapabilities-no-version.xml │ │ │ │ │ ├── get_GetCapabilities.xml │ │ │ │ │ ├── get_GetDomain-parameter.xml │ │ │ │ │ ├── get_GetDomain-value-reference.xml │ │ │ │ │ ├── get_GetRepositoryItem.xml │ │ │ │ │ ├── get_OpenSearch-description.xml │ │ │ │ │ ├── get_a2f18643-e24e-4fa5-b780-6de4a2dbc814.xml │ │ │ │ │ ├── get_abc90c8c-5868-4405-a73e-64c849be3b2a.xml │ │ │ │ │ ├── get_ad0c0571-09ed-436a-9a4f-a5de744c88fe.xml │ │ │ │ │ ├── get_af502903-f4ee-47ee-b76e-af878d238bcc.xml │ │ │ │ │ ├── get_b2aafc3f-4f35-47bc-affd-08590972deae.xml │ │ │ │ │ ├── get_b6069623-f7d8-4021-8582-98f0aea0f763.xml │ │ │ │ │ ├── get_b9a07a54-75a8-45bd-b341-2823600211e3.xml │ │ │ │ │ ├── get_baa4a7d0-0c01-42b6-adc3-0d03e9949fa3.xml │ │ │ │ │ ├── get_bfbe6409-f64a-4c89-acb3-50f260a5c743.xml │ │ │ │ │ ├── get_bfe20134-d1da-42ef-9c0f-8e1307bbf92b.xml │ │ │ │ │ ├── get_c03d173a-3f42-4956-89c8-1fe02c3a0873.xml │ │ │ │ │ ├── get_cb43d8c3-e14c-4a9f-9231-4384b7dd21f3.xml │ │ │ │ │ ├── get_d03c6fd3-e821-4a26-b62f-d20a474e25af.xml │ │ │ │ │ ├── get_d4ccbf96-a529-480e-a53d-5b88dc1dea7f.xml │ │ │ │ │ ├── get_d94c801a-1207-4897-b84a-53f3a192515b.xml │ │ │ │ │ ├── get_da859e34-91fc-495a-8c09-285a40c0900b.xml │ │ │ │ │ ├── get_dc246fb8-5af5-4fda-82bb-c18b3ecd439c.xml │ │ │ │ │ ├── get_de016645-6d5c-4855-943c-2db07ae9f49a.xml │ │ │ │ │ ├── get_dff3ec6b-bb2d-4887-bd17-8fcf15def042.xml │ │ │ │ │ ├── get_e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b.xml │ │ │ │ │ ├── get_e67ca935-d65d-4d8c-8302-1405333dded0.xml │ │ │ │ │ ├── get_e7704509-3441-458f-8ef0-e333c6b6043f.xml │ │ │ │ │ ├── get_f1223a49-6d08-44ff-97fe-4c32cbbfad82.xml │ │ │ │ │ ├── get_f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18.xml │ │ │ │ │ ├── post_Exception-GetDomain-parametername-bad.xml │ │ │ │ │ ├── post_Exception-GetDomain-valuereference-bad.xml │ │ │ │ │ ├── post_Exception-GetRecordById-404.xml │ │ │ │ │ ├── post_Exception-GetRecordById-bad-esn.xml │ │ │ │ │ ├── post_Exception-bad-xml.xml │ │ │ │ │ ├── post_Exception-not-xml.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ ├── post_GetDomain-parametername.xml │ │ │ │ │ ├── post_GetDomain-valuereference.xml │ │ │ │ │ ├── post_GetRecordById-dc-full.xml │ │ │ │ │ ├── post_GetRecordById-dc.xml │ │ │ │ │ └── post_GetRecords-anytext.xml │ │ │ │ ├── get/ │ │ │ │ │ └── requests.txt │ │ │ │ └── post/ │ │ │ │ ├── Exception-GetDomain-parametername-bad.xml │ │ │ │ ├── Exception-GetDomain-valuereference-bad.xml │ │ │ │ ├── Exception-GetRecordById-404.xml │ │ │ │ ├── Exception-GetRecordById-bad-esn.xml │ │ │ │ ├── Exception-bad-xml.xml │ │ │ │ ├── Exception-not-xml.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ ├── GetDomain-parametername.xml │ │ │ │ ├── GetDomain-valuereference.xml │ │ │ │ ├── GetRecordById-dc-full.xml │ │ │ │ ├── GetRecordById-dc.xml │ │ │ │ └── GetRecords-anytext.xml │ │ │ ├── default/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_Exception-GetRepositoryItem-notfound.xml │ │ │ │ │ ├── get_Exception-GetRepositoryItem-service-invalid1.xml │ │ │ │ │ ├── get_Exception-GetRepositoryItem-service-invalid2.xml │ │ │ │ │ ├── get_Exception-GetRepositoryItem-version-invalid.xml │ │ │ │ │ ├── get_GetCapabilities-invalid-request.xml │ │ │ │ │ ├── get_GetCapabilities.xml │ │ │ │ │ ├── get_GetRecords-all.xml │ │ │ │ │ ├── get_GetRecords-empty-maxrecords.xml │ │ │ │ │ ├── get_GetRecords-filter-cql-title-or-abstract-with-spaces.xml │ │ │ │ │ ├── get_GetRecords-filter-cql-title-or-abstract.xml │ │ │ │ │ ├── get_GetRecords-filter-cql-title-with-spaces-or-abstract-with-spaces.xml │ │ │ │ │ ├── get_GetRecords-filter-cql-title-with-spaces-or-abstract.xml │ │ │ │ │ ├── get_GetRecords-filter-cql-title-with-spaces.xml │ │ │ │ │ ├── get_GetRecords-filter-cql-title.xml │ │ │ │ │ ├── get_GetRecords-filter.xml │ │ │ │ │ ├── get_GetRecords-sortby-asc.xml │ │ │ │ │ ├── get_GetRecords-sortby-desc.xml │ │ │ │ │ ├── get_GetRecords-sortby-invalid-order.xml │ │ │ │ │ ├── get_GetRecords-sortby-invalid-propertyname.xml │ │ │ │ │ ├── get_GetRepositoryItem.xml │ │ │ │ │ ├── post_DescribeRecord-json.xml │ │ │ │ │ ├── post_DescribeRecord.xml │ │ │ │ │ ├── post_Exception-GetRecords-badsrsname.xml │ │ │ │ │ ├── post_Exception-GetRecords-elementname.xml │ │ │ │ │ ├── post_Exception-GetRecords-invalid-xml.xml │ │ │ │ │ ├── post_GetCapabilities-SOAP.xml │ │ │ │ │ ├── post_GetCapabilities-sections.xml │ │ │ │ │ ├── post_GetCapabilities-updatesequence.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ ├── post_GetDomain-parameter.xml │ │ │ │ │ ├── post_GetDomain-property.xml │ │ │ │ │ ├── post_GetRecordById-json.xml │ │ │ │ │ ├── post_GetRecordById.xml │ │ │ │ │ ├── post_GetRecords-all-json.xml │ │ │ │ │ ├── post_GetRecords-all-resulttype-hits.xml │ │ │ │ │ ├── post_GetRecords-all-resulttype-validate.xml │ │ │ │ │ ├── post_GetRecords-all-sortby-bbox.xml │ │ │ │ │ ├── post_GetRecords-all.xml │ │ │ │ │ ├── post_GetRecords-bbox-filter-crs84.xml │ │ │ │ │ ├── post_GetRecords-cql-title-and-abstract.xml │ │ │ │ │ ├── post_GetRecords-cql-title.xml │ │ │ │ │ ├── post_GetRecords-distributedsearch.xml │ │ │ │ │ ├── post_GetRecords-elementname.xml │ │ │ │ │ ├── post_GetRecords-end.xml │ │ │ │ │ ├── post_GetRecords-filter-and-bbox-freetext.xml │ │ │ │ │ ├── post_GetRecords-filter-and-nested-or-multiple.xml │ │ │ │ │ ├── post_GetRecords-filter-and-nested-or.xml │ │ │ │ │ ├── post_GetRecords-filter-and-nested-or2.xml │ │ │ │ │ ├── post_GetRecords-filter-anytext-and-not.xml │ │ │ │ │ ├── post_GetRecords-filter-anytext-equal.xml │ │ │ │ │ ├── post_GetRecords-filter-anytext.xml │ │ │ │ │ ├── post_GetRecords-filter-bbox-poslist.xml │ │ │ │ │ ├── post_GetRecords-filter-bbox-reproject.xml │ │ │ │ │ ├── post_GetRecords-filter-bbox-sortby.xml │ │ │ │ │ ├── post_GetRecords-filter-bbox.xml │ │ │ │ │ ├── post_GetRecords-filter-between.xml │ │ │ │ │ ├── post_GetRecords-filter-function-bad.xml │ │ │ │ │ ├── post_GetRecords-filter-function.xml │ │ │ │ │ ├── post_GetRecords-filter-invalid-poslist.xml │ │ │ │ │ ├── post_GetRecords-filter-not-bbox.xml │ │ │ │ │ ├── post_GetRecords-filter-or-bbox-freetext.xml │ │ │ │ │ ├── post_GetRecords-filter-or-nested-and.xml │ │ │ │ │ ├── post_GetRecords-filter-or-title-abstract.xml │ │ │ │ │ ├── post_GetRecords-maxrecords.xml │ │ │ │ │ ├── post_GetRecords-requestid.xml │ │ │ │ │ ├── post_Harvest-default.xml │ │ │ │ │ ├── post_Harvest-response-handler.xml │ │ │ │ │ ├── post_Transaction-delete.xml │ │ │ │ │ ├── post_Transaction-insert.xml │ │ │ │ │ ├── post_Transaction-update-full.xml │ │ │ │ │ └── post_Transaction-update-recordproperty.xml │ │ │ │ ├── get/ │ │ │ │ │ └── requests.txt │ │ │ │ └── post/ │ │ │ │ ├── DescribeRecord-json.xml │ │ │ │ ├── DescribeRecord.xml │ │ │ │ ├── Exception-GetRecords-badsrsname.xml │ │ │ │ ├── Exception-GetRecords-elementname.xml │ │ │ │ ├── Exception-GetRecords-invalid-xml.xml │ │ │ │ ├── GetCapabilities-SOAP.xml │ │ │ │ ├── GetCapabilities-sections.xml │ │ │ │ ├── GetCapabilities-updatesequence.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ ├── GetDomain-parameter.xml │ │ │ │ ├── GetDomain-property.xml │ │ │ │ ├── GetRecordById-json.xml │ │ │ │ ├── GetRecordById.xml │ │ │ │ ├── GetRecords-all-json.xml │ │ │ │ ├── GetRecords-all-resulttype-hits.xml │ │ │ │ ├── GetRecords-all-resulttype-validate.xml │ │ │ │ ├── GetRecords-all-sortby-bbox.xml │ │ │ │ ├── GetRecords-all.xml │ │ │ │ ├── GetRecords-bbox-filter-crs84.xml │ │ │ │ ├── GetRecords-cql-title-and-abstract.xml │ │ │ │ ├── GetRecords-cql-title.xml │ │ │ │ ├── GetRecords-distributedsearch.xml │ │ │ │ ├── GetRecords-elementname.xml │ │ │ │ ├── GetRecords-end.xml │ │ │ │ ├── GetRecords-filter-and-bbox-freetext.xml │ │ │ │ ├── GetRecords-filter-and-nested-or-multiple.xml │ │ │ │ ├── GetRecords-filter-and-nested-or.xml │ │ │ │ ├── GetRecords-filter-and-nested-or2.xml │ │ │ │ ├── GetRecords-filter-anytext-and-not.xml │ │ │ │ ├── GetRecords-filter-anytext-equal.xml │ │ │ │ ├── GetRecords-filter-anytext.xml │ │ │ │ ├── GetRecords-filter-bbox-poslist.xml │ │ │ │ ├── GetRecords-filter-bbox-reproject.xml │ │ │ │ ├── GetRecords-filter-bbox-sortby.xml │ │ │ │ ├── GetRecords-filter-bbox.xml │ │ │ │ ├── GetRecords-filter-between.xml │ │ │ │ ├── GetRecords-filter-function-bad.xml │ │ │ │ ├── GetRecords-filter-function.xml │ │ │ │ ├── GetRecords-filter-invalid-poslist.xml │ │ │ │ ├── GetRecords-filter-not-bbox.xml │ │ │ │ ├── GetRecords-filter-or-bbox-freetext.xml │ │ │ │ ├── GetRecords-filter-or-nested-and.xml │ │ │ │ ├── GetRecords-filter-or-title-abstract.xml │ │ │ │ ├── GetRecords-maxrecords.xml │ │ │ │ ├── GetRecords-requestid.xml │ │ │ │ ├── Harvest-default.xml │ │ │ │ ├── Harvest-response-handler.xml │ │ │ │ ├── Transaction-delete.xml │ │ │ │ ├── Transaction-insert.xml │ │ │ │ ├── Transaction-update-full.xml │ │ │ │ └── Transaction-update-recordproperty.xml │ │ │ ├── dif/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── post_DescribeRecord.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ └── post_GetRecords-filter-bbox.xml │ │ │ │ └── post/ │ │ │ │ ├── DescribeRecord.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ └── GetRecords-filter-bbox.xml │ │ │ ├── duplicatefileid/ │ │ │ │ ├── data/ │ │ │ │ │ └── isos/ │ │ │ │ │ └── tds.maracoos.org/ │ │ │ │ │ └── iso/ │ │ │ │ │ ├── AVHRR.2011.7Agg.xml │ │ │ │ │ └── AVHRR.2012.7Agg.xml │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_GetCapabilities.xml │ │ │ │ │ └── post_GetRecords-all.xml │ │ │ │ ├── get/ │ │ │ │ │ └── requests.txt │ │ │ │ └── post/ │ │ │ │ └── GetRecords-all.xml │ │ │ ├── ebrim/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── post_DescribeRecord.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ ├── post_GetRecords-filter-bbox-full.xml │ │ │ │ │ └── post_GetRecords-filter-bbox.xml │ │ │ │ └── post/ │ │ │ │ ├── DescribeRecord.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ ├── GetRecords-filter-bbox-full.xml │ │ │ │ └── GetRecords-filter-bbox.xml │ │ │ ├── fgdc/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── post_DescribeRecord.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ └── post_GetRecords-filter-bbox.xml │ │ │ │ └── post/ │ │ │ │ ├── DescribeRecord.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ └── GetRecords-filter-bbox.xml │ │ │ ├── gm03/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ └── post_GetRecords-filter-bbox.xml │ │ │ │ └── post/ │ │ │ │ ├── GetCapabilities.xml │ │ │ │ └── GetRecords-filter-bbox.xml │ │ │ ├── harvesting/ │ │ │ │ ├── data/ │ │ │ │ │ └── .gitignore │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_Exception-Harvest-invalid-resourcetype.xml │ │ │ │ │ ├── get_Exception-Harvest-missing-resourcetype.xml │ │ │ │ │ ├── get_Exception-Harvest-missing-source.xml │ │ │ │ │ ├── get_Exception-Harvest-waf-bad-value.xml │ │ │ │ │ ├── get_Exception-Harvest-waf-no-records-found.xml │ │ │ │ │ ├── post_Clear-000-delete-all.xml │ │ │ │ │ ├── post_Exception-Havest-csw-404.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ ├── post_GetDomain-parameter.xml │ │ │ │ │ ├── post_Harvest-csw-iso.xml │ │ │ │ │ ├── post_Harvest-csw-run1.xml │ │ │ │ │ ├── post_Harvest-csw-run2.xml │ │ │ │ │ ├── post_Harvest-dc.xml │ │ │ │ │ ├── post_Harvest-fgdc.xml │ │ │ │ │ ├── post_Harvest-iso.xml │ │ │ │ │ ├── post_Harvest-rdf.xml │ │ │ │ │ ├── post_Harvest-sos100.xml │ │ │ │ │ ├── post_Harvest-sos200.xml │ │ │ │ │ ├── post_Harvest-waf.xml │ │ │ │ │ ├── post_Harvest-wcs.xml │ │ │ │ │ ├── post_Harvest-wfs110.xml │ │ │ │ │ ├── post_Harvest-wfs200.xml │ │ │ │ │ ├── post_Harvest-wms-run1.xml │ │ │ │ │ ├── post_Harvest-wms-run2.xml │ │ │ │ │ ├── post_Harvest-wmts.xml │ │ │ │ │ ├── post_Harvest-wps.xml │ │ │ │ │ ├── post_Harvest-zzz-post-GetRecords-filter-ows-dc.xml │ │ │ │ │ ├── post_Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml │ │ │ │ │ ├── post_Harvest-zzz-post-GetRecords-filter-sos-dc.xml │ │ │ │ │ ├── post_Harvest-zzz-post-GetRecords-filter-sos-iso.xml │ │ │ │ │ ├── post_Harvest-zzz-post-GetRecords-filter-wfs-iso.xml │ │ │ │ │ ├── post_Harvest-zzz-post-GetRecords-filter-wms-dc.xml │ │ │ │ │ ├── post_Harvest-zzz-post-GetRecords-filter-wms-iso.xml │ │ │ │ │ ├── post_Harvest-zzz-post-GetRecords-filter-wms-layer.xml │ │ │ │ │ ├── post_Harvest-zzz-post-GetRecords-filter-wps-process.xml │ │ │ │ │ └── post_Transaction-000-delete-all.xml │ │ │ │ ├── get/ │ │ │ │ │ └── requests.txt │ │ │ │ └── post/ │ │ │ │ ├── Clear-000-delete-all.xml │ │ │ │ ├── Exception-Havest-csw-404.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ ├── GetDomain-parameter.xml │ │ │ │ ├── Harvest-csw-iso.xml │ │ │ │ ├── Harvest-csw-run1.xml │ │ │ │ ├── Harvest-csw-run2.xml │ │ │ │ ├── Harvest-dc.xml │ │ │ │ ├── Harvest-fgdc.xml │ │ │ │ ├── Harvest-iso.xml │ │ │ │ ├── Harvest-rdf.xml │ │ │ │ ├── Harvest-sos100.xml │ │ │ │ ├── Harvest-sos200.xml │ │ │ │ ├── Harvest-waf.xml │ │ │ │ ├── Harvest-wcs.xml │ │ │ │ ├── Harvest-wfs110.xml │ │ │ │ ├── Harvest-wfs200.xml │ │ │ │ ├── Harvest-wms-run1.xml │ │ │ │ ├── Harvest-wms-run2.xml │ │ │ │ ├── Harvest-wmts.xml │ │ │ │ ├── Harvest-wps.xml │ │ │ │ ├── Harvest-zzz-post-GetRecords-filter-ows-dc.xml │ │ │ │ ├── Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml │ │ │ │ ├── Harvest-zzz-post-GetRecords-filter-sos-dc.xml │ │ │ │ ├── Harvest-zzz-post-GetRecords-filter-sos-iso.xml │ │ │ │ ├── Harvest-zzz-post-GetRecords-filter-wfs-iso.xml │ │ │ │ ├── Harvest-zzz-post-GetRecords-filter-wms-dc.xml │ │ │ │ ├── Harvest-zzz-post-GetRecords-filter-wms-iso.xml │ │ │ │ ├── Harvest-zzz-post-GetRecords-filter-wms-layer.xml │ │ │ │ ├── Harvest-zzz-post-GetRecords-filter-wps-process.xml │ │ │ │ └── Transaction-000-delete-all.xml │ │ │ ├── idswithpaths/ │ │ │ │ ├── data/ │ │ │ │ │ ├── file_id_as_url.xml │ │ │ │ │ ├── file_id_starting_with_forward_slash.xml │ │ │ │ │ ├── file_id_with_colon.xml │ │ │ │ │ ├── file_id_with_directory_changes.xml │ │ │ │ │ ├── file_id_with_driveletter_and_backslashes.xml │ │ │ │ │ └── file_id_with_foward_slashes.xml │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ └── get_GetCapabilities.xml │ │ │ │ └── get/ │ │ │ │ └── requests.txt │ │ │ ├── iso19115p3/ │ │ │ │ ├── data/ │ │ │ │ │ ├── README.txt │ │ │ │ │ ├── auscope-3d-model.xml │ │ │ │ │ ├── auscope-iso19139-geoprovinces.xml │ │ │ │ │ ├── metawal.wallonie.be-catchments.xml │ │ │ │ │ └── metawal.wallonie.be-srv.xml │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_DescribeRecord.xml │ │ │ │ │ ├── get_GetCapabilities.xml │ │ │ │ │ ├── post_DescribeRecord.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ ├── post_GetDomain-property.xml │ │ │ │ │ ├── post_GetRecordById-ISO19139-full.xml │ │ │ │ │ ├── post_GetRecordById-brief.xml │ │ │ │ │ ├── post_GetRecordById-full-dc.xml │ │ │ │ │ ├── post_GetRecordById-full.xml │ │ │ │ │ ├── post_GetRecordById-srv-brief.xml │ │ │ │ │ ├── post_GetRecords-all-csw-output.xml │ │ │ │ │ ├── post_GetRecords-all.xml │ │ │ │ │ ├── post_GetRecords-cql-title.xml │ │ │ │ │ ├── post_GetRecords-elementname.xml │ │ │ │ │ ├── post_GetRecords-filter-accessconstraints.xml │ │ │ │ │ ├── post_GetRecords-filter-and-nested-spatial-or-dateline.xml │ │ │ │ │ ├── post_GetRecords-filter-anytext.xml │ │ │ │ │ ├── post_GetRecords-filter-bbox-csw-output.xml │ │ │ │ │ ├── post_GetRecords-filter-bbox.xml │ │ │ │ │ ├── post_GetRecords-filter-date.xml │ │ │ │ │ ├── post_Transaction-delete.xml │ │ │ │ │ ├── post_Transaction-insert.xml │ │ │ │ │ ├── post_Transaction-update-full.xml │ │ │ │ │ └── post_Transaction-update-recordproperty.xml │ │ │ │ ├── get/ │ │ │ │ │ └── requests.txt │ │ │ │ └── post/ │ │ │ │ ├── DescribeRecord.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ ├── GetDomain-property.xml │ │ │ │ ├── GetRecordById-ISO19139-full.xml │ │ │ │ ├── GetRecordById-brief.xml │ │ │ │ ├── GetRecordById-full-dc.xml │ │ │ │ ├── GetRecordById-full.xml │ │ │ │ ├── GetRecordById-srv-brief.xml │ │ │ │ ├── GetRecords-all-csw-output.xml │ │ │ │ ├── GetRecords-all.xml │ │ │ │ ├── GetRecords-cql-title.xml │ │ │ │ ├── GetRecords-elementname.xml │ │ │ │ ├── GetRecords-filter-accessconstraints.xml │ │ │ │ ├── GetRecords-filter-and-nested-spatial-or-dateline.xml │ │ │ │ ├── GetRecords-filter-anytext.xml │ │ │ │ ├── GetRecords-filter-bbox-csw-output.xml │ │ │ │ ├── GetRecords-filter-bbox.xml │ │ │ │ ├── GetRecords-filter-date.xml │ │ │ │ ├── Transaction-delete.xml │ │ │ │ ├── Transaction-insert.xml │ │ │ │ ├── Transaction-update-full.xml │ │ │ │ └── Transaction-update-recordproperty.xml │ │ │ ├── manager/ │ │ │ │ ├── data/ │ │ │ │ │ └── .gitignore │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── post_Clear-000-delete-all.xml │ │ │ │ │ ├── post_GetCapabilities.xml │ │ │ │ │ ├── post_GetDomain-parameter.xml │ │ │ │ │ ├── post_Transaction-000-delete-all.xml │ │ │ │ │ ├── post_Transaction-dc-01-insert.xml │ │ │ │ │ ├── post_Transaction-dc-02-update-full.xml │ │ │ │ │ ├── post_Transaction-fgdc-01-insert.xml │ │ │ │ │ ├── post_Transaction-fgdc-02-update-recprop.xml │ │ │ │ │ ├── post_Transaction-fgdc-03-delete-all.xml │ │ │ │ │ ├── post_Transaction-iso-00-delete-all.xml │ │ │ │ │ ├── post_Transaction-iso-01-insert.xml │ │ │ │ │ ├── post_Transaction-iso-02-update-full.xml │ │ │ │ │ ├── post_Transaction-iso-03-update-recprop.xml │ │ │ │ │ ├── post_Transaction-iso-04-update-recprop-no-matches.xml │ │ │ │ │ ├── post_Transaction-iso-05-delete.xml │ │ │ │ │ └── post_Transaction-xxx-delete-all.xml │ │ │ │ └── post/ │ │ │ │ ├── Clear-000-delete-all.xml │ │ │ │ ├── GetCapabilities.xml │ │ │ │ ├── GetDomain-parameter.xml │ │ │ │ ├── Transaction-000-delete-all.xml │ │ │ │ ├── Transaction-dc-01-insert.xml │ │ │ │ ├── Transaction-dc-02-update-full.xml │ │ │ │ ├── Transaction-fgdc-01-insert.xml │ │ │ │ ├── Transaction-fgdc-02-update-recprop.xml │ │ │ │ ├── Transaction-fgdc-03-delete-all.xml │ │ │ │ ├── Transaction-iso-00-delete-all.xml │ │ │ │ ├── Transaction-iso-01-insert.xml │ │ │ │ ├── Transaction-iso-02-update-full.xml │ │ │ │ ├── Transaction-iso-03-update-recprop.xml │ │ │ │ ├── Transaction-iso-04-update-recprop-no-matches.xml │ │ │ │ ├── Transaction-iso-05-delete.xml │ │ │ │ └── Transaction-xxx-delete-all.xml │ │ │ ├── oaipmh/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_GetRecord_bad_metadata_prefix.xml │ │ │ │ │ ├── get_GetRecord_datacite.xml │ │ │ │ │ ├── get_GetRecord_dc.xml │ │ │ │ │ ├── get_GetRecord_iso.xml │ │ │ │ │ ├── get_GetRecord_oai_dc.xml │ │ │ │ │ ├── get_Identify.xml │ │ │ │ │ ├── get_ListIdentifiers_bad_metadata_prefix.xml │ │ │ │ │ ├── get_ListIdentifiers_datacite.xml │ │ │ │ │ ├── get_ListIdentifiers_dc.xml │ │ │ │ │ ├── get_ListIdentifiers_iso.xml │ │ │ │ │ ├── get_ListIdentifiers_missing_metadata_prefix.xml │ │ │ │ │ ├── get_ListIdentifiers_oai_dc.xml │ │ │ │ │ ├── get_ListMetadataFormats.xml │ │ │ │ │ ├── get_ListRecords_datacite.xml │ │ │ │ │ ├── get_ListRecords_dc.xml │ │ │ │ │ ├── get_ListRecords_dc_bad_metadata_prefix.xml │ │ │ │ │ ├── get_ListRecords_iso19139.xml │ │ │ │ │ ├── get_ListRecords_oai_dc.xml │ │ │ │ │ ├── get_ListSets.xml │ │ │ │ │ ├── get_bad_verb.xml │ │ │ │ │ ├── get_empty.xml │ │ │ │ │ ├── get_empty_with_amp.xml │ │ │ │ │ └── get_illegal_verb.xml │ │ │ │ └── get/ │ │ │ │ └── requests.txt │ │ │ ├── oarec/ │ │ │ │ ├── conftest.py │ │ │ │ ├── test_oarec_functional.py │ │ │ │ └── test_oarec_virtual_collections_functional.py │ │ │ ├── opensearcheo/ │ │ │ │ ├── data/ │ │ │ │ │ ├── 3e9a8c05.xml │ │ │ │ │ ├── README.txt │ │ │ │ │ ├── T_aerfo_RAS_1991_GR800P001800000012.xml │ │ │ │ │ ├── T_aerfo_RAS_1991_GR800P001800000013.xml │ │ │ │ │ ├── T_aerfo_RAS_1991_GR800P001800000014.xml │ │ │ │ │ ├── T_aerfo_RAS_1991_GR800P001800000015.xml │ │ │ │ │ ├── T_ortho_RAS_1998_284404.xml │ │ │ │ │ ├── T_ortho_RAS_1998_288395.xml │ │ │ │ │ ├── T_ortho_RAS_1998_288398.xml │ │ │ │ │ ├── T_ortho_RAS_1998_288401.xml │ │ │ │ │ ├── T_ortho_RAS_1998_288404.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_276395.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_276398.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_276401.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_276404.xml │ │ │ │ │ ├── T_pmoed_DTM_1996_280395.xml │ │ │ │ │ ├── iso_19115-2_Sentinel-2-scene.xml │ │ │ │ │ ├── pacioos-NS06agg.xml │ │ │ │ │ └── test.xml │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_opensearch-description-document.xml │ │ │ │ │ ├── get_opensearch-query-cloudcover-gt.xml │ │ │ │ │ ├── get_opensearch-query-cloudcover-lt-gt.xml │ │ │ │ │ ├── get_opensearch-query-cloudcover-lt.xml │ │ │ │ │ ├── get_opensearch-query-cloudcover.xml │ │ │ │ │ ├── get_opensearch-query-instrument.xml │ │ │ │ │ ├── get_opensearch-query-orbitdirection.xml │ │ │ │ │ ├── get_opensearch-query-orbitnumber.xml │ │ │ │ │ ├── get_opensearch-query-platform.xml │ │ │ │ │ ├── get_opensearch-query-processinglevel.xml │ │ │ │ │ ├── get_opensearch-query-producttype.xml │ │ │ │ │ ├── get_opensearch-query-sensortype.xml │ │ │ │ │ ├── get_opensearch-query-snowcover.xml │ │ │ │ │ ├── get_opensearch-query-spectralrange.xml │ │ │ │ │ ├── get_opensearch-query-start-stop-extent.xml │ │ │ │ │ └── get_opensearch-query-time-extent.xml │ │ │ │ └── get/ │ │ │ │ └── requests.txt │ │ │ ├── pubsub/ │ │ │ │ ├── conftest.py │ │ │ │ └── test_pubsub_functional.py │ │ │ ├── repofilter/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── post_GetRecordById-masked.xml │ │ │ │ │ └── post_GetRecords-all.xml │ │ │ │ └── post/ │ │ │ │ ├── GetRecordById-masked.xml │ │ │ │ └── GetRecords-all.xml │ │ │ ├── sru/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_explain.xml │ │ │ │ │ ├── get_search.xml │ │ │ │ │ ├── get_search_cql.xml │ │ │ │ │ ├── get_search_maxrecords.xml │ │ │ │ │ └── get_search_startrecord_maxrecords.xml │ │ │ │ └── get/ │ │ │ │ └── requests.txt │ │ │ ├── stablesort/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ ├── get_GetRecords-page1.xml │ │ │ │ │ ├── get_GetRecords-page2.xml │ │ │ │ │ └── get_GetRecords-page3.xml │ │ │ │ └── get/ │ │ │ │ └── requests.txt │ │ │ ├── stac_api/ │ │ │ │ ├── conftest.py │ │ │ │ ├── data/ │ │ │ │ │ ├── 20201211_223832_CS21.json │ │ │ │ │ ├── S2A_MSIL2A_20241128T092331_R093_T34SEJ_20241128T122153.json │ │ │ │ │ ├── S2A_MSIL2A_20241128T092331_R093_T34SFH_20241128T122153.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE.json │ │ │ │ │ ├── S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE.json │ │ │ │ │ ├── S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE.json │ │ │ │ │ ├── S2MSI1C.xml │ │ │ │ │ ├── S2MSI2A.xml │ │ │ │ │ ├── sentinel-2-l2a.json │ │ │ │ │ ├── simple-collection.json │ │ │ │ │ └── woudc-total-column-ozone-totalozone.json │ │ │ │ └── test_stac_api_functional.py │ │ │ ├── utf-8/ │ │ │ │ ├── default.yml │ │ │ │ ├── expected/ │ │ │ │ │ └── post_GetCapabilities.xml │ │ │ │ └── post/ │ │ │ │ └── GetCapabilities.xml │ │ │ └── xslt/ │ │ │ ├── custom.xslt │ │ │ ├── default.yml │ │ │ ├── expected/ │ │ │ │ ├── post_csw2-GetRecordById-xslt.xml │ │ │ │ ├── post_csw2-GetRecordById.xml │ │ │ │ ├── post_csw2-GetRecords-all-xslt.xml │ │ │ │ ├── post_csw2-GetRecords-all.xml │ │ │ │ ├── post_csw3-GetRecordById-xslt.xml │ │ │ │ ├── post_csw3-GetRecordById.xml │ │ │ │ ├── post_csw3-GetRecords-all-xslt.xml │ │ │ │ └── post_csw3-GetRecords-all.xml │ │ │ └── post/ │ │ │ ├── csw2-GetRecordById-xslt.xml │ │ │ ├── csw2-GetRecordById.xml │ │ │ ├── csw2-GetRecords-all-xslt.xml │ │ │ ├── csw2-GetRecords-all.xml │ │ │ ├── csw3-GetRecordById-xslt.xml │ │ │ ├── csw3-GetRecordById.xml │ │ │ ├── csw3-GetRecords-all-xslt.xml │ │ │ └── csw3-GetRecords-all.xml │ │ └── test_xml_suites_functional.py │ ├── gen_html.py │ └── unittests/ │ ├── test_fmt_json.py │ ├── test_metadata.py │ ├── test_ogc_csw_csw3.py │ ├── test_opensearch.py │ ├── test_repository.py │ ├── test_server.py │ ├── test_util.py │ └── test_wsgi.py └── tox.ini ================================================ FILE CONTENTS ================================================ ================================================ FILE: .coveragerc ================================================ [run] branch = True source = pycsw [paths] source = pycsw .tox/*/lib/python*/site-packages/pycsw /usr/local/lib/python*/dist-packages/pycsw [report] show_missing = True ================================================ FILE: .dockerignore ================================================ # build artifacts *.pyc *.egg-info build dist docs/_build MANIFEST # testing artifacts tests/index.html tests/results **.cache .coverage .tox # test configurations /default.cfg # git stuff .git # pycharm ide .idea ================================================ FILE: .gitattributes ================================================ .gitattributes export-ignore .gitignore export-ignore ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms #github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] custom: ['https://github.com/geopython/pycsw/wiki/Sponsorship'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ # Description # Environment - operating system: - Python version: - pycsw version: - source/distribution - [ ] git clone - [ ] DebianGIS/UbuntuGIS - [ ] PyPI - [ ] zip/tar.gz - [ ] other (please specify): - web server - [ ] Apache/mod_wsgi - [ ] CGI - [ ] other (please specify): # Steps to Reproduce # Additional Information ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ # Overview # Related Issue / Discussion # Additional Information # Contributions and Licensing (as per https://github.com/geopython/pycsw/blob/master/CONTRIBUTING.rst#contributions-and-licensing) - [ ] I'd like to contribute [feature X|bugfix Y|docs|something else] to pycsw. I confirm that my contributions to pycsw will be compatible with the pycsw license guidelines at the time of contribution. - [ ] I have already previously agreed to the pycsw Contributions and Licensing Guidelines ================================================ FILE: .github/workflows/docker.yml ================================================ # Triggers a Docker workflow on completion of the "build" workflow but # pushes to DockerHub # # Author: Just van den Broecke & Edward Lewis - 2021 # name: Docker Build on: workflow_run: workflows: ["build ⚙️"] types: [completed] jobs: # Single job now to build Docker Image and push to DockerHub on-success: name: Build, Test and Push Docker Image to DockerHub runs-on: ubuntu-24.04 if: ${{ github.event.workflow_run.conclusion == 'success' }} # v2 https://github.com/docker/build-push-action/blob/master/UPGRADE.md steps: - name: Checkout ✅ uses: actions/checkout@master - name: Prepare 📦 id: prep run: | DOCKER_IMAGE=geopython/pycsw VERSION=latest if [[ $GITHUB_REF == refs/tags/* ]]; then VERSION=${GITHUB_REF#refs/tags/} elif [[ $GITHUB_REF == refs/heads/* ]]; then VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g') elif [[ $GITHUB_REF == refs/pull/* ]]; then VERSION=pr-${{ github.event.number }} fi if [[ $VERSION == master ]]; then VERSION=latest fi TAGS="${DOCKER_IMAGE}:${VERSION}" echo ::set-output name=image::${DOCKER_IMAGE} echo ::set-output name=version::${VERSION} echo ::set-output name=tags::${TAGS} echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ') - name: Show Image Settings 📦 run: echo "IMAGE=${{ steps.prep.outputs.image }} VERSION=${{ steps.prep.outputs.version }} TAGS=${{ steps.prep.outputs.tags }}" - name: Set up Docker Buildx 📦 uses: docker/setup-buildx-action@v1 - name: Login to DockerHub 📦 if: github.event_name != 'pull_request' uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Docker Build only - retain local Image 📦 uses: docker/build-push-action@v2 with: context: . load: true push: false tags: ${{ steps.prep.outputs.tags }} labels: | org.opencontainers.image.source=${{ github.event.repository.html_url }} org.opencontainers.image.created=${{ steps.prep.outputs.created }} org.opencontainers.image.revision=${{ github.sha }} - name: Push to Docker repo ☁️ run: docker push ${{ steps.prep.outputs.image }}:${{ steps.prep.outputs.version }} on-failure: runs-on: ubuntu-24.04 if: ${{ github.event.workflow_run.conclusion == 'failure' }} steps: - name: Print Test Fail run: echo Tests Failed ================================================ FILE: .github/workflows/ghcr.yml ================================================ # This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. # Triggers a Docker workflow on completion of the "build" workflow but # pushes to GitHub Container Registry # # Author: Edward Lewis - 2021 name: GHCR on: workflow_run: workflows: ["build ⚙️"] types: [completed] env: REGISTRY: ghcr.io IMAGE_NAME: pycsw jobs: # Push image to GitHub Packages. # See also https://docs.docker.com/docker-hub/builds/ push: runs-on: ubuntu-24.04 if: ${{ github.event.workflow_run.conclusion == 'success' }} permissions: packages: write contents: read steps: - uses: actions/checkout@master - name: Build image run: docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}" - name: Log in to registry # This is where you will update the PAT to GITHUB_TOKEN run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - name: Rename image for publication run: | IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME # Change all uppercase to lowercase IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') # Strip git ref prefix from version VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') # Strip "v" prefix from tag name [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') # Use Docker `latest` tag convention [ "$VERSION" == "master" ] && VERSION=latest echo IMAGE_ID=$IMAGE_ID echo VERSION=$VERSION echo FULLCONTAINERNAME=$IMAGE_ID:$VERSION >> $GITHUB_ENV docker tag $IMAGE_NAME $IMAGE_ID:$VERSION #- uses: Azure/container-scan@v0 #with: #image-name: ${{ env.FULLCONTAINERNAME }} - name: Push to CR run: docker push ${{ env.FULLCONTAINERNAME }} on-failure: runs-on: ubuntu-24.04 if: ${{ github.event.workflow_run.conclusion == 'failure' }} steps: - name: Print Test Fail run: echo Tests Failed ================================================ FILE: .github/workflows/main.yml ================================================ name: build ⚙️ on: push: branches: - master paths-ignore: - '**.md' pull_request: branches: - master paths-ignore: - '**.md' release: types: - released jobs: main: runs-on: ubuntu-24.04 strategy: matrix: include: - python-version: "3.12" toxenv: "py312-sqlite" env: TOXENV: ${{ matrix.toxenv }} steps: - uses: actions/checkout@master - uses: actions/setup-python@v5 name: Setup Python ${{ matrix.python-version }} with: python-version: ${{ matrix.python-version }} - name: Install requirements 📦 run: | sudo apt update sudo apt install -y libgeos-dev libpq-dev libxml2-dev libxslt1-dev libz-dev libexpat1 python3-distutils-extra pip3 install setuptools pip3 install -r requirements.txt pip3 install -r requirements-standalone.txt pip3 install -r requirements-pubsub.txt pip3 install -r requirements-dev.txt pip3 install --upgrade https://github.com/geopython/OWSLib/archive/master.zip pip3 install tox echo "TOXENV => $TOXENV" - name: run unit tests ⚙️ run: tox -- --exitfirst -m unit - name: run integration tests ⚙️ run: tox -- --exitfirst -m functional -k 'not harvesting' - name: build docs 🏗️ run: cd docs && make html ================================================ FILE: .github/workflows/stale.yml ================================================ name: 'Close stale Issues and Pull Requests' env: STALE_AFTER_INACTIVE_DAYS: 90 CLOSE_AFTER_INACTIVE_DAYS: 7 on: schedule: - cron: '1 3 * * 0' # runs every Sunday at 03h01 UTC # - cron: '0 * * * *' # runs every hour, for debugging jobs: stale: permissions: issues: write pull-requests: write if: github.repository == 'geopython/pycsw' runs-on: ubuntu-24.04 steps: - uses: 'actions/stale@v10' with: # debug-only: true operations-per-run: 1000 enable-statistics: true stale-issue-label: stale stale-pr-label: stale exempt-issue-labels: blocker exempt-pr-labels: blocker days-before-stale: ${{ env.STALE_AFTER_INACTIVE_DAYS }} days-before-close: ${{ env.CLOSE_AFTER_INACTIVE_DAYS }} remove-stale-when-updated: true stale-issue-message: > This Issue has been inactive for ${{env.STALE_AFTER_INACTIVE_DAYS }} days. In order to manage maintenance burden, it will be automatically closed in ${{ env.CLOSE_AFTER_INACTIVE_DAYS }} days. stale-pr-message: > This Pull Request has been inactive for ${{env.STALE_AFTER_INACTIVE_DAYS }} days. In order to manage maintenance burden, it will be automatically closed in ${{ env.CLOSE_AFTER_INACTIVE_DAYS }} days. close-issue-message: > This Issue has been closed due to there being no activity for more than ${{ env.STALE_AFTER_INACTIVE_DAYS }} days. close-pr-message: > This Pull Request has been closed due to there being no activity for more than ${{ env.STALE_AFTER_INACTIVE_DAYS }} days. ================================================ FILE: .github/workflows/vulnerabilities.yml ================================================ name: Check vulnerabilities on: push: paths-ignore: - '**.md' pull_request: branches: - master paths-ignore: - '!**.md' release: types: - released jobs: vulnerabilities: runs-on: ubuntu-24.04 defaults: run: working-directory: . steps: - name: Checkout pycsw uses: actions/checkout@master - name: Scan vulnerabilities with trivy uses: aquasecurity/trivy-action@v0.35.0 with: scan-type: fs exit-code: 1 ignore-unfixed: true severity: CRITICAL,HIGH scanners: vuln,misconfig,secret scan-ref: . skip-dirs: docker/helm,docker/kubernetes - name: Build locally the image from Dockerfile run: | docker buildx build -t ${{ github.repository }}:${{ github.sha }} --platform linux/amd64 --no-cache -f Dockerfile . - name: Scan locally built Docker image for vulnerabilities with trivy uses: aquasecurity/trivy-action@v0.35.0 with: scan-type: image exit-code: 1 ignore-unfixed: true severity: CRITICAL,HIGH vuln-type: os,library image-ref: '${{ github.repository }}:${{ github.sha }}' ================================================ FILE: .gitignore ================================================ # build artifacts *.pyc *.egg-info build dist docs/_build MANIFEST # testing artifacts tests/index.html tests/results **.cache .coverage .tox .pytest_cache # test configurations /default.cfg # pycharm ide .idea # shell files .env .envrc # compiled file for *.po. *.mo # virtual environments .venv # visual studio code workspace *.code-workspace .vscode/settings.json .vscode/launch.json ================================================ FILE: .readthedocs.yaml ================================================ # .readthedocs.yaml # Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Set the version of Python and other tools you might need build: os: ubuntu-22.04 tools: python: "3.11" # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py # We recommend specifying your dependencies to enable reproducible builds: # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html python: install: - requirements: docs/requirements-mocked.txt formats: - pdf ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at pycsw-devel@lists.osgeo.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ ================================================ FILE: COMMITTERS.txt ================================================ ============== ===================== ================================== ================================== Login(s) Name Email / Contact Area(s) ============== ===================== ================================== ================================== tomkralidis Tom Kralidis tomkralidis at gmail.com Overall kalxas Angelos Tzotsos tzotsos at gmail.com INSPIRE, APISO profiles, Packaging adamhinz Adam Hinz hinz dot adam at gmail.com WSGI/Server Deployment ricardogsilva Ricardo Garcia Silva ricardo.garcia.silva at gmail.com Overall ============== ===================== ================================== ================================== ================================================ FILE: CONTRIBUTING.rst ================================================ Contributing to pycsw ===================== The pycsw project openly welcomes contributions (bug reports, bug fixes, code enhancements/features, etc.). This document will outline some guidelines on contributing to pycsw. As well, the pycsw `community `_ is a great place to get an idea of how to connect and participate in pycsw community and development. pycsw has the following modes of contribution: - GitHub Commit Access - GitHub Pull Requests Code of Conduct --------------- Contributors to this project are expected to act respectfully toward others in accordance with the `OSGeo Code of Conduct `_. Contributions and Licensing --------------------------- Contributors are asked to confirm that they comply with project `license `_ guidelines. GitHub Commit Access ^^^^^^^^^^^^^^^^^^^^ - proposals to provide developers with GitHub commit access shall be emailed to the pycsw-devel `mailing list`_. Proposals shall be approved by the pycsw development team. Committers shall be added by the project admin - removal of commit access shall be handled in the same manner - each committer must send an email to the pycsw mailing list agreeing to the license guidelines (see `Contributions and Licensing Agreement Template <#contributions-and-licensing-agreement-template>`_). **This is only required once** - each committer shall be listed in https://github.com/geopython/pycsw/blob/master/COMMITTERS.txt GitHub Pull Requests ^^^^^^^^^^^^^^^^^^^^ - pull requests can provide agreement to license guidelines as text in the pull request or via email to the pycsw `mailing list`_ (see `Contributions and Licensing Agreement Template <#contributions-and-licensing-agreement-template>`_). **This is only required for a contributor's first pull request. Subsequent pull requests do not require this step** - pull requests may include copyright in the source code header by the contributor if the contribution is significant or the contributor wants to claim copyright on their contribution - all contributors shall be listed at https://github.com/geopython/pycsw/graphs/contributors - unclaimed copyright, by default, is assigned to the main copyright holders as specified in https://github.com/geopython/pycsw/blob/master/LICENSE.txt Contributions and Licensing Agreement Template ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``Hi all, I'd like to contribute to pycsw. I confirm that my contributions to pycsw will be compatible with the pycsw license guidelines at the time of contribution.`` GitHub ------ Code, tests, documentation, wiki and issue tracking are all managed on GitHub. Make sure you have a `GitHub account `_. Code Overview ------------- - the pycsw `wiki `_ documents an overview of the codebase Documentation ------------- - documentation is managed in ``docs/``, in reStructuredText format - `Sphinx`_ is used to generate the documentation - See the `reStructuredText Primer `_ on rST markup and syntax. Bugs ---- pycsw's `issue tracker `_ is the place to report bugs or request enhancements. To submit a bug be sure to specify the pycsw version you are using, the appropriate component, a description of how to reproduce the bug, as well as what version of Python and platform. For convenience, you can run ``pycsw-admin.py get-sysprof`` and copy/paste the output into your issue. Forking pycsw ------------- Contributions are most easily managed via GitHub pull requests. `Fork `_ pycsw into your own GitHub repository to be able to commit your work and submit pull requests. Development ----------- GitHub Commit Guidelines ^^^^^^^^^^^^^^^^^^^^^^^^ - enhancements and bug fixes should be identified with a GitHub issue - commits should be granular enough for other developers to understand the nature / implications of the change(s) - non-trivial Git commits shall be associated with a GitHub issue. As documentation can always be improved, tickets need not be opened for improving the docs - Git commits shall include a description of changes - Git commits shall include the GitHub issue number (i.e. ``#1234``) in the Git commit log message - all enhancements or bug fixes must successfully pass all :ref:`ogc-cite` tests before they are committed - all enhancements or bug fixes must successfully pass all :ref:`tests` tests before they are committed - enhancements which can be demonstrated from the pycsw :ref:`tests` should be accompanied by example CSW request XML Coding Guidelines ^^^^^^^^^^^^^^^^^ - pycsw instead of PyCSW, pyCSW, Pycsw - always code with `PEP 8`_ conventions - always run source code through `flake8`_ and `pylint`_, using all pylint defaults except for ``C0111``. ``sbin/pycsw-pylint.sh`` is included for convenience - for exceptions which make their way to OGC ``ExceptionReport`` XML, always specify the appropriate ``locator`` and ``code`` parameters Submitting a Pull Request ^^^^^^^^^^^^^^^^^^^^^^^^^ This section will guide you through steps of working on pycsw. This section assumes you have forked pycsw into your own GitHub repository. .. code-block:: bash # setup a virtualenv virtualenv mypycsw && cd mypycsw . ./bin/activate # clone the repository locally git clone git@github.com:USERNAME/pycsw.git cd pycsw pip install -e . && pip install -r requirements-standalone.txt # add the main pycsw master branch to keep up to date with upstream changes git remote add upstream https://github.com/geopython/pycsw.git git pull upstream master # create a local branch off master # The name of the branch should include the issue number if it exists git branch issue-72 git checkout issue-72 # # make code/doc changes # git commit -am 'fix xyz (#72)' git push origin issue-72 Your changes are now visible on your pycsw repository on GitHub. You are now ready to create a pull request. A member of the pycsw team will review the pull request and provide feedback / suggestions if required. If changes are required, make them against the same branch and push as per above (all changes to the branch in the pull request apply). The pull request will then be merged by the pycsw team. You can then delete your local branch (on GitHub), and then update your own repository to ensure your pycsw repository is up to date with pycsw master: .. code-block:: bash git checkout master git pull upstream master .. _`info@osgeo.org`: mailto:info@osgeo.org .. _`PEP 8`: https://www.python.org/dev/peps/pep-0008/ .. _`flake8`: https://gitlab.com/pycqa/flake8 .. _`pylint`: https://pylint.org .. _`Sphinx`: https://www.sphinx-doc.org .. _`developer tasks`: https://github.com/geopython/pycsw/wiki/Developer-Tasks .. _`mailing list`: https://pycsw.org/community#mailing-list ================================================ FILE: Dockerfile ================================================ # ================================================================= # Authors: Ricardo Garcia Silva # Authors: Massimo Di Stefano # Authors: Tom Kralidis # Authors: Angelos Tzotsos # # Contributors: Arnulf Heimsbakk # Tom Kralidis # # Copyright (c) 2020 Ricardo Garcia Silva # Copyright (c) 2020 Massimo Di Stefano # Copyright (c) 2025 Tom Kralidis # Copyright (c) 2026 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # # ================================================================= FROM python:3.12-slim-trixie LABEL maintainer="massimods@met.no,aheimsbakk@met.no,tommkralidis@gmail.com,gcpp.kalxas@gmail.com" # Build arguments # add "--build-arg BUILD_DEV_IMAGE=true" to Docker build command when building with test/doc tools ARG BUILD_DEV_IMAGE="false" RUN apt-get update --yes && \ apt-get install --yes --no-install-recommends ca-certificates python3-setuptools libssl3t64 && \ rm -rf /var/lib/apt/lists/* RUN adduser --uid 1000 --gecos '' --disabled-password pycsw ENV PYCSW_CONFIG=/etc/pycsw/pycsw.yml WORKDIR /home/pycsw/pycsw RUN chown --recursive pycsw:pycsw . # initially copy only the requirements files COPY --chown=pycsw \ requirements.txt \ requirements-standalone.txt \ requirements-dev.txt \ ./ RUN python3 -m venv /venv && \ /venv/bin/pip3 install -U pip setuptools && \ /venv/bin/pip3 install \ --requirement requirements.txt \ --requirement requirements-standalone.txt \ psycopg2-binary gunicorn \ && if [ "$BUILD_DEV_IMAGE" = "true" ] ; then /venv/bin/pip3 install -r requirements-dev.txt; fi COPY --chown=pycsw . . COPY docker/pycsw.yml ${PYCSW_CONFIG} COPY docker/entrypoint.py /usr/local/bin/entrypoint.py RUN /venv/bin/pip3 install -e . --config-settings editable_mode=strict WORKDIR /home/pycsw EXPOSE 8000 USER pycsw ENTRYPOINT [ "/venv/bin/python3", "/usr/local/bin/entrypoint.py" ] ================================================ FILE: HISTORY.txt ================================================ pycsw Revision History =========================== See http://github.com/geopython/pycsw for commit and release history. ================================================ FILE: LICENSE.txt ================================================ The MIT License (MIT) ===================== Copyright © 2010-2026 Tom Kralidis Copyright © 2011-2026 Angelos Tzotsos Copyright © 2012-2015 Adam Hinz Copyright © 2015-2021 Ricardo Garcia Silva Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: MANIFEST.in ================================================ recursive-include pycsw *.xsd *.yaml *.html *.png *.ico include *.txt include README.md ================================================ FILE: README.md ================================================ # pycsw [![DOI](https://zenodo.org/badge/2367090.svg)](https://zenodo.org/badge/latestdoi/2367090) [![Build Status](https://github.com/geopython/pycsw/workflows/build%20%E2%9A%99%EF%B8%8F/badge.svg)](https://github.com/geopython/pycsw/actions) [![Join the chat at https://gitter.im/geopython/pycsw](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/geopython/pycsw) [![Documentation](https://readthedocs.org/projects/pycsw/badge/)](https://docs.pycsw.org) [![Vulnerabilities](https://github.com/geopython/pycsw/actions/workflows/vulnerabilities.yml/badge.svg)](https://github.com/geopython/pycsw/actions/workflows/vulnerabilities.yml) [pycsw](https://pycsw.org) is an OGC API - Records and CSW server implementation written in Python. pycsw fully implements the the [OGC API - Records (OARec) standard](https://ogcapi.ogc.org/records/) and the OpenGIS Catalogue Service Implementation Specification (Catalogue Service for the Web). Initial development started in 2010 (more formally announced in 2011). The project is certified OGC Compliant, and is an OGC Reference Implementation. Since 2015, pycsw is an official OSGeo Project. pycsw allows for the publishing and discovery of geospatial metadata via numerous APIs (OGC API - Records, CSW 2/CSW 3, OpenSearch, OAI-PMH, SRU). Existing repositories of geospatial metadata can also be exposed, providing a standards-based metadata and catalogue component of spatial data infrastructures. pycsw is Open Source, released under an MIT license, and runs on all major platforms (Windows, Linux, Mac OS X). Please read the docs at [https://pycsw.org/docs](https://pycsw.org/docs) for more information. ================================================ FILE: SECURITY.md ================================================ # pycsw Security Policy ## Reporting Security/vulnerability reports **should not** be submitted through GitHub issues or public discussions, but instead please send your report to **geopython-security nospam @ lists.osgeo.org** - (remove the blanks and 'nospam'). Please follow the [contributor guidelines](https://github.com/geopython/pycsw/blob/master/CONTRIBUTING.rst#bugs) when submitting a vulnerability report. ## Supported Versions The pycsw Project Steering Committee (PSC) will release patches for security vulnerabilities for the following versions: | Version | Supported | | ------- | ------------------ | | 2.6.x | :white_check_mark: | | 2.4.x | :white_check_mark: | | 2.2.x | :white_check_mark: | | 2.0.x | :white_check_mark: | | < 2.0 | :x: | ================================================ FILE: csw.py ================================================ #!/usr/bin/python3 -u # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """ A CGI wrapper for pycsw that reuses code from the wsgi wrapper. """ from wsgiref.handlers import CGIHandler from pycsw.wsgi import application handler = CGIHandler() handler.run(application) ================================================ FILE: default-sample.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2024 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 #ogc_schemas_location: http://foo #pretty_print: true gzip_compresslevel: 9 #domainquerytype: range #domaincounts: true #spatial_ranking: true #workers=2 #timeout=30 # templates: # path: /path/to/Jinja2/templates # static: /path/to/static/folder # css/js/img logging: level: ERROR #logfile: /tmp/pycsw.log profiles: - apiso federatedcatalogues: - id: arctic-sdi-csw type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: pycsw-cite-demo type: OARec title: pycsw OGC CITE demo and Reference Implementation uresultsrl: https://demo.pycsw.org/cite - id: fedcat03 type: STAC-API title: Copernicus Data Space Ecosystem (CDSE) asset-level STAC catalogue url: https://stac.dataspace.copernicus.eu/v1 collections: - daymet-annual-pr manager: transactions: false allowed_ips: - 127.0.0.1 csw_harvest_pagesize: 10 #pubsub: # broker: # type: mqtt # url: mqtt://localhost:1883 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery - metadata keywords_type: theme fees: None accessconstraints: None terms_of_service: https://creativecommons.org/licenses/by/4.0 url: https://example.org license: name: CC-BY 4.0 license url: https://creativecommons.org/licenses/by/4.0 provider: name: Organization Name url: https://pycsw.org contact: name: Lastname, Firstname position: Position Title address: Mailing Address city: City stateorprovince: Administrative Area postalcode: Zip or Postal Code country: Country phone: +xx-xxx-xxx-xxxx fax: +xx-xxx-xxx-xxxx email: you@example.org url: Contact URL hours: Mo-Fr 08:00-17:00 instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: true languages_supported: - eng - gre default_language: eng date: YYYY-MM-DD gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: Organization Name contact_email: Email Address temp_extent: begin: YYYY-MM-DD end: YYYY-MM-DD repository: # sqlite database: sqlite:////var/www/pycsw/tests/functionaltests/suites/cite/data/cite.db # postgres #database: postgresql://username:password@localhost/pycsw # mysql #database: mysql://username:password@localhost/pycsw?charset=utf8 #mappings: path/to/mappings.py table: records #filter: type = 'http://purl.org/dc/dcmitype/Dataset' #max_retries: 5 #stable_sort: true facets: - type - title ================================================ FILE: docker/compose/docker-compose.scale.yml ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # Authors: Tom Kralidis # # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2025 Tom Kralidis # Copyright (c) 2025 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= # # # This docker compose file demos how to use the pycsw docker image with a # PostgreSQL/PostGIS database. # # docker compose usage: # # docker compose up # # docker stack (in a docker swarm): # # PYCSW_DOCKER_IMAGE=2.1-dev docker stack deploy --compose-file docker-compose.yml pycsw # services: db: container_name: db image: postgis/postgis:17-3.5 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: mypass POSTGRES_DB: pycsw PGDATA: /var/lib/postgresql/data/pgdata volumes: - db-data:/var/lib/postgresql/data/pgdata ports: - 5432:5432 networks: - pycsw-net pycsw: image: geopython/pycsw:${PYCSW_DOCKER_IMAGE} environment: PYCSW_SERVER_URL: http://localhost:8000 # deploy 5 instances of pycsw, from ports 8000-8004 deploy: replicas: 5 ports: - 8000-8004:8000 volumes: - ./pycsw.yml:/etc/pycsw/pycsw.yml networks: - pycsw-net networks: pycsw-net: volumes: db-data: ================================================ FILE: docker/compose/docker-compose.yml ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # Authors: Tom Kralidis # # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2025 Tom Kralidis # Copyright (c) 2025 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= # # # This docker compose file demos how to use the pycsw docker image with a # PostgreSQL/PostGIS database. # # docker compose usage: # # docker compose up # # docker stack (in a docker swarm): # # PYCSW_DOCKER_IMAGE=2.1-dev docker stack deploy --compose-file docker-compose.yml pycsw # services: db: container_name: db image: postgis/postgis:17-3.5 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: mypass POSTGRES_DB: pycsw PGDATA: /var/lib/postgresql/data/pgdata volumes: - db-data:/var/lib/postgresql/data/pgdata ports: - 5432:5432 networks: - pycsw-net pycsw: container_name: pycsw image: geopython/pycsw:${PYCSW_DOCKER_IMAGE} environment: PYCSW_SERVER_URL: http://localhost:8000 ports: - 8000:8000 volumes: - ./pycsw.yml:/etc/pycsw/pycsw.yml networks: - pycsw-net networks: pycsw-net: volumes: db-data: ================================================ FILE: docker/compose/pycsw.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # Ricardo Garcia Silva # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: ${PYCSW_SERVER_URL} mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 timeout: 30 #ogc_schemas_location: http://foo #pretty_print: true gzip_compresslevel: 9 #domainquerytype: range #domaincounts: true #spatial_ranking: true #workers=2 logging: level: DEBUG #logfile: /tmp/pycsw.log profiles: - apiso federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw manager: transactions: false allowed_ips: - 127.0.0.1 # csw_harvest_pagesize: 10 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery - metadata keywords_type: theme fees: None accessconstraints: None terms_of_service: https://creativecommons.org/licenses/by/4.0 url: https://example.org license: name: CC-BY 4.0 license url: https://creativecommons.org/licenses/by/4.0 provider: name: Organization Name url: https://pycsw.org contact: name: Lastname, Firstname position: Position Title address: Mailing Address city: City stateorprovince: Administrative Area postalcode: Zip or Postal Code country: Country phone: +xx-xxx-xxx-xxxx fax: +xx-xxx-xxx-xxxx email: you@example.org url: Contact URL hours: Mo-Fr 08:00-17:00 instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: true languages_supported: - eng - gre default_language: eng date: YYYY-MM-DD gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: Organization Name contact_email: Email Address temp_extent: begin: YYYY-MM-DD end: YYYY-MM-DD repository: database: 'postgresql://postgres:mypass@db/pycsw' table: records ================================================ FILE: docker/entrypoint.py ================================================ #!/usr/bin/env python3 # ================================================================= # # Authors: Ricardo Garcia Silva # Tom Kralidis # # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Entrypoint script for docker containers. This module serves as the entrypoint for docker containers. Its main purpose is to set up the pycsw database so that newly generated containers may be useful soon after being launched, without requiring additional input. """ import argparse import logging import os import sys from pycsw.core.config import StaticContext from pycsw.core.repository import Repository, setup from pycsw.ogc.api.util import yaml_load LOGGER = logging.getLogger(__name__) def launch_pycsw(pycsw_config, workers=2, reload=False): """Launch pycsw. Main function of this entrypoint script. It will read pycsw's config file and handle the specified repository backend, after which it will yield control to the gunicorn wsgi server. The ``os.execlp`` function is used to launch gunicorn. This causes it to replace the current process - something analogous to bash's `exec` command, which seems to be a common techinque when writing docker entrypoint scripts. This means gunicorn will become PID 1 inside the container and it somehow simplifies the process of interacting with it (e.g. if the need arises to restart the worker processes). It also allows for a clean exit. See http://docs.gunicorn.org/en/latest/signals.html for more information on how to control gunicorn by sending UNIX signals. """ database = pycsw_config['repository'].get('database') table = pycsw_config['repository'].get('table') try: setup(database, table) except Exception as err: LOGGER.debug(err) repo = Repository(database, StaticContext(), table=table) repo.ping() sys.stdout.flush() # we're using --reload-engine=poll because there is a bug with gunicorn # that prevents using inotify together with python3. For more info: # # https://github.com/benoitc/gunicorn/issues/1477 # timeout = pycsw_config["server"].get('timeout', 30) args = ["--reload", "--reload-engine=poll"] if reload else [] execution_args = ["gunicorn"] + args + [ "--bind=0.0.0.0:8000", "--access-logfile=-", "--error-logfile=-", f"--workers={workers}", f"--timeout={timeout}", 'pycsw.wsgi_flask:APP' ] LOGGER.debug(f"Launching pycsw with {' '.join(execution_args)} ...") os.execlp( "/venv/bin/gunicorn", *execution_args ) if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( "--workers", default=2, help="Number of workers to use by the gunicorn server. Defaults to 2." ) parser.add_argument( "-r", "--reload", action="store_true", help="Should the gunicorn server automatically restart workers when " "code changes? This option is only useful for development. " "Defaults to False." ) args = parser.parse_args() with open(os.getenv('PYCSW_CONFIG'), encoding='utf8') as fh: config = yaml_load(fh) level = config['logging'].get('level', 'WARNING') workers = int(config['server'].get('workers', args.workers)) logging.basicConfig(level=getattr(logging, level)) launch_pycsw(config, workers=workers, reload=args.reload) ================================================ FILE: docker/helm/Chart.yaml ================================================ apiVersion: v2 name: pycsw description: A Helm chart for pycsw version: 3.0.0-beta2 appVersion: 3.0.0-beta2 ================================================ FILE: docker/helm/README.md ================================================ # Helm chart for pycsw services Debug with: ```bash helm install --dry-run --debug pycsw . ``` Test template rendering with: ```bash helm template --debug . ``` Deploy with: ```bash helm install pycsw . ``` The server should then be made available at the host/port specified by `minikube service pycsw --url`. ================================================ FILE: docker/helm/templates/db-data-persistentvolumeclaim.yaml ================================================ apiVersion: v1 kind: PersistentVolumeClaim metadata: namespace: {{ .Values.global.namespace }} creationTimestamp: null labels: io.kompose.service: {{ .Values.db.volume_name }} name: {{ .Values.db.volume_name }} spec: {{ if .Values.db.volume_storage_type }} storageClassName: {{ .Values.db.volume_storage_type }} {{ end }} accessModes: - {{ .Values.db.volume_access_modes }} resources: requests: storage: {{ .Values.db.volume_size }} status: {} ================================================ FILE: docker/helm/templates/db-service.yaml ================================================ apiVersion: v1 kind: Service metadata: namespace: {{ .Values.global.namespace }} labels: io.kompose.service: {{ .Values.db.name }} name: {{ .Values.db.name }} spec: ports: - name: "default" port: {{ .Values.db.port }} targetPort: {{ .Values.db.port }} selector: io.kompose.service: {{ .Values.db.name }} ================================================ FILE: docker/helm/templates/db-statefulset.yaml ================================================ apiVersion: apps/v1 kind: StatefulSet metadata: namespace: {{ .Values.global.namespace }} labels: io.kompose.service: {{ .Values.db.name }} name: {{ .Values.db.name }} spec: replicas: 1 selector: matchLabels: io.kompose.service: {{ .Values.db.name }} # strategy: # type: Recreate serviceName: {{ .Values.db.name }} template: metadata: labels: io.kompose.service: {{ .Values.db.name }} spec: containers: - env: - name: PGDATA value: {{ .Values.db.volume_path }} - name: POSTGRES_DB value: {{ .Values.db.database }} - name: POSTGRES_PASSWORD value: {{ .Values.db.pass }} - name: POSTGRES_USER value: {{ .Values.db.user }} image: {{ .Values.db.image }} name: {{ .Values.db.name }} ports: - containerPort: {{ .Values.db.port }} resources: {} volumeMounts: - mountPath: {{ .Values.db.volume_path }} name: {{ .Values.db.volume_name }} securityContext: readOnlyRootFilesystem: true restartPolicy: Always volumeClaimTemplates: - metadata: name: {{ .Values.db.volume_name }} spec: storageClassName: {{ .Values.db.volume_storage_type }} accessModes: - {{ .Values.db.volume_access_modes }} resources: requests: storage: {{ .Values.db.volume_size }} # status: {} ================================================ FILE: docker/helm/templates/pycsw-configmap.yaml ================================================ apiVersion: v1 data: pycsw.yml: |+ {{- if .Values.pycsw.config }} {{- toYaml .Values.pycsw.config | nindent 4 -}} {{- end }} kind: ConfigMap metadata: name: {{ .Values.pycsw.configmap_name }} namespace: {{ .Values.global.namespace }} ================================================ FILE: docker/helm/templates/pycsw-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: namespace: {{ .Values.global.namespace }} labels: io.kompose.service: {{ .Values.pycsw.name }} name: {{ .Values.pycsw.name }} spec: replicas: 1 selector: matchLabels: io.kompose.service: {{ .Values.pycsw.name }} strategy: type: Recreate template: metadata: labels: io.kompose.service: {{ .Values.pycsw.name }} spec: containers: - env: - name: PYCSW_SERVER_URL value: {{ .Values.pycsw.config.server.url }} - name: PYCSW_REPOSITORY_DATABASE_URI value: {{ .Values.pycsw.config.repository.database }} image: {{ .Values.pycsw.image }} name: {{ .Values.pycsw.name }} ports: - containerPort: {{ .Values.pycsw.container_port }} resources: {} volumeMounts: - mountPath: {{ .Values.pycsw.volume_path }} name: {{ .Values.pycsw.volume_name }} securityContext: readOnlyRootFilesystem: true restartPolicy: Always volumes: - name: {{ .Values.pycsw.volume_name }} configMap: name: {{ .Values.pycsw.configmap_name }} ================================================ FILE: docker/helm/templates/pycsw-service.yaml ================================================ apiVersion: v1 kind: Service metadata: namespace: {{ .Values.global.namespace }} labels: io.kompose.service: {{ .Values.pycsw.name }} name: {{ .Values.pycsw.name }} spec: type: {{ .Values.pycsw.service_type }} ports: - port: {{ .Values.pycsw.service_port }} {{ if .Values.pycsw.service_node_port }} nodePort: {{ .Values.pycsw.service_node_port }} {{ end }} {{ if .Values.pycsw.service_target_port }} targetPort: {{ .Values.pycsw.service_target_port }} {{ end }} {{ if .Values.pycsw.service_port_protocol }} protocol: {{ .Values.pycsw.service_port_protocol }} {{ end }} name: {{ .Values.pycsw.service_port_name }} selector: io.kompose.service: {{ .Values.pycsw.name }} ================================================ FILE: docker/helm/values.yaml ================================================ global: namespace: default db: name: db image: postgis/postgis:17-3.5 port: 5432 database: pycsw user: postgres pass: mypass volume_name: db-data volume_path: /var/lib/postgresql/data/pgdata volume_size: 500Mi volume_access_modes: ReadWriteOnce volume_storage_type: standard pycsw: name: pycsw image: geopython/pycsw:latest container_port: 8000 service_type: NodePort service_port: 8000 service_port_name: http service_node_port: 30000 # service_port_protocol: TCP # service_target_port: 8000 configmap_name: pycsw-configmap volume_name: pycsw-config volume_path: /etc/pycsw config: server: url: http://localhost:8000 mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 # ogc_schemas_base: http://foo # pretty_print: true # gzip_compresslevel: 8 # domainquerytype: range # domaincounts: true # spatial_ranking: true # workers: 2 timeout: 30 logging: level: ERROR # logfile: /tmp/pycsw.log profiles: - apiso # federatedcatalogues: # - id: fedcat01 # type: CSW # title: Arctic SDI # url: https://catalogue.arctic-sdi.org/csw manager: transactions: "false" allowed_ips: - 127.0.0.1 csw_harvest_pagesize: 10 # pubsub: # broker: # type: mqtt # url: mqtt://localhost:1883 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery - metadata keywords_type: theme fees: None accessconstraints: None terms_of_service: https://creativecommons.org/licenses/by/4.0 url: https://example.org license: name: CC-BY 4.0 license url: https://creativecommons.org/licenses/by/4.0 provider: name: Organization Name url: https://pycsw.org/ contact: name: Lastname, Firstname position: Position Title address: Mailing Address city: City stateorprovince: Administrative Area postalcode: Zip or Postal Code country: Country phone: +xx-xxx-xxx-xxxx fax: +xx-xxx-xxx-xxxx email: Email Address url: Contact URL hours: Hours of Service instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: "true" languages_supported: - eng - gre default_language: eng date: YYYY-MM-DD gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: Organization Name contact_email: Email Address temp_extent: begin: YYYY-MM-DD end: YYYY-MM-DD repository: database: postgresql://postgres:mypass@db/pycsw table: records # mappings: path/to/mappings.py # filter: type = 'http://purl.org/dc/dcmitype/Dataset' # max_retries: 5 # stable_sort: true facets: - type - title ================================================ FILE: docker/kubernetes/Makefile ================================================ PYCSW_DOCKER_IMAGE=latest convert: PYCSW_DOCKER_IMAGE=$(PYCSW_DOCKER_IMAGE) kompose convert --volumes hostPath up: kubectl apply -f db-data-persistentvolumeclaim.yaml kubectl apply -f db-deployment.yaml kubectl apply -f db-service.yaml kubectl apply -f pycsw-configmap.yaml kubectl apply -f pycsw-deployment.yaml kubectl apply -f pycsw-service.yaml down: kubectl delete service pycsw kubectl delete service db kubectl delete deployment pycsw kubectl delete deployment db remove-volumes: kubectl delete configmap pycsw-config kubectl delete PersistentVolumeClaim db-data open: minikube service pycsw --url restart: down up status: kubectl get all -o wide ================================================ FILE: docker/kubernetes/db-data-persistentvolumeclaim.yaml ================================================ apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null labels: io.kompose.service: db-data name: db-data spec: accessModes: - ReadWriteOnce resources: requests: storage: 500Mi status: {} ================================================ FILE: docker/kubernetes/db-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: labels: io.kompose.service: db name: db spec: replicas: 1 selector: matchLabels: io.kompose.service: db strategy: type: Recreate template: metadata: labels: io.kompose.service: db spec: containers: - env: - name: PGDATA value: /var/lib/postgresql/data/pgdata - name: POSTGRES_DB value: pycsw - name: POSTGRES_PASSWORD value: mypass - name: POSTGRES_USER value: postgres image: postgis/postgis:17-3.5 name: db ports: - containerPort: 5432 resources: {} volumeMounts: - mountPath: /var/lib/postgresql/data/pgdata name: db-data securityContext: readOnlyRootFilesystem: true restartPolicy: Always volumes: - name: db-data persistentVolumeClaim: claimName: db-data status: {} ================================================ FILE: docker/kubernetes/db-service.yaml ================================================ apiVersion: v1 kind: Service metadata: labels: io.kompose.service: db name: db spec: ports: - name: "5432" port: 5432 targetPort: 5432 selector: io.kompose.service: db status: loadBalancer: {} ================================================ FILE: docker/kubernetes/pycsw-configmap.yaml ================================================ apiVersion: v1 data: pycsw.yml: |+ # ================================================================= # # Authors: Tom Kralidis # Ricardo Garcia Silva # Angelos Tzotsos # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2024 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: ${PYCSW_SERVER_URL} mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 timeout: 30 #ogc_schemas_location: http://foo #pretty_print: true #gzip_compresslevel: 9 #domainquerytype: range #domaincounts: true #spatial_ranking: true #workers=2 logging: level: DEBUG #logfile: /tmp/pycsw.log profiles: - apiso federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw manager: transactions: false allowed_ips: - 127.0.0.1 #csw_harvest_pagesize: 10 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery - metadata keywords_type: theme fees: None accessconstraints: None terms_of_service: https://creativecommons.org/licenses/by/4.0 url: https://example.org license: name: CC-BY 4.0 license url: https://creativecommons.org/licenses/by/4.0 provider: name: Organization Name url: https://pycsw.org contact: name: Lastname, Firstname position: Position Title address: Mailing Address city: City stateorprovince: Administrative Area postalcode: Zip or Postal Code country: Country phone: +xx-xxx-xxx-xxxx fax: +xx-xxx-xxx-xxxx email: you@example.org url: Contact URL hours: Mo-Fr 08:00-17:00 instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: true languages_supported: - eng - gre default_language: eng date: YYYY-MM-DD gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: Organization Name contact_email: Email Address temp_extent: begin: YYYY-MM-DD end: YYYY-MM-DD repository: database: ${PYCSW_REPOSITORY_DATABASE_URI} table: records facets: - type - title kind: ConfigMap metadata: creationTimestamp: "2020-10-12T20:12:04Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:pycsw_config: {} manager: kubectl operation: Update time: "2020-10-12T20:12:04Z" name: pycsw-configmap namespace: default resourceVersion: "192581" selfLink: /api/v1/namespaces/default/configmaps/pycsw-configmap uid: 95a9327a-0091-4f07-abf9-093f59dc3a24 ================================================ FILE: docker/kubernetes/pycsw-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: labels: io.kompose.service: pycsw name: pycsw spec: replicas: 1 selector: matchLabels: io.kompose.service: pycsw strategy: type: Recreate template: metadata: labels: io.kompose.service: pycsw spec: containers: - env: - name: PYCSW_SERVER_URL value: http://localhost:8000 - name: PYCSW_REPOSITORY_DATABASE_URI value: postgresql://postgres:mypass@db/pycsw image: 'geopython/pycsw:latest' name: pycsw ports: - containerPort: 8000 resources: {} volumeMounts: - mountPath: /etc/pycsw name: pycsw-config securityContext: readOnlyRootFilesystem: true restartPolicy: Always volumes: - name: pycsw-config configMap: name: pycsw-configmap status: {} ================================================ FILE: docker/kubernetes/pycsw-service.yaml ================================================ apiVersion: v1 kind: Service metadata: labels: io.kompose.service: pycsw name: pycsw spec: type: NodePort ports: - port: 8000 nodePort: 30000 selector: io.kompose.service: pycsw status: loadBalancer: {} ================================================ FILE: docker/min-apk ================================================ #!/bin/sh -e apk --update add $@ && rm -rf /var/cache/apk/* || false strip --strip-unneeded --strip-debug /usr/lib/*.a || true ================================================ FILE: docker/pycsw.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # Ricardo Garcia Silva # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost:8000/ mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 timeout: 30 #ogc_schemas_location: http://foo #pretty_print: true gzip_compresslevel: 9 #domainquerytype: range #domaincounts: true #spatial_ranking: true #workers=2 logging: level: DEBUG #logfile: /tmp/pycsw.log profiles: - apiso federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw manager: transactions: false allowed_ips: - 127.0.0.1 # csw_harvest_pagesize: 10 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery - metadata keywords_type: theme fees: None accessconstraints: None terms_of_service: https://creativecommons.org/licenses/by/4.0 url: https://example.org license: name: CC-BY 4.0 license url: https://creativecommons.org/licenses/by/4.0 provider: name: Organization Name url: https://pycsw.org contact: name: Lastname, Firstname position: Position Title address: Mailing Address city: City stateorprovince: Administrative Area postalcode: Zip or Postal Code country: Country phone: +xx-xxx-xxx-xxxx fax: +xx-xxx-xxx-xxxx email: you@example.org url: Contact URL hours: Mo-Fr 08:00-17:00 instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: true languages_supported: - eng - gre default_language: eng date: YYYY-MM-DD gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: Organization Name contact_email: Email Address temp_extent: begin: YYYY-MM-DD end: YYYY-MM-DD repository: # sqlite database: 'sqlite:////home/pycsw/pycsw/tests/functionaltests/suites/cite/data/cite.db' table: records ================================================ FILE: docs/Makefile ================================================ # Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -W -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: mkdir -p $(BUILDDIR) $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pycsw.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pycsw.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/pycsw" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pycsw" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." ================================================ FILE: docs/_static/favicon/browserconfig.xml ================================================ #2d89ef ================================================ FILE: docs/_templates/indexsidebar.html ================================================

pycsw

pycsw is Certified OGC Compliant and is an OGC Reference Implementation

DOI

This product conforms to the OpenGIS Catalogue Service Implementation Specification [Catalogue Service for the Web], Revision 2.0.2. OGC, OGC®, and CERTIFIED OGC COMPLIANT are trademarks or registered trademarks of the Open Geospatial Consortium, Inc. in the United States and other countries.

This product conforms to the OpenGIS Catalogue Service Implementation Specification [Catalogue Service for the Web], Revision 3.0.0. OGC, OGC®, and CERTIFIED OGC COMPLIANT are trademarks or registered trademarks of the Open Geospatial Consortium, Inc. in the United States and other countries.

This product conforms to the OpenGIS Catalogue Service Implementation Specification [Catalogue Service for the Web], Revision 2.0.2. OGC, OGC®, and CERTIFIED OGC COMPLIANT are trademarks or registered trademarks of the Open Geospatial Consortium, Inc. in the United States and other countries.

This product conforms to the OGC GeoRSS Encoding Standard version 1.0. OGC, OGC®, and CERTIFIED OGC COMPLIANT are trademarks or registered trademarks of the Open Geospatial Consortium, Inc. in the United States and other countries.

OSGeo Project

================================================ FILE: docs/_templates/layout.html ================================================ {% extends "!layout.html" %} {%- block extrahead %} {{ super() }} {% endblock %} {% block relbar1 %} {{ super() }} {% endblock %} {% block footer %} {% endblock %} ================================================ FILE: docs/administration.rst ================================================ .. _administration: Administration ============== pycsw administration is handled by the ``pycsw-admin.py`` utility. ``pycsw-admin.py`` is installed as part of the pycsw install process and should be available in your PATH. .. note:: Run ``pycsw-admin.py --help`` to see all administration operations and parameters Metadata Repository Setup ------------------------- pycsw supports the following databases: - SQLite3 - PostgreSQL (without PostGIS) - PostgreSQL with PostGIS enabled - MySQL .. note:: The easiest and fastest way to deploy pycsw is to use SQLite3 as the backend. To use an SQLite in-memory database, in the pycsw configuration, set `repository.database` to ``sqlite://``. .. note:: PostgreSQL support includes support for PostGIS functions if enabled .. note:: If PostGIS is activated before setting up the pycsw/PostgreSQL database, then native PostGIS geometries will be enabled. To expose your geospatial metadata via pycsw, perform the following actions: - setup the database - import metadata - publish the repository Supported Information Models ---------------------------- By default, pycsw's API supports the core OGC API - Records and CSW Record information models. From the database perspective, the pycsw metadata model is loosely based on ISO 19115 and is able to transform to other formats as part of transformation during OGC API - Records/CSW requests. .. note:: See :ref:`profiles` for information on enabling profiles .. note:: See :ref:`metadata-model-reference` for detailed information on pycsw's internal metadata model Setting up the Database ----------------------- .. code-block:: bash pycsw-admin.py setup-repository --config default.yml This will create the necessary tables and values for the repository. The database created is an `OGC SFSQL`_ compliant database, and can be used with any implementing software. For example, to use with `GDAL`_: .. code-block:: bash ogrinfo /path/to/records.db INFO: Open of 'records.db' using driver 'SQLite' successful. 1: records (Polygon) ogrinfo -al /path/to/records.db # lots of output .. note:: If PostGIS is detected, the ``pycsw-admin.py`` script does not create the SFSQL tables as they are already in the database. Loading Records ---------------- .. code-block:: bash pycsw-admin.py load-records --config default.yml --path /path/to/records This will import all ``*.xml`` records from ``/path/to/records`` into the database specified in ``default.yml`` (``repository.database``). Passing ``-r`` to the script will process ``/path/to/records`` recursively. Passing ``-y`` to the script will force overwrite existing metadata with the same identifier. Note that ``-p`` accepts either a directory path or single file. .. note:: Records can also be imported using CSW-T (see :ref:`transactions`). Exporting the Repository ------------------------ .. code-block:: bash pycsw-admin.py export-records --config default.yml --path /path/to/output_dir This will write each record in the database specified in ``default.yml`` (``repository.database``) to an XML document on disk, in directory ``/path/to/output_dir``. Optimizing the Database ----------------------- .. code-block:: bash pycsw-admin.py optimize-db --config default.yml pycsw-admin.py rebuild-db-indexes --config default.yml .. note:: This feature is relevant only for PostgreSQL and MySQL Deleting Records from the Repository ------------------------------------ .. code-block:: bash pycsw-admin.py delete-records --config default.yml This will empty the repository of all records. Database Specific Notes ----------------------- PostgreSQL ^^^^^^^^^^ - To enable PostgreSQL support, the database user must be able to create functions within the database. - `PostgreSQL Full Text Search`_ is supported for ``csw:AnyText`` based queries. pycsw creates a tsvector column based on the text from anytext column. Then pycsw creates a GIN index against the anytext_tsvector column. This is created automatically in ``pycsw.core.repository.setup``. Any query against the OGC API - Records ``q`` parameter or CSW `csw:AnyText` or `apiso:AnyText` will process using PostgreSQL FTS handling PostGIS ^^^^^^^ - pycsw makes use of PostGIS spatial functions and native geometry data type. - It is advised to install the PostGIS extension before setting up the pycsw database - If PostGIS is detected, the ``pycsw-admin.py`` script will create both a native geometry column and a WKT column, as well as a trigger to keep both synchronized - In case PostGIS gets disabled, pycsw will continue to work with the `WKT`_ column - In case of migration from plain PostgreSQL database to PostGIS, the spatial functions of PostGIS will be used automatically - When migrating from plain PostgreSQL database to PostGIS, in order to enable native geometry support, a "GEOMETRY" column named "wkb_geometry" needs to be created manually (along with the update trigger in ``pycsw.core.repository.setup``). Also the native geometries must be filled manually from the `WKT`_ field. Next versions of pycsw will automate this process .. _custom_repository: Mapping to an Existing Repository --------------------------------- pycsw supports publishing metadata from an existing repository. To enable this functionality, the default database mappings must be modified to represent the existing database columns mapping to the abstract core model (the default mappings are in ``pycsw/core/config.py:StaticContext.md_core_model``). To override the default settings: - define a custom database mapping based on ``etc/mappings.py`` - in ``default.yml``, set ``repository.mappings`` to the location of the mappings.py file: .. code-block:: yaml repository: ... mappings: path/to/mappings.py Note you can also reference mappings as a Python object as a dotted path: .. code-block:: yaml repository: ... mappings: path.to.pycsw_mappings See the :ref:`geonode`, :ref:`hhypermap`, and :ref:`odc` for further examples. .. _existing-repository-requirements: Existing Repository Requirements ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pycsw requires certain repository attributes and semantics to exist in any repository to operate as follows: - ``pycsw:Identifier``: unique identifier - ``pycsw:Typename``: typename for the metadata; typically the value of the root element tag (e.g. ``csw:Record``, ``gmd:MD_Metadata``) - ``pycsw:Schema``: schema for the metadata; typically the target namespace (e.g. ``http://www.opengis.net/cat/csw/2.0.2``, ``http://www.isotc211.org/2005/gmd``) - ``pycsw:InsertDate``: date of insertion - ``pycsw:XML``: full XML representation (deprecated; will be removed in a future release) - ``pycsw:Metadata``: full metadata representation - ``pycsw:MetadataType``: media type of metadata representation - ``pycsw:AnyText``: bag of XML element text values, used for full text search. Realized with the following design pattern: - capture all XML element and attribute values - store in repository - ``pycsw:BoundingBox``: string of `WKT`_ or `EWKT`_ geometry The following repository semantics exist if the attributes are specified: - ``pycsw:Keywords``: comma delimited list of keywords - ``pycsw:Themes``: Text field of JSON list of objects with properties ``concepts``, ``scheme`` .. code-block:: json [ { "concepts": [ { "id": "atmosphericComposition" }, { "id": "pollution" }, { "id": "observationPlatform" }, { "id": "rocketSounding" } ], "scheme": "https://wis.wmo.int/2012/codelists/WMOCodeLists.xml#WMO_CategoryCode" } ] - ``pycsw:Contacts``: Text field of JSON list of objects with properties as per the OGC API - Records party definition .. code-block:: json [ { "name": "contact", "individual": "Lastname, Firstname", "positionName": "Position Title", "contactInfo": { "phone": { "office": "+xx-xxx-xxx-xxxx" }, "email": { "office": "you@example.org" }, "address": { "office": { "deliveryPoint": "Mailing Address", "city": "City", "administrativeArea": "Administrative Area", "postalCode": "Zip or Postal Code", "country": "COuntry" }, "onlineResource": { "href": "Contact URL" } }, "hoursOfService": "Hours of Service", "contactInstructions": "During hours of service. Off on weekends", "url": { "rel": "canonical", "type": "text/html", "href": "https://example.org" } }, "roles": [ { "name": "pointOfContact" } ] } ] - ``pycsw:Links``: Text field of JSON list of objects with properties ``name``, ``description``, ``protocol``, ``url`` .. code-block:: json [ { "name": "foo", "description": "bar", "protocol": "OGC:WMS", "url": "https://example.org/wms" } ] .. note:: The ``pycsw:Links`` field should be a text type, not a JSON object type - ``pycsw:Bands``: Text field of JSON list of dicts with properties: ``name``, ``units``, ``min``, ``max`` .. code-block:: json [ { "name": "B1", "units": "nm", "min": 0.1, "max": 0.333 } ] .. note:: The ``pycsw:Bands`` field should be a text type, not a JSON object type Values of mappings can be derived from the following mechanisms: - text fields - Python datetime.datetime or datetime.date objects - Python functions Further information is provided in ``pycsw/config.py:MD_CORE_MODEL``. .. note:: See :ref:`metadata-model-reference` for detailed information on pycsw's internal metadata model Using a SQL View as the repository table ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If your pre-existing database stores information in a normalized fashion, *i.e.* distributed on multiple tables rather than on a single table (which is what pycsw expects by default), you have the option to create a DB view and use that as pycsw's repository. As a practical example, lets say you have a `CKAN`_ project which you would like to also provide pycsw integration with. CKAN stores dataset-related information over multiple tables: - ``package`` - has base metadata fields for each dataset; - ``package_extra`` - additional custom metadata fields, depending on the user's metadata schema; - ``package_tag`` - dataset_related keywords; - ``tag`` - dataset_related keywords; - ``group`` - details about a dataset's owner organization; - etc. One way to adapt such a DB structure to be able to integrate with pycsw is to create a `PostgreSQL Materialized View`_. For example: .. code-block:: SQL CREATE MATERIALIZED VIEW IF NOT EXISTS my_pycsw_view AS WITH cte_extras AS ( SELECT p.id, p.title, g.title AS org_name, json_object_agg(pe.key, pe.value) AS extras, array_agg(DISTINCT t.name) AS tags -- remaining columns omitted for brevity FROM package AS p JOIN package_extra AS pe ON p.id = pe.package_id JOIN "group" AS g ON p.owner_org = g.id JOIN package_tag AS pt ON p.id = pt.package_id JOIN tag AS t on pt.tag_id = t.id WHERE p.state = 'active' AND p.private = false GROUP BY p.id, g.title ) SELECT c.id AS identifier, c.title AS title, c.org_name AS organization, ST_GeomFromGeoJSON(c.extras->>'spatial')::geometry(Polygon, 4326) AS geom, c.extras->>'reference_date' AS date, concat_ws(', ', VARIADIC c.tags) AS keywords -- remaining columns omitted for brevity FROM cte_extras AS c WITH DATA; Creating this SQL view in the database means that all we now have the CKAN dataset information all on a single flat table, ready for pycsw to integrate with. A crucial setup that is required in order for SQL Views to be usable by pycsw is to include the additional ``column_constraints`` property in your custom mappings. This property is used to specify which column(s) should function as the primary key of the SQL View: .. code-block:: python # contents of my_custom_pycsw_mappings.py from sqlalchemy.schema import PrimaryKeyConstraint MD_CORE_MODEL = { "column_constraints": (PrimaryKeyConstraint("identifier"),), "typename": "pycsw:CoreMetadata", "outputschema": "http://pycsw.org/metadata", "mappings": { "pycsw:Identifier": "identifier", # remaining mappings omitted for brevity The above code snippet demonstrates how you could instruct sqlalchemy, which is what pycsw uses to interface with the DB, that the ``identifier`` column of the SQL view should be assumed to be the primary key of the table. Finally, we can configure pycsw with the path to the custom mappings and the name of the SQL view: .. code-block:: yaml # file: pycsw.yml repository: database: postgresql://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME} mappings: /path/to/my_custom_pycsw_mappings.py table: my_pycsw_view .. _`GDAL`: https://www.gdal.org .. _`OGC SFSQL`: https://www.ogc.org/standards/sfs .. _`WKT`: https://en.wikipedia.org/wiki/Well-known_text .. _`EWKT`: https://en.wikipedia.org/wiki/Well-known_text#Variations .. _`PostgreSQL Full Text Search`: https://www.postgresql.org/docs/current/textsearch.html .. _`CKAN`: https://ckan.org/ .. _`PostgreSQL Materialized View`: https://www.postgresql.org/docs/current/sql-creatematerializedview.html ================================================ FILE: docs/api.rst ================================================ .. _api: API === Python applications can integrate pycsw into their custom workflows. This allows for seamless integate within frameworks such as Flask and Django. Below are examples of where using the API (as opposed to the default WSGI/CGI services could be used: - configuration based on a Python dict, or stored in a database - downstream request environment / framework (Flask, Django) - authentication or authorization logic - forcing CSW version 2.0.2 as default OGC API - Records Flask Example ------------------------------- See https://github.com/geopython/pycsw/blob/master/pycsw/wsgi_flask.py for how to implement a Flask wrapper atop all pycsw supported APIs. Note the use of Flask blueprints to enable integration with downstream Flask applications. Simple Flask blueprint example ------------------------------ .. code-block:: python from flask import Flask, redirect from pycsw.wsgi_flask import BLUEPRINT as pycsw_blueprint app = Flask(__name__, static_url_path='/static') app.url_map.strict_slashes = False app.register_blueprint(pycsw_blueprint, url_prefix='/oapi') @app.route('/') def hello_world(): return "Hello, World!" In the above example, all pycsw endpoints are made available under ``http://localhost:8000/oapi``. Simple CSW Flask Example ------------------------ .. code-block:: python import logging from flask import Flask, request from pycsw import __version__ as pycsw_version from pycsw.server import Csw LOGGER = logging.getLogger(__name__) APP = Flask(__name__) @APP.route('/csw') def csw_wrapper(): """CSW wrapper""" LOGGER.info('Running pycsw %s', pycsw_version) pycsw_config = some_dict # really comes from somewhere # initialize pycsw # pycsw_config: dict of the pycsw configuration # # env: dict of (HTTP) environment (defaults to os.environ) # # version: defaults to '3.0.0' my_csw = Csw(pycsw_config, request.environ, version='2.0.2') # dispatch the request http_status_code, response = my_csw.dispatch_wsgi() return response, http_status_code, {'Content-type': csw.contenttype} ================================================ FILE: docs/ckan.rst ================================================ .. _ckan: CKAN Configuration ================== CKAN (https://ckan.org) is a powerful data management system that makes data accessible – by providing tools to streamline publishing, sharing, finding and using data. CKAN is aimed at data publishers (national and regional governments, companies and organizations) wanting to make their data open and available. `ckanext-spatial`_ is CKAN's geospatial extension. 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. CKAN Setup ---------- Installation and configuration Instructions are provided as part of the ckanext-spatial `documentation`_. .. _`ckanext-spatial`: https://github.com/ckan/ckanext-spatial .. _`documentation`: https://docs.ckan.org/projects/ckanext-spatial/en/latest/csw.html ================================================ FILE: docs/committers.rst ================================================ .. _committers: Committers ========== .. include:: ../COMMITTERS.txt ================================================ FILE: docs/conf.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= # # pycsw documentation build configuration file, created by # sphinx-quickstart on Fri Aug 2 19:48:50 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 from unittest.mock import MagicMock # 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 ----------------------------------------------------- # locale locale_dirs = ['locale/'] # 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 = [] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = {'.rst': 'restructuredtext'} locale_dirs = ['locale/'] # path is example but recommended. # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'pycsw' authors = u'Tom Kralidis' license = u'This work is licensed under a Creative Commons Attribution 4.0 International License' copyright = u'2010-2026, ' + authors + ' ' + license # 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 = '3.0-dev' # The full version, including alpha/beta/rc tags. release = version # 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 = '%Y-%m-%d' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # 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 = True # 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 = [] # -- 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 = 'classic' # 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 = { 'sidebarbgcolor': '#356aa0', 'sidebarlinkcolor': '#ffffff', 'relbarlinkcolor': '#ffffff', 'footerbgcolor': '#356aa0' } # 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 = 'Documentation' # 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 = '_static/favicon/favicon.ico' # 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 = '%Y-%m-%dT%H:%M:%SZ' # 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 = { #'index':'indexsidebar.html', '**': ['indexsidebar.html'] } # 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 = False # 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 = 'pycswdoc' # -- 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', 'pycsw.tex', u'pycsw Documentation', authors, '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', 'pycsw', u'pycsw Documentation', [authors], 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', 'pycsw', u'pycsw Documentation', authors, 'pycsw', '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' # -- Options for Epub output --------------------------------------------------- # Bibliographic Dublin Core info. epub_title = u'pycsw' epub_author = authors epub_publisher = authors epub_copyright = copyright # The language of the text. It defaults to the language option # or en if the language is not set. #epub_language = '' # The scheme of the identifier. Typical schemes are ISBN or URL. #epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. #epub_identifier = '' # A unique identification for the text. #epub_uid = '' # A tuple containing the cover image and cover page html template filenames. #epub_cover = () # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_pre_files = [] # HTML files shat should be inserted after the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_post_files = [] # A list of files that should not be packed into the epub file. #epub_exclude_files = [] # The depth of the table of contents in toc.ncx. #epub_tocdepth = 3 # Allow duplicate toc entries. #epub_tocdup = True # mock out imports with C extensions for building on readthedocs.io class Mock(MagicMock): @classmethod def __getattr__(cls, name): return MagicMock() MOCK_MODULES = ['shapely'] sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) ================================================ FILE: docs/configuration.rst ================================================ .. _configuration: Configuration ============= pycsw's runtime configuration is defined by ``default.yml``. pycsw ships with a `sample configuration`_ (``default-sample.yml``). Copy the file to ``default.yml`` and edit the following: **server** - **home**: the full filesystem path to pycsw - **url**: the URL of the resulting service - **mimetype**: the MIME type when returning HTTP responses - **language**: the ISO 639-1 language and ISO 3166-1 alpha2 country code of the service (e.g. ``en-CA``, ``fr-CA``, ``en-US``) - **encoding**: the content type encoding (e.g. ``ISO-8859-1``, see https://docs.python.org/2/library/codecs.html#standard-encodings). Default value is 'UTF-8' - **maxrecords**: the maximum number of records to return by default. This value is enforced if a CSW's client's ``maxRecords`` parameter is greater than ``server.maxrecords`` to limit capacity. See :ref:`maxrecords-handling` for more information - **level**: the logging level (see https://docs.python.org/library/logging.html#logging-levels) - **logfile**: the full file path to the logfile - **ogc_schemas_base**: base URL of OGC XML schemas tree file structure (default is http://schemas.opengis.net) - **federatedcatalogues**: arrray of distributed catalogue endpoints to be used for distributed searching, if requested by the client (see :ref:`distributedsearching`) - **pretty_print**: whether to pretty print the output (``true`` or ``false``). Default is ``false`` - **gzip_compresslevel**: gzip compression level, lowest is ``1``, highest is ``9``. Default is off. **NOTE**: if gzip compression is already enabled via your web server, do not enable this directive (or else the server will try to compress the response twice, resulting in degraded performance) - **domainquerytype**: for GetDomain operations, how to output domain values. Accepted values are ``list`` and ``range`` (min/max). Default is ``list`` - **domaincounts**: for GetDomain operations, whether to provide frequency counts for values. Accepted values are ``true`` and ``False``. Default is ``false`` - **smtp_host**: SMTP host for processing ``csw:ResponseHandler`` parameter via outgoing email requests (default is ``localhost``) - **smtp_user**: SMTP user name related to the account (default is '') - **smtp_pass**: SMTP password related to the account (default is '') - **smtp_ssl**: Option to choose between SMTP and SMTP_SSL. To enable it, set the value to ``true`` (default is ``false``) - **spatial_ranking**: parameter that enables (``true`` or ``false``) ranking of spatial query results as per `K.J. Lanfear 2006 - A Spatial Overlay Ranking Method for a Geospatial Search of Text Objects `_. - **workers**: set the number of workers used by the wsgi server when lunching pycsw using the provided docker/entrypoint.py. If not set, it will use 2 workers as Default. **profiles** - list of profiles to load at runtime (default is none). See :ref:`profiles` **manager** - **transactions**: whether to enable transactions (``true`` or ``false``). Default is ``false`` (see :ref:`transactions`) - **allowed_ips**: comma delimited list of IP addresses (e.g. 192.168.0.103), wildcards (e.g. 192.168.0.*) or CIDR notations (e.g. 192.168.100.0/24) allowed to perform transactions (see :ref:`transactions`) - **csw_harvest_pagesize**: when harvesting other CSW servers, the number of records per request to page by (default is 10) **pubsub** - **broker**: Publish-Subscribe definition **pubsub.broker** - **show_link**: whether to display as a link in the landing page (``true`` or ``false``) - **type**: type of broker - **url**: endpoint of broker .. note:: See :ref:`pubsub` for configuring your instance with Pub/Sub capability. **metadata** **metadata.identification** - **title**: the title of the service - **description**: some descriptive text about the service - **keywords**: list of keywords about the service - **keywords_type**: keyword type as per the `ISO 19115 MD_KeywordTypeCode codelist `_). Accepted values are ``discipline``, ``temporal``, ``place``, ``theme``, ``stratum`` - **fees**: fees associated with the service - **accessconstraints**: access constraints associated with the service **metadata.provider** - **name**: the name of the service provider - **url**: the URL of the service provider **metadata.contact** - **name**: the name of the provider contact - **position**: the position title of the provider contact - **address**: the address of the provider contact - **city**: the city of the provider contact - **stateorprovince**: the province or territory of the provider contact - **postalcode**: the postal code of the provider contact (enclose in quotes) - **country**: the country of the provider contact - **phone**: the phone number of the provider contact (enclose in quotes) - **fax**: the facsimile number of the provider contact (enclose in quotes) - **email**: the email address of the provider contact - **url**: the URL to more information about the provider contact - **hours**: the hours of service to contact the provider - **instructions**: the how to contact the provider contact - **role**: the role of the provider contact as per the `ISO 19115 CI_RoleCode codelist `_). Accepted values are ``author``, ``processor``, ``publisher``, ``custodian``, ``pointOfContact``, ``distributor``, ``user``, ``resourceProvider``, ``originator``, ``owner``, ``principalInvestigator`` **repository** - **database**: the full file path to the metadata database, in database URL format (see https://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls) - **table**: the table name for metadata records (default is ``records``). If you are using PostgreSQL with a DB schema other than ``public``, qualify the table like ``myschema.table`` - **mappings**: custom repository mappings (see :ref:`custom_repository`) - **source**: the source of this repository only if not local (e.g. :ref:`geonode`, :ref:`odc`). Supported values are ``geonode``, ``odc`` - **filter**: server side database filter to apply as mask to all CSW requests (see :ref:`repofilters`) - **max_retries**: max number of retry attempts when connecting to records-repository database - **stable_sort**: enables stable sorting by appending an identifier sort as the last sortable. Default is ``false`` - **facets**: comma-separated list of facetable properties for search results .. note:: See :ref:`administration` for connecting your metadata repository and supported information models. .. _maxrecords-handling: MaxRecords Handling ------------------- The The following describes how ``maxRecords`` is handled by the configuration when handling OGC API - Records items or CSW ``GetRecords`` requests: .. csv-table:: :header: server.maxrecords,OGC API - Records limit/CSW GetRecords.maxRecords,Result none set,none passed,10 (CSW default) 20,14,20 20,none passed,20 none set,100,100 20,200,20 .. _alternate-configurations: Using environment variables in configuration files -------------------------------------------------- pycsw configuration supports using system environment variables, which can be helpful for deploying into `12 factor `_ environments for example. Below is an example of how to integrate system environment variables in pycsw: .. code-block:: yaml repository: database: ${PYCSW_REPOSITORY_DATABASE_URI} table: ${MY_TABLE} Alternate Configurations ------------------------ By default, pycsw loads ``default.yml`` at runtime. To load an alternate configuration, modify ``csw.py`` to point to the desired configuration. Alternatively, pycsw supports explicitly specifiying a configuration by appending ``config=/path/to/default.yml`` to the base URL of the service (e.g. ``http://localhost/pycsw/csw.py?config=tests/suites/default/default.yml&service=CSW&version=2.0.2&request=GetCapabilities``). When the ``config`` parameter is passed by a CSW client, pycsw will override the default configuration location and subsequent settings with those of the specified configuration. This also provides the functionality to deploy numerous CSW servers with a single pycsw installation. Hiding the Location ^^^^^^^^^^^^^^^^^^^ Some deployments with alternate configurations prefer not to advertise the base URL with the ``config=`` approach. In this case, there are many options to advertise the base URL. Environment Variables ~~~~~~~~~~~~~~~~~~~~~ pycsw supports the following environment variables: - ``PYCSW_CONFIG``: specifies the filepath to a pycsw configuraiton Configuration file location ^^^^^^^^^^^^^^^^^^^^^^^^^^^ One option is using Apache's ``Alias`` and ``SetEnvIf`` directives. For example, given the base URL ``http://localhost/pycsw/csw.py?config=foo.yml``, set the following in your Apache configuration: .. code-block:: none Alias /pycsw/csw-foo.py /var/www/pycsw/csw.py SetEnvIf Request_URI "/pycsw/csw-foo.py" PYCSW_CONFIG=/var/www/pycsw/csw-foo.yml. .. note:: Apache must be restarted after changes to configuration pycsw will use the configuration as set in the ``PYCSW_CONFIG`` environment variable in the same manner as if it was specified in the base URL. Note that the configuration value ``server.url`` value must match the ``Request_URI`` value so as to advertise correctly in pycsw's Capabilities XML. Wrapper Script ~~~~~~~~~~~~~~ Another option is to write a simple wrapper (e.g. ``csw-foo.sh``), which provides the same functionality and can be deployed without restarting Apache: .. code-block:: bash #!/bin/sh export PYCSW_CONFIG=/var/www/pycsw/csw-foo.yml /var/www/pycsw/csw.py .. _`sample configuration`: https://github.com/geopython/pycsw/blob/master/default-sample.yml ================================================ FILE: docs/contributing.rst ================================================ .. _contributing: .. include:: ../CONTRIBUTING.rst ================================================ FILE: docs/csw-support.rst ================================================ .. _csw-support: CSW Support =========== Versions -------- pycsw supports both CSW 2.0.2 and 3.0.0 versions by default. In alignment with the CSW specifications, the default version returned is the latest supported version. That is, pycsw will always behave like a 3.0.0 CSW unless the client explicitly requests a 2.0.2 CSW. The sample URLs below provide examples of how requests behaves against various/missing/default version parameters. .. code-block:: bash http://localhost/csw # returns 3.0.0 Capabilities http://localhost/csw?service=CSW&request=GetCapabilities # returns 3.0.0 Capabilities http://localhost/csw?service=CSW&version=2.0.2&request=GetCapabilities # returns 2.0.2 Capabilities http://localhost/csw?service=CSW&version=3.0.0&request=GetCapabilities # returns 3.0.0 Capabilities Request Examples ---------------- The best place to look for sample requests is within the `tests/` directory, which provides numerous examples of all supported APIs and requests. Additional examples: - `Data.gov CSW HowTo v2.0`_ - `pycsw Quickstart on OSGeoLive`_ .. _`pycsw Quickstart on OSGeoLive`: https://live.osgeo.org/en/quickstart/pycsw_quickstart.html .. _`Data.gov CSW HowTo v2.0`: https://gist.github.com/kalxas/6ecb06d61cdd487dc7f9 ================================================ FILE: docs/distributedsearching.rst ================================================ .. _distributedsearching: Distributed Searching ===================== .. note:: - in CSW mode, distributed search must be configured against remote CSW services - in OGC API - Records mode, distributed search must be configured against remote OGC API - Records services .. note:: Your server must be able to make outgoing HTTP requests for this functionality. CSW 2 / 3 --------- pycsw has the ability to perform distributed searching against other CSW servers. Distributed searching is disabled by default; to enable, ``federatedcatalogues`` must be set. A CSW client must issue a GetRecords request with ``csw:DistributedSearch`` specified, along with an optional ``hopCount`` attribute (see subclause 10.8.4.13 of the CSW specification). When enabled, pycsw will search all specified catalogues and return a unified set of search results to the client. Due to the distributed nature of this functionality, requests will take extra time to process compared to queries against the local repository. Scenario: Federated Search ^^^^^^^^^^^^^^^^^^^^^^^^^^ pycsw deployment with 3 configurations (CSW-1, CSW-2, CSW-3), subsequently providing three (3) endpoints. Each endpoint is based on an opaque metadata repository (based on theme/place/discipline, etc.). Goal is to perform a single search against all endpoints. pycsw realizes this functionality by supporting :ref:`alternate configurations `, and exposes the additional CSW endpoint(s) with the following design pattern: CSW-1: ``http://localhost/pycsw/csw.py?config=CSW-1.yml`` CSW-2: ``http://localhost/pycsw/csw.py?config=CSW-2.yml`` CSW-3: ``http://localhost/pycsw/csw.py?config=CSW-3.yml`` ...where the ``*.yml`` configuration files are configured for each respective metadata repository. The above CSW endpoints can be interacted with as usual. To federate the discovery of the three (3) portals into a unified search, pycsw realizes this functionality by deploying an additional configuration which acts as the superset of CSW-1, CSW-2, CSW-3: CSW-all: ``http://localhost/pycsw/csw.py?config=CSW-all.yml`` This allows the client to invoke one (1) CSW GetRecords request, in which the CSW endpoint spawns the same GetRecords request to 1..n distributed CSW endpoints. Distributed CSW endpoints are advertised in CSW Capabilities XML via ``ows:Constraint``: .. code-block:: xml ... http://localhost/pycsw/csw.py?config=CSW-1.yml http://localhost/pycsw/csw.py?config=CSW-2.yml http://localhost/pycsw/csw.py?config=CSW-3.yml ... ...which advertises which CSW endpoint(s) the CSW server will spawn if a distributed search is requested by the client. in the CSW-all configuration: .. code-block:: yaml federatedcatalogues: - id: fedcat01 type: CSW title: Federated catalogue 1 url: http://localhost/pycsw/csw.py?config=CSW-1.yml - id: fedcat02 type: CSW title: Federated catalogue 2 url: http://localhost/pycsw/csw.py?config=CSW-2.yml - id: fedcat03 type: CSW title: Federated catalogue 3 url: http://localhost/pycsw/csw.py?config=CSW-3.yml At which point a CSW client request to CSW-all with ``distributedsearch=TRUE``, while specifying an optional ``hopCount``. Query network topology: .. code-block:: none AnyClient ^ | v CSW-all ^ | v /-------------\ ^ ^ ^ | | | v v v CSW-1 CSW-2 CSW-3 As a result, a pycsw deployment in this scenario may be approached on a per 'theme' basis, or at an aggregate level. All interaction in this scenario is local to the pycsw installation, so network performance would not be problematic. A very important facet of distributed search is as per Annex B of OGC:CSW 2.0.2. Given that all the CSW endpoints are managed locally, duplicates and infinite looping are not deemed to present an issue. OGC API - Records ----------------- Experimental support for distibuted searching is available in pycsw's OGC API - Records support to allow for searching remote services. The implementation uses the same approach as described above, operating in OGC API - Records mode as per `OGC API - Records - Part 4: Federated Search`_ (draft). .. note:: The ``federatedcatalogues`` directives must point to an OGC API - Records **collections** endpoint. .. code-block:: yaml federatedcatalogues: - id: fedcat01 type: OARec title: Federated catalogue 1 url: https://example.org/collections/collection1 - id: fedcat02 type: OARec title: Federated catalogue 2 url: https://example.org/collections/collection2 With the above configured, a distributed search can be invoked as follows: http://localhost/collections/metadata:main/items?distributedSearch=true STAC API -------- Experimental support for distibuted searching is available in pycsw's STAC API support to allow for searching remote services. The implementation uses the same approach as described above. .. note:: The ``federatedcatalogues`` directives must point to a STAC API endpoint. .. code-block:: yaml federatedcatalogues: - id: fedcat03 type: STAC-API title: Copernicus Data Space Ecosystem (CDSE) asset-level STAC catalogue url: https://stac.dataspace.copernicus.eu/v1 collections: - daymet-annual-pr .. note:: To constrain STAC API distributed search to specific collections, define one to many in the `collections` (array) directive. With the above configured, a distributed search can be invoked as follows: http://localhost/stac/search?distributedSearch=true .. _`OGC API - Records - Part 4: Federated Search`: https://github.com/opengeospatial/ogcapi-records/blob/master/extensions/federated-search/document.adoc ================================================ FILE: docs/docker.rst ================================================ Docker ====== Installation ------------ pycsw provides an official `Docker`_ image which is made available on both the `geopython Docker Hub`_ and our `GitHub Container Registry`_. Either ``IMAGE`` can be called with the ``docker`` command, ``geopython/pycsw`` from DockerHub or ``ghcr.io/geophython/pycsw`` from the GitHub Container Registry. Examples below use ``geopython/pygeoapi``. Assuming you already have docker installed, you can get a pycsw instance up and running run with the default built-in configuration: .. code-block:: bash docker run -p 8000:8000 geopython/pycsw # or docker run -p 8000:8000 ghcr.io/geopython/pycsw ...then browse to http://localhost:8000 Docker will retrieve the pycsw image (if needed) and then start a new container listening on port 8000. The default configuration will run pycsw with an sqlite repository backend loaded with some test data from the CITE test suite. You can use this to take pycsw for a test drive. Inspect logs ------------ The default configuration for the docker image outputs logs to stdout. This is common practice with docker containers and enables the inspection of logs with the ``docker logs`` command:: # run a pycsw container in the background docker run \ --name pycsw-test \ --publish 8000:8000 \ --detach \ geopython/pycsw # inspect logs docker logs pycsw-test .. note:: In order to have pycsw logs being sent to standard output you must set ``server.logfile=`` in the pycsw configuration file. Using pycsw-admin.py -------------------- ``pycsw-admin.py`` can be executed on a running container by using ``docker exec``:: docker exec -ti pycsw-admin.py --help Running custom pycsw containers ------------------------------- pycsw configuration ^^^^^^^^^^^^^^^^^^^ It is possible to supply a custom configuration file for pycsw as a bind mount or as a docker secret (in the case of docker swarm). The configuration file is searched at the value of the ``PYCSW_CONFIG`` environmental variable, which defaults to ``/etc/pycsw/pycsw.yml``. Supplying the configuration file via bind mount:: docker run \ --name pycsw \ --detach \ --volume :/etc/pycsw/pycsw.yml \ --publish 8000:8000 \ geopython/pycsw Supplying the configuration file via docker secrets:: # first create a docker secret with the pycsw config file docker secret create pycsw-config docker service create \ --name pycsw \ --secret src=pycsw-config,target=/etc/pycsw/pycsw.yml \ --publish 8000:8000 geopython/pycsw sqlite repositories ^^^^^^^^^^^^^^^^^^^ The default database repository is the CITE database that is used for running pycsw's test suites. Docker volumes may be used to specify a custom sqlite database path. It should be mounted under ``/var/lib/pycsw``:: # first create a docker volume for persisting the database when # destroying containers docker volume create pycsw-db-data docker run \ --volume db-data:/var/lib/pycsw \ --detach \ --publish 8000:8000 geopython/pycsw PostgreSQL repositories ^^^^^^^^^^^^^^^^^^^^^^^ Specifying a PostgreSQL repository is just a matter of configuring a custom pycsw.yml file with the correct specification. Check `pycsw's GitHub repository`_ for an example of a docker compose/stack file that spins up a postgis database together with a pycsw instance. Setting up a development environment with docker ------------------------------------------------ Working on pycsw's code using docker enables an isolated environment that helps ensuring reproducibility while at the same time keeping your base system free from pycsw related dependencies. This can be achieved by: * Cloning pycsw's repository locally; * Starting up a docker container with appropriately set up bind mounts. In addition, the pycsw docker image supports a ``reload`` flag that turns on automatic reloading of the gunicorn web server whenever the code changes; * Installing the development dependencies by using ``docker exec`` with the root user; The following instructions set up a fully working development environment:: # clone pycsw's repo git clone https://github.com/geopython/pycsw.git # start a container for development cd pycsw docker run \ --name pycsw-dev \ --detach \ --volume ${PWD}/pycsw:/usr/lib/python3.7/site-packages/pycsw \ --volume ${PWD}/docs:/home/pycsw/docs \ --volume ${PWD}/LICENSE.txt:/home/pycsw/LICENSE.txt \ --volume ${PWD}/COMMITTERS.txt:/home/pycsw/COMMITTERS.txt \ --volume ${PWD}/CONTRIBUTING.rst:/home/pycsw/CONTRIBUTING.rst \ --volume ${PWD}/pycsw/plugins:/home/pycsw/pycsw/plugins \ --publish 8000:8000 \ geopython/pycsw --reload # install additional dependencies used in tests and docs docker exec \ -ti \ --user root \ pycsw-dev pip3 install -r pycsw/requirements-dev.txt # run tests (for example unit tests) docker exec -ti pycsw-dev pytest -m unit pycsw # build docs docker exec -ti pycsw-dev sh -c "cd pycsw/docs && make html" .. note:: The pycsw image uses a specific Python version and does not install pycsw in editable mode. As such it is not possible to use ``tox``. Since the docs directory is bind mounted from your host machine into the container, after building the docs you may inspect their content visually, for example by running:: firefox docs/_build/html/index.html Docker Compose ============== For `Docker Compose`_ deployment, run the following in ``docker/compose``: .. code-block:: bash PYCSW_DOCKER_IMAGE=latest docker compose up .. note:: The ``PYCSW_DOCKER_IMAGE`` setting is required to set the Docker image version/tag. Scaling ------- To scale via Docker Compose, run the following in ``docker/compose``: .. code-block:: bash PYCSW_DOCKER_IMAGE=latest docker compose -f docker-compose.scale.yml up .. note:: In ``docker/compose/docker-compose.scale.yml``, adjust the ``services.pycsw.deploy`` and services.pycsw.ports values to scale accordingly. The port range specified must match the number of replicas defined. Kubernetes ========== For `Kubernetes`_ orchestration, run the following in ``docker/kubernetes``: .. code-block:: bash make up make open Helm ==== For Kubernetes deployment via `Helm`_, run the following in ``docker/helm``: .. code-block:: bash helm install pycsw . minikube service pycsw --url .. _`Docker`: https://www.docker.com .. _`geopython Docker Hub`: https://hub.docker.com/r/geopython/pycsw .. _`GitHub Container Registry`: https://github.com/geopython/pycsw/pkgs/container/pycsw .. _pycsw's GitHub repository: https://github.com/geopython/pycsw/tree/master/docker .. _`Docker Compose`: https://docs.docker.com/compose .. _`Kubernetes`: https://kubernetes.io/ .. _`Helm`: https://helm.sh ================================================ FILE: docs/geonode.rst ================================================ .. _geonode: GeoNode Configuration ====================== GeoNode (https://geonode.org/) is a platform for the management and publication of geospatial data. It brings together mature and stable open-source software projects under a consistent and easy-to-use interface allowing users, with little training, to quickly and easily share data and create interactive maps. GeoNode provides a cost-effective and scalable tool for developing information management systems. GeoNode uses CSW as a cataloguing mechanism to query and present geospatial metadata. pycsw supports binding to an existing GeoNode repository for metadata query. The binding is read-only (transactions are not in scope, as GeoNode manages repository metadata changes in the application proper). GeoNode Setup ------------- pycsw is enabled and configured by default in GeoNode, so there are no additional steps required once GeoNode is setup. See the ``CATALOGUE`` and ``PYCSW`` `settings.py entries`_ at for customizing pycsw within GeoNode. The GeoNode plugin is managed outside of pycsw within the GeoNode project. .. _`settings.py entries`: https://docs.geonode.org/en/master/basic/settings/index.html ================================================ FILE: docs/hhypermap.rst ================================================ .. _hhypermap: HHypermap-Registry Configuration ================================ HHypermap (Harvard Hypermap) Registry (https://github.com/cga-harvard/Hypermap-Registry) is an application that manages OWS, Esri REST, and other types of map service harvesting, and maintains uptime statistics for services and layers. HHypermap Registry will publish to HHypermap Search (based on Lucene) which provides a fast search and visualization environment for spatio-temporal materials. HHypermap uses CSW as a cataloguing mechanism to ingest, query and present geospatial metadata. pycsw supports binding to an existing HHypermap repository for metadata query. HHypermap Setup --------------- pycsw is enabled and configured by default in HHypermap, so there are no additional steps required once HHypermap is setup. See the ``REGISTRY_PYCSW`` `hypermap/settings.py entries`_ for customizing pycsw within HHypermap. The HHypermap plugin is managed outside of pycsw within the HHypermap project. HHypermap settings must ensure that ``REGISTRY_PYCSW['repository']['source']`` is set to ``hypermap.search.pycsw_repository``. .. _`hypermap/settings.py entries`: https://github.com/cga-harvard/Hypermap-Registry/blob/master/hypermap/settings.py ================================================ FILE: docs/html-templating.rst ================================================ .. _html-templating: HTML Templating =============== pycsw uses `Jinja`_ as its templating engine to render HTML and `Flask`_ to provide route paths of the API that returns HTTP responses. For complete details on how to use these modules, refer to the `Jinja documentation`_ and the `Flask documentation`_. The default pycsw configuration has ``server.templates`` commented out and defaults to the pycsw ``pycsw/templates`` and ``pycsw/static`` folder. To point to a different set of template configuration, you can edit your configuration as follows: .. code-block:: yaml server: templates: path: /path/to/jinja2/templates/folder # jinja2 template HTML files static: /path/to/static/folder # css, js, images and other static files referenced by the template **Note:** the URL path to your static folder will always be ``/static`` in your deployed web instance of pycsw. Your templates folder should mimic the same file names and structure of the default pycsw templates. Otherwise, you will need to modify ``api.py`` accordingly. Note that you need only copy and edit the templates you are interested in updating. For example, if you are only interested in updating the ``landing_page.html`` template, then create your own version of only that same file. When pycsw detects that a custom HTML template is being used, it will look for the custom template in ``server.templates.path``. If it does not exist, pycsw will render the default HTML template for the given endpoint/request. Linking to a static file in your HTML templates can be done using Jinja syntax and the exposed ``config['server']['url']``: .. code-block:: html .. _`Jinja`: https://palletsprojects.com/p/jinja/ .. _`Jinja documentation`: https://jinja.palletsprojects.com .. _`Flask`: https://palletsprojects.com/p/flask/ .. _`Flask documentation`: https://flask.palletsprojects.com ================================================ FILE: docs/index.rst ================================================ .. _index: ============================= pycsw |release| Documentation ============================= .. image:: https://zenodo.org/badge/2367090.svg :target: https://zenodo.org/badge/latestdoi/2367090 :Author: Tom Kralidis :Contact: tomkralidis at gmail.com :Release: |release| :Date: |today| .. toctree:: :maxdepth: 2 introduction installation docker configuration administration metadata-model-reference oarec-support csw-support pubsub stac distributedsearching sru opensearch oaipmh json soap sitemaps transactions repofilters profiles repositories outputschemas xslt html-templating geonode hhypermap odc ckan api testing migration-guide tools support contributing license committers ================================================ FILE: docs/installation.rst ================================================ .. _installation: Installation ============ System Requirements ------------------- pycsw is written in `Python `_, and works with (tested) Python 3. pycsw requires the following Python supporting libraries: - `lxml`_ for XML support - `SQLAlchemy`_ for database bindings - `pyproj`_ for coordinate transformations - `PyYAML`_ for configuration management - `Shapely`_ for spatial query / geometry support - `OWSLib`_ for CSW client and metadata parser - `xmltodict`_ for working with XML similar to working with JSON - `geolinks`_ for dealing with geospatial links OGC API - Records ^^^^^^^^^^^^^^^^^ OGC API - Records support additionally requires the following: - `Flask`_ for pycsw's default OGC API - Records endpoint - `pygeofilter`_ for CQL parsing .. note:: You can install these dependencies via `pip`_ .. note:: For :ref:`GeoNode ` or :ref:`Open Data Catalog ` or :ref:`HHypermap ` deployments, SQLAlchemy is not required Installing from Source ---------------------- `Download `_ the latest stable version or fetch from Git. For Developers and the Truly Impatient ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The 4 minute install: .. code-block:: bash virtualenv pycsw && cd pycsw && . bin/activate git clone https://github.com/geopython/pycsw.git && cd pycsw pip3 install -e . && pip3 install -r requirements-standalone.txt cp default-sample.yml default.yml vi default.yml # adjust paths in # server.home # repository.database # set server.url to http://localhost:8000/ # start server - CSW 2/3, OAI-PMH, OpenSearch, SRU (all endpoints at /) python3 pycsw/wsgi.py curl http://localhost:8000/?service=CSW&version=2.0.2&request=GetCapabilities To enable OGC API - Records as well as the abovementioned search standards: .. code-block:: bash # configure which config file to use export PYCSW_CONFIG=default.yml # start server - OGC API - Records and all services (various endpoints below) python3 pycsw/wsgi_flask.py # OGC API - Records curl http://localhost:8000 # OpenAPI document curl http://localhost:8000/openapi # OGC CSW 3 curl http://localhost:8000/csw # OGC CSW 2 curl http://localhost:8000/csw?service=CSW&version=2.0.2&request=GetCapabilities # OAI-PMH curl http://localhost:8000/oaipmh # OpenSearch curl http://localhost:8000/opensearch # SRU curl http://localhost:8000/sru The Quick and Dirty Way ^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: bash git clone https://github.com/geopython/pycsw.git Ensure that CGI is enabled for the install directory. For example, on Apache, if pycsw is installed in ``/srv/www/htdocs/pycsw`` (where the URL will be ``http://host/pycsw/csw.py``), add the following to ``httpd.conf``: .. code-block:: none Options +FollowSymLinks +ExecCGI Allow from all AddHandler cgi-script .py .. note:: If pycsw is installed in ``cgi-bin``, this should work as expected. In this case, the :ref:`tests ` application must be moved to a different location to serve static HTML documents. Make sure, you have all the dependencies from ``requirements.txt and requirements-standalone.txt`` The Clean and Proper Way ^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: bash git clone https://github.com/geopython/pycsw.git cd pycsw python3 setup.py build python3 setup.py install At this point, pycsw is installed as a library and requires a CGI ``csw.py`` or WSGI ``pycsw/wsgi.py`` script to be served into your web server environment (see below for WSGI configuration/deployment). .. _pypi: Installing from the Python Package Index (PyPI) ----------------------------------------------- .. code-block:: bash pip3 install pycsw .. _opensuse: Installing from OpenSUSE Build Service -------------------------------------- In order to install the pycsw package in openSUSE Leap (stable distribution), one can run the following commands as user ``root``: .. code-block:: bash zypper -ar https://download.opensuse.org/repositories/Application:/Geo/openSUSE_Leap_15.2/ GEO zypper refresh zypper install python-pycsw pycsw-cgi In order to install the pycsw package in openSUSE Tumbleweed (rolling distribution), one can run the following commands as user ``root``: .. code-block:: bash zypper -ar https://download.opensuse.org/repositories/Application:/Geo/openSUSE_Tumbleweed/ GEO zypper refresh zypper install python-pycsw pycsw-cgi An alternative method is to use the `One-Click Installer `_. .. _ubuntu: Installing on Ubuntu/Mint ------------------------- In order to install the most recent pycsw release to an Ubuntu-based distribution, one can use the UbuntuGIS Unstable repository by running the following commands: .. code-block:: bash sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable sudo apt-get update sudo apt-get install python-pycsw pycsw-cgi Alternatively, one can use the UbuntuGIS Stable repository which includes older but very well tested versions: sudo add-apt-repository ppa:ubuntugis/ppa sudo apt-get update sudo apt-get install python-pycsw pycsw-cgi .. note:: Since Ubuntu 16.04 LTS Xenial release, pycsw is included by default in the official Multiverse repository. Running on Windows ------------------ For Windows installs, change the first line of ``csw.py`` to: .. code-block:: python #!/Users/USERNAME/AppData/Local/Programs/Python/Python36/python -u .. note:: The use of ``-u`` is required to properly output gzip-compressed responses. .. note:: ``USERNAME`` should match your username, and the Python version should match with your install (e.g. ``Python36``). .. Tip:: `MS4W `__ (MapServer for Windows) as of its version 4.0 release includes pycsw, Apache's mod_wsgi, Python 3.7, and many other tools, all ready to use out of the box. After installing, you will find your local pycsw catalogue endpoint, and steps for further configuration, on your browser's localhost page. You can read more about pycsw inside MS4W `here `__. Security -------- By default, ``default.yml`` is at the root of the pycsw install. If pycsw is setup outside an HTTP server's ``cgi-bin`` area, this file could be read. The following options protect the configuration: - move ``default.yml`` to a non HTTP accessible area, and modify ``csw.py`` to point to the updated location - configure web server to deny access to the configuration. For example, in Apache, add the following to ``httpd.conf``: .. code-block:: none order allow,deny deny from all Running on WSGI --------------- pycsw supports the `Web Server Gateway Interface`_ (WSGI). To run pycsw in WSGI mode, use ``pycsw/wsgi.py`` in your WSGI server environment. .. note:: ``mod_wsgi`` supports only the version of Python it was compiled with. If the target server already supports WSGI applications, pycsw will need to use the same Python version. `WSGIDaemonProcess`_ provides a ``python-path`` directive that may allow a virtualenv created from the Python version ``mod_wsgi`` uses. Below is an example of configuring with Apache: .. code-block:: none WSGIDaemonProcess host1 home=/var/www/pycsw processes=2 WSGIProcessGroup host1 WSGIScriptAlias /pycsw-wsgi /var/www/pycsw/wsgi.py Order deny,allow Allow from all or use the `WSGI reference implementation`_: .. code-block:: bash python3 ./pycsw/wsgi.py Serving on port 8000... which will publish pycsw to ``http://localhost:8000/`` .. _`lxml`: https://lxml.de/ .. _`SQLAlchemy`: https://www.sqlalchemy.org/ .. _`Shapely`: https://toblerity.github.io/shapely/ .. _`pyproj`: https://code.google.com/p/pyproj/ .. _`OWSLib`: https://geopython.github.io/OWSLib .. _`xmltodict`: https://github.com/martinblech/xmltodict .. _`geolinks`: https://github.com/geopython/geolinks .. _`Flask`: https://flask.palletsprojects.com .. _`pygeofilter`: https://github.com/geopython/pygeofilter .. _`PyYAML`: https://pyyaml.org .. _`pip`: https://pip.pypa.io/en/stable .. _`Web Server Gateway Interface`: https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface .. _`WSGIDaemonProcess`: https://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIDaemonProcess .. _`WSGI reference implementation`: https://docs.python.org/library/wsgiref.html ================================================ FILE: docs/introduction.rst ================================================ .. _introduction: Introduction ============ pycsw is an OGC API - Records and OGC CSW server implementation written in Python. Features ======== - implements `OGC API - Records - Part 1: Core`_ - implements `OGC API - Records - Part 2: Facets`_ - implements `OGC API - Records - Part 3: Create, Replace, Update, Delete, Harvest`_ - implements `OGC API - Records - Part 4: Federated Search`_ - implements `OGC API - Features - Part 3: Filtering`_ - implements `STAC API`_ - implements `Common Query Language (CQL2)`_ - certified OGC `Compliant`_ and OGC Reference Implementation for both CSW 2.0.2 and CSW 3.0.0 - harvesting support for WMS, WFS, WCS, WPS, WAF, CSW, SOS - implements `INSPIRE Discovery Services 3.0`_ - implements `ISO Metadata Application Profile 1.0.0`_ - implements `FGDC CSDGM Application Profile for CSW 2.0`_ - implements the Search/Retrieval via URL (`SRU`_) search protocol - implements Full Text Search capabilities - implements OGC OpenSearch Geo and Time Extensions - implements Open Archives Initiative Protocol for Metadata Harvesting - implements Pub/Sub capability via `OGC API Publish-Subscribe Workflow - Part 1: Core`_ - supports ISO, Dublin Core, DIF, FGDC, Atom, GM03 and DataCite metadata models - CGI or WSGI deployment - simple YAML configuration - transactional capabilities (OGC API - Records and CSW-T) - flexible repository configuration - `GeoNode`_ connectivity - `HHypermap`_ connectivity - `Open Data Catalog`_ connectivity - `CKAN`_ connectivity - federated catalogue distributed searching - realtime XML Schema validation - extensible profile plugin architecture Standards Support ----------------- .. csv-table:: :header: Standard,Version(s) `OGC API - Records - Part 1: Core`_,1.0 `OGC API - Features - Part 3: Filtering`_,draft "`OGC API - Features - Part 4: Create, Replace, Update and Delete`_",draft `OGC API Publish-Subscribe Workflow - Part 1: Core`_,draft `OGC CSW`_,2.0.2/3.0.0 `OGC Filter`_,1.1.0/2.0.0 `OGC OWS Common`_,1.0.0/2.0.0 `OGC GML`_,3.1.1 `OGC SFSQL`_,1.2.1 `OGC GeoRSS`_,1.0 `Dublin Core`_,1.1 `SOAP`_,1.2 `ISO 19115`_,2003 `ISO 19139`_,2007 `ISO 19119`_,2005 `NASA DIF`_,9.7 `FGDC CSDGM`_,1998 `GM03`_,2.1 `SRU`_,1.1 `OGC OpenSearch`_,1.0 `OAI-PMH`_,2.0 `DataCite`_,4.3 OGC API - Records support ------------------------- - Part 1: Core OGC API - Features support -------------------------- - Part 3: Filtering - Part 4: Create, Replace, Update and Delete CQL --- - Common Query Language (CQL2) Supported Output Formats ^^^^^^^^^^^^^^^^^^^^^^^^ - JSON (default) - XML Supported Filters ^^^^^^^^^^^^^^^^^ - q - datetime - filter / filter-lang (CQL) - bbox - all properties (``property=value``) Paging ^^^^^^ - limit - offset CSW Support ----------- Supported Operations ^^^^^^^^^^^^^^^^^^^^ .. csv-table:: :header: Request,Optionality,Supported,HTTP method binding(s) GetCapabilities,mandatory,yes,GET (KVP) / POST (XML) / SOAP DescribeRecord,mandatory,yes,GET (KVP) / POST (XML) / SOAP GetRecords,mandatory,yes,GET (KVP) / POST (XML) / SOAP GetRecordById,optional,yes,GET (KVP) / POST (XML) / SOAP GetRepositoryItem,optional,yes,GET (KVP) GetDomain,optional,yes,GET (KVP) / POST (XML) / SOAP Harvest,optional,yes,GET (KVP) / POST (XML) / SOAP UnHarvest,optional,no, Transaction,optional,yes,POST (XML) / SOAP .. note:: Asynchronous processing supported for GetRecords and Harvest requests (via ``csw:ResponseHandler``) .. note:: Supported Harvest Resource Types are listed in :ref:`transactions` Supported Output Formats ^^^^^^^^^^^^^^^^^^^^^^^^ - XML (default) - JSON Supported Output Schemas ^^^^^^^^^^^^^^^^^^^^^^^^ - Dublin Core - ISO 19139 - FGDC CSDGM - NASA DIF - Atom - GM03 - DataCite Supported Sorting Functionality ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ogc:SortBy - ascending or descending - aspatial (queryable properties) - spatial (geometric area) Supported Filters ^^^^^^^^^^^^^^^^^ Full Text Search ^^^^^^^^^^^^^^^^ - csw:AnyText Geometry Operands ^^^^^^^^^^^^^^^^^ - gml:Point - gml:LineString - gml:Polygon - gml:Envelope .. note:: Coordinate transformations are supported Spatial Operators ^^^^^^^^^^^^^^^^^ - BBOX - Beyond - Contains - Crosses - Disjoint - DWithin - Equals - Intersects - Overlaps - Touches - Within Logical Operators ^^^^^^^^^^^^^^^^^ - Between - EqualTo - LessThanEqualTo - GreaterThan - Like - LessThan - GreaterThanEqualTo - NotEqualTo - NullCheck Functions ^^^^^^^^^ - length - lower - ltrim - rtrim - trim - upper OAI-PMH Support --------------- Supported Operations ^^^^^^^^^^^^^^^^^^^^ - GetRecord - Identify - ListIdentifiers - ListMetadataFormats - ListRecords - ListSets Supported Filters ^^^^^^^^^^^^^^^^^ - from - until - set Paging ^^^^^^ - resumptionToken .. _`OGC API - Records - Part 1: Core`: https://docs.ogc.org/is/20-004r1/20-004r1.html .. _`OGC API - Records - Part 2: Facets`: https://docs.ogc.org/DRAFTS/25-013.html .. _`OGC API - Records - Part 3: Create, Replace, Update, Delete, Harvest`: https://docs.ogc.org/DRAFTS/25-015.html .. _`OGC API - Records - Part 4: Federated Search`: https://github.com/opengeospatial/ogcapi-records/blob/master/extensions/federated-search/document.adoc .. _`OGC API - Features - Part 3: Filtering`: http://docs.ogc.org/DRAFTS/19-079.html .. _`Common Query Language (CQL2)`: https://docs.ogc.org/DRAFTS/21-065.html .. _`OGC CSW`: https://www.ogc.org/standards/cat .. _`ISO Metadata Application Profile 1.0.0`: https://portal.ogc.org/files/?artifact_id=21460 .. _`OGC Filter`: https://www.ogc.org/standards/filter .. _`OGC OWS Common`: https://www.ogc.org/standards/common .. _`OGC GML`: https://www.ogc.org/standards/gml .. _`OGC SFSQL`: https://www.ogc.org/standards/sfs .. _`Dublin Core`: https://www.dublincore.org/ .. _`OGC CITE CSW`: https://github.com/opengeospatial/ets-csw202 .. _`OGC GeoRSS`: http://docs.opengeospatial.org/cs/17-002r1/17-002r1.html .. _`SOAP`: https://www.w3.org/TR/soap/ .. _`INSPIRE Discovery Services 3.0`: https://inspire.jrc.ec.europa.eu/documents/Network_Services/TechnicalGuidance_DiscoveryServices_v3.0.pdf .. _`ISO 19115`: https://www.iso.org/iso/catalogue_detail.htm?csnumber=26020 .. _`ISO 19139`: https://www.iso.org/iso/catalogue_detail.htm?csnumber=32557 .. _`ISO 19119`: https://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=39890 .. _`NASA DIF`: https://earthdata.nasa.gov/esdis/eso/standards-and-references/directory-interchange-format-dif-standard .. _`FGDC CSDGM`: https://www.fgdc.gov/metadata/csdgm-standard .. _`FGDC CSDGM Application Profile for CSW 2.0`: https://portal.ogc.org/files/?artifact_id=16936 .. _`SRU`: https://www.loc.gov/standards/sru .. _`OGC OpenSearch`: https://www.ogc.org/standards/opensearchgeo .. _`GeoNode`: https://geonode.org/ .. _`HHypermap`: https://github.com/cga-harvard/HHypermap .. _`Open Data Catalog`: https://github.com/azavea/Open-Data-Catalog/ .. _`CKAN`: https://ckan.org/ .. _`Compliant`: https://www.ogc.org/resource/products/details/?pid=1374 .. _`OAI-PMH`: https://www.openarchives.org/pmh/ .. _`GM03`: https://www.geocat.admin.ch/en/dokumentation/gm03.html .. _`OGC API - Features - Part 4: Create, Replace, Update and Delete`: https://cnn.com .. _`DataCite`: https://schema.datacite.org/meta/kernel-4.3/ .. _`OGC API Publish-Subscribe Workflow - Part 1: Core`: https://docs.ogc.org/DRAFTS/25-030.html .. _`STAC API`: https://github.com/radiantearth/stac-api-spec ================================================ FILE: docs/json.rst ================================================ .. _json: JSON Support ============ OGC API - Records ----------------- pycsw fully supports the OGC API - Records JSON conformance class, which is the default representation provided. CSW --- pycsw supports JSON support for ``DescribeRecord``, ``GetRecords`` and ``GetRecordById`` requests. Adding ``outputFormat=application/json`` to your CSW request will return the response as a JSON representation. ================================================ FILE: docs/license.rst ================================================ .. _license: License ======= .. include:: ../LICENSE.txt Documentation ------------- The documentation is released under the `Creative Commons Attribution 4.0 International (CC BY 4.0)`_ license. .. _`Creative Commons Attribution 4.0 International (CC BY 4.0)`: https://creativecommons.org/licenses/by/4.0 ================================================ FILE: docs/locale/el/LC_MESSAGES/.gitkeep ================================================ ================================================ FILE: docs/locale/fr/LC_MESSAGES/.gitkeep ================================================ ================================================ FILE: docs/locale/zh/LC_MESSAGES/administration.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 09:34+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../administration.rst:4 msgid "Administration" msgstr "管理" #: ../../administration.rst:6 msgid "" "pycsw administration is handled by the ``pycsw-admin.py`` utility. ``pycsw-" "admin.py`` is installed as part of the pycsw install process and should be " "available in your PATH." msgstr "" "pycsw 管理由 ``pycsw-admin.py`` 实用程序处理。 ``pycsw-admin.py`` 是作为 pycsw " "安装过程的一部分安装的,可在PATH 中可用。" #: ../../administration.rst:11 msgid "" "Run ``pycsw-admin.py --help`` to see all administration operations and " "parameters" msgstr "运行 ``pycsw-admin.py -h`` 以查看所有的管理操作与参数" #: ../../administration.rst:14 msgid "Metadata Repository Setup" msgstr "元数据存储库设置" #: ../../administration.rst:16 msgid "pycsw supports the following databases:" msgstr "pycsw支持以下数据库:" #: ../../administration.rst:18 msgid "SQLite3" msgstr "SQLite3" #: ../../administration.rst:19 msgid "PostgreSQL (without PostGIS)" msgstr "PostgreSQL (无 PostGIS)" #: ../../administration.rst:20 msgid "PostgreSQL with PostGIS enabled" msgstr "启用 PostGIS 的 PostgreSQL" #: ../../administration.rst:21 msgid "MySQL" msgstr "MySQL" #: ../../administration.rst:24 msgid "" "The easiest and fastest way to deploy pycsw is to use SQLite3 as the backend." msgstr "部署 pycsw 最简单、最快的方法是使用 SQLite3 作为后端。" #: ../../administration.rst:27 msgid "PostgreSQL support includes support for PostGIS functions if enabled" msgstr "PostgreSQL 支持包括对 PostGIS 功能的支持(如果启用)" #: ../../administration.rst:30 msgid "" "If PostGIS is activated before setting up the pycsw/PostgreSQL database, then " "native PostGIS geometries will be enabled." msgstr "" "如果在设置 pycsw/PostgreSQL 数据库之前激活 PostGIS,则将启用本机 PostGIS " "geometries。" #: ../../administration.rst:32 msgid "" "To expose your geospatial metadata via pycsw, perform the following actions:" msgstr "通过 pycsw 发布地理空间元数据,执行以下操作:" #: ../../administration.rst:34 msgid "setup the database" msgstr "创建数据库" #: ../../administration.rst:35 msgid "import metadata" msgstr "导入元数据" #: ../../administration.rst:36 msgid "publish the repository" msgstr "存储库发布" #: ../../administration.rst:39 msgid "Supported Information Models" msgstr "支持的信息模型" #: ../../administration.rst:41 msgid "" "By default, pycsw's API supports the core OARec and CSW Record information " "models. From the database perspective, the pycsw metadata model is loosely " "based on ISO 19115 and is able to transform to other formats as part of " "transformation during OARec/CSW requests." msgstr "" "默认情况下,pycsw 的 API 支持核心是 OARec 和 CSW Record 信息模型。从数据库的角度" "来看,pycsw 元数据模型松散地基于 ISO 19115,并且能够在 OARec/CSW 请求期间转换为" "其他格式作为转换的一部分。" #: ../../administration.rst:46 msgid "See :ref:`profiles` for information on enabling profiles" msgstr "请参见 :ref:`profiles` 查看有关配置文件的信息" #: ../../administration.rst:49 msgid "Setting up the Database" msgstr "创建数据库" #: ../../administration.rst:55 msgid "This will create the necessary tables and values for the repository." msgstr "这将为存储库创建必要的表与值。" #: ../../administration.rst:57 msgid "" "The database created is an `OGC SFSQL`_ compliant database, and can be used " "with any implementing software. For example, to use with `GDAL`_:" msgstr "" "创建的数据库是兼容 `OGC SFSQL`_ 的,此数据库可应用于任何实现(相关标准的)软件。" "例如, `OGR`_ :创建的数据库是符合“OGC SFSQL”的数据库,可与任何实施软件一起使用。" "例如,与 `GDAL`_ 一起使用:" #: ../../administration.rst:69 msgid "" "If PostGIS is detected, the ``pycsw-admin.py`` script does not create the SFSQL " "tables as they are already in the database." msgstr "" "如检测到PostGIS, pycsw-admin.py 脚本就不会再创建 SFSQL 表,因为数据库中已经存在" "了。" #: ../../administration.rst:73 msgid "Loading Records" msgstr "加载记录" #: ../../administration.rst:79 msgid "" "This will import all ``*.xml`` records from ``/path/to/records`` into the " "database specified in ``default.yml`` (``repository.database``). Passing ``-" "r`` to the script will process ``/path/to/records`` recursively. Passing ``-" "y`` to the script will force overwrite existing metadata with the same " "identifier. Note that ``-p`` accepts either a directory path or single file." msgstr "" "这时所有的 ``*.xml`` 记录就会从 ``/path/to/records`` 导入到 ``default.yml`` 中指" "定的数据库 (``repository.database``)。将 ``-r`` 传递到脚本中, 程序 ``/path/to/" "records`` 就会递归运行。将 ``-y`` 传递到脚本中, 程序 ``/path/to/records`` 将强" "制替换现有的相同元数据标识符。请注意, ``-p`` 只能接受一个目录路径或单个文件。" #: ../../administration.rst:82 msgid "Records can also be imported using CSW-T (see :ref:`transactions`)." msgstr "记录也可以使用 CSW-T导入 (请查看 :ref:`transactions` )。" #: ../../administration.rst:85 msgid "Exporting the Repository" msgstr "导出数据库" #: ../../administration.rst:91 msgid "" "This will write each record in the database specified in ``default.yml`` " "(``repository.database``) to an XML document on disk, in directory ``/path/to/" "output_dir``." msgstr "" "这会将 ``default.yml`` (``repository.database``) 中指定的数据库的每条记录写入磁" "盘上的 ``/path/to/output_dir`` 目录中的 XML 文档。" #: ../../administration.rst:94 msgid "Optimizing the Database" msgstr "优化数据库" #: ../../administration.rst:102 msgid "This feature is relevant only for PostgreSQL and MySQL" msgstr "此特性只适用于 PostgreSQL和MySQL" #: ../../administration.rst:105 msgid "Deleting Records from the Repository" msgstr "从存储库中删除记录" #: ../../administration.rst:111 msgid "This will empty the repository of all records." msgstr "数据库中的所有记录都会被清空。" #: ../../administration.rst:114 msgid "Database Specific Notes" msgstr "数据库特别需要注意的是" #: ../../administration.rst:117 msgid "PostgreSQL" msgstr "PostgreSQL" #: ../../administration.rst:119 msgid "" "To enable the database user must be able to create functions within the database." msgstr "" "在PostgreSQL支持下,用户必须在数据" #: ../../administration.rst:120 msgid "" "`PostgreSQL Full Text Search`_ is supported for ``csw:AnyText`` based queries. " "pycsw creates a tsvector column based on the text from anytext column. Then " "pycsw creates a GIN index against the anytext_tsvector column. This is created " "automatically in ``pycsw.core.repository.setup``. Any query against OARec's ``q`` " "parameter or CSW `csw:AnyText` or `apiso:AnyText` will process using PostgreSQL " "FTS handling" msgstr "" "`PostgreSQL Full Text Search`_ (全文搜索)支持基于 ``csw:AnyText`` (任意文本)的" "查询。pycsw创建的tsvector栏是基于文本anytext栏。然而pycsw针对" "anytext_tsvector(任意文本)栏创建了GIN索引。这在 ``pycsw.core.repository.setup`` 是自" "动生成的。任何针对 `csw:AnyText` or `apiso:AnyText` 的查询都是使用PostgreSQL FT" "进行处理" #: ../../administration.rst:123 msgid "PostGIS" msgstr "PostGIS" #: ../../administration.rst:125 msgid "" "pycsw makes use of PostGIS spatial functions and native geometry data type." msgstr "pycsw使用的是PostGIS空间功能和本地 geometry数据类型." #: ../../administration.rst:126 msgid "" "It is advised to install the PostGIS extension before setting up the pycsw " "database" msgstr "建议在创建pycsw数据库前先安装PostGIS扩展信息" #: ../../administration.rst:127 msgid "" "If PostGIS is detected, the ``pycsw-admin.py`` script will create both a native " "geometry column and a WKT column, as well as a trigger to keep both synchronized" msgstr "" "如果PostGIS被监测到,脚本pycsw-admin.py既会在本地 geometry栏创建,也会在WKT栏创" "建,以及触发器,来保持两者的同步。" #: ../../administration.rst:128 msgid "" "In case PostGIS gets disabled, pycsw will continue to work with the `WKT`_ " "column" msgstr "一旦PostGIS被禁用,pycsw将继续与 `WKT`_ 栏一起运行" #: ../../administration.rst:129 msgid "" "In case of migration from plain PostgreSQL database to PostGIS, the spatial " "functions of PostGIS will be used automatically" msgstr "如果plain PostgreSQL数据库移入PostGIS中,PostGIS的空间功能将自行启动" #: ../../administration.rst:130 msgid "" "When migrating from plain PostgreSQL database to PostGIS, in order to enable " "native geometry support, a \"GEOMETRY\" column named \"wkb_geometry\" needs to " "be created manually (along with the update trigger in ``pycsw.core.repository." "setup``). Also the native geometries must be filled manually from the `WKT`_ " "field. Next versions of pycsw will automate this process" msgstr "" "当从普通的数据库plain PostgreSQL移入PostGIS时, 为了启用本地geometry支持,需要手" "动创建一个名为 \"wkb_geometry\" 的 \"GEOMETRY\" 列(随着 ``pycsw.core.repository." "setup`` 一起更新)。本地geometries也必须在 `WKT`_ 中手动填充。pycsw的下一个版" "本就会将此过程自动化运行" #: ../../administration.rst:135 msgid "Mapping to an Existing Repository" msgstr "映射到现有的存储库" #: ../../administration.rst:137 msgid "" "pycsw supports publishing metadata from an existing repository. To enable this " "functionality, the default database mappings must be modified to represent the " "existing database columns mapping to the abstract core model (the default " "mappings are in ``pycsw/config.py:MD_CORE_MODEL``)." msgstr "" "pycsw支持在现在的存储库中发布元数据。为了启用此功能,必须修改默认数据库映射以表" "示映射到抽象核心模型的现有数据库列(默认的眏射方式在 ``pycsw/config.py:" "MD_CORE_MODEL`` 中)" #: ../../administration.rst:139 msgid "To override the default settings:" msgstr "覆盖默认的配置:" #: ../../administration.rst:141 msgid "define a custom database mapping based on ``etc/mappings.py``" msgstr "定于基于 ``etc/mappings.py`` 数据库映射" #: ../../administration.rst:142 msgid "" "in ``default.yml``, set ``repository.mappings`` to the location of the mappings." "py file:" msgstr "" "在 ``default.yml`` 中,设置 ``repository.mappings`` 为 mappings.py 文件的位置:" #: ../../administration.rst:150 msgid "Note you can also reference mappings as a Python object as a dotted path:" msgstr "注意,还可以将映射作为Python对象引用为虚线路径:" #: ../../administration.rst:159 msgid "" "See the :ref:`geonode`, :ref:`hhypermap`, and :ref:`odc` for further examples." msgstr "请参照 :ref:`geonode` , :ref:`hhypermap` 和 :ref:`odc` 查看更多示例。" #: ../../administration.rst:162 msgid "Existing Repository Requirements" msgstr "现有的存储需求" #: ../../administration.rst:164 msgid "" "pycsw requires certain repository attributes and semantics to exist in any " "repository to operate as follows:" msgstr "pycsw需要在任何存储库中存在某些存储库属性和语义,以便按照以下方式操作:" #: ../../administration.rst:166 msgid "``pycsw:Identifier``: unique identifier" msgstr "``pycsw:Identifier``:唯一的标识符" #: ../../administration.rst:167 msgid "" "``pycsw:Typename``: typename for the metadata; typically the value of the root " "element tag (e.g. ``csw:Record``, ``gmd:MD_Metadata``)" msgstr "" "``pycsw:Typename``: 元数据的类型名;典型的根标签值(例如 ``csw:Record`` , ``gmd:" "MD_Metadata`` )" #: ../../administration.rst:168 msgid "" "``pycsw:Schema``: schema for the metadata; typically the target namespace (e.g. " "``http://www.opengis.net/cat/csw/2.0.2``, ``http://www.isotc211.org/2005/gmd``)" msgstr "" "``pycsw:Schema``: 元数据图表;典型的目标名称空间(例如 ``http://www.opengis.net/" "cat/csw/2.0.2`` , ``http://www.isotc211.org/2005/gmd`` )" #: ../../administration.rst:169 msgid "``pycsw:InsertDate``: date of insertion" msgstr "``pycsw:InsertDate`` : 插入日期" #: ../../administration.rst:170 msgid "``pycsw:XML``: full XML representation" msgstr "``pycsw:XML`` :完整的XML表现形式" #: ../../administration.rst:171 msgid "" "``pycsw:AnyText``: bag of XML element text values, used for full text search. " "Realized with the following design pattern:" msgstr "" "``pycsw:AnyText`` : XML元素文件值包,用于完整的文本搜索。采用以下设计模式实现:" #: ../../administration.rst:173 msgid "capture all XML element and attribute values" msgstr "获取所有的XML元素与属性值" #: ../../administration.rst:174 msgid "store in repository" msgstr "存储数据库" #: ../../administration.rst:175 msgid "``pycsw:BoundingBox``: string of `WKT`_ or `EWKT`_ geometry" msgstr "``pycsw:BoundingBox`` : `WKT`_ or `EWKT`_ geometry字符串" #: ../../administration.rst:177 msgid "The following repository semantics exist if the attributes are specified:" msgstr "如果指定了属性,则存在以下存储库语义:" #: ../../administration.rst:179 msgid "``pycsw:Keywords``: comma delimited list of keywords" msgstr "``pycsw:Keywords`` : 以逗号分隔的关键字列表" #: ../../administration.rst:180 msgid "" "``pycsw:Links``: Text field of JSON list of objects with properties ``name``, " "``description``, ``protocol``, ``url``" msgstr "" "``pycsw:Links``:具有属性 ``name``,``description``,``protocol``,``url`` 的对" "象的JSON列表的文本字段" #: ../../administration.rst:194 msgid "The ``pycsw:Links`` field should be a text type, not a JSON object type" msgstr "``pycsw:Links`` 字段应该是文本类型,而不是 JSON 对象类型" #: ../../administration.rst:196 msgid "" "``pycsw:Bands``: Text field of JSON list of dicts with properties: ``name``, " "``units``, ``min``, ``max``" msgstr "" "``pycsw:Bands``:具有属性的 JSON 列表的文本字段:``name``,``units``,``min``," "``max``" #: ../../administration.rst:210 msgid "The ``pycsw:Bands`` field should be a text type, not a JSON object type" msgstr "``pycsw:Bands`` 字段应该是文本类型,而不是 JSON 对象类型" #: ../../administration.rst:212 msgid "Values of mappings can be derived from the following mechanisms:" msgstr "映射值由以下的结构获得:" #: ../../administration.rst:214 msgid "text fields" msgstr "文本域" #: ../../administration.rst:215 msgid "Python datetime.datetime or datetime.date objects" msgstr "Python ``datetime.datetime`` 或 ``datetime.date`` 对象" #: ../../administration.rst:216 msgid "Python functions" msgstr "Python 功能" #: ../../administration.rst:218 msgid "Further information is provided in ``pycsw/config.py:MD_CORE_MODEL``." msgstr "在 ``pycsw/config.py:MD_CORE_MODEL`` 中可获得更多资料。" #~ msgid "By default, pycsw supports the ``csw:Record`` information model." #~ msgstr "默认情况下,pycsw支持 ``csw:Record`` 信息模型。" #~ msgid "" #~ "``pycsw:Links``: structure of links in the format \"name,description," #~ "protocol,url[^,,,[^,,,]]\"" #~ msgstr "" #~ "``pycsw:Links`` : 链接的格式结构 \"name,description,protocol,url[^,,," #~ "[^,,,]]\" " ================================================ FILE: docs/locale/zh/LC_MESSAGES/api.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010-2015, Tom Kralidis This work is licensed under a # Creative Commons Attribution 4.0 International License # This file is distributed under the same license as the pycsw package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: pycsw 2.1-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 09:44+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../api.rst:4 msgid "API" msgstr "API" #: ../../api.rst:6 msgid "" "Python applications can integrate pycsw into their custom workflows. " "This allows for seamless integate within frameworks such as Flask and " "Django." msgstr "" "Python应用可以在自己的工作流中集成 pycsw 。这样就允许在 Flask与 Django 这" "样的框架中无缝集成。" #: ../../api.rst:9 msgid "" "Below are examples of where using the API (as opposed to the default " "WSGI/CGI services could be used:" msgstr "下面是一些使用API的示例(相对于默认的WSGI/CGI服务,可以使用:" #: ../../api.rst:12 msgid "configuration based on a Python dict, or stored in a database" msgstr "基于Python字典 进行配置,或存储在数据库中" #: ../../api.rst:13 msgid "downstream request environment / framework (Flask, Django)" msgstr "下游请求环境/框架(Flask,Django)" #: ../../api.rst:14 msgid "authentication or authorization logic" msgstr "认证或授权逻辑" #: ../../api.rst:15 msgid "forcing CSW version 2.0.2 as default" msgstr "强制使用 CSW 版本2.0.2作为默认值" #: ../../api.rst:18 msgid "OARec Flask Example" msgstr "OARec Flask 示例" #: ../../api.rst:20 msgid "" "See https://github.com/geopython/pycsw/blob/master/pycsw/wsgi_flask.py " "for how to implement a Flask wrapper atop all pycsw supported APIs. " "Note the use of Flask blueprints to enable integration with downstream " "Flask applications." msgstr "" "请参阅 https://github.com/geopython/pycsw/blob/master/pycsw/wsgi_flask." "py 了解如何在所有 pycsw 支持的 API 上实现 Flask 包装器。请注意使用 Flask " "蓝图来实现与下游 Flask 应用程序的集成。" #: ../../api.rst:25 msgid "Simple Flask blueprint example" msgstr "简单的 Flask 蓝图示例" #: ../../api.rst:43 msgid "" "In the above example, all pycsw endpoints are made available under " "``http://localhost:8000/oapi``." msgstr "" "在上面的示例中,所有 pycsw 端点都在 http://localhost:8000/oapi 下可用。" #: ../../api.rst:46 msgid "Simple CSW Flask Example" msgstr "简单的 CSW Flask 示例" ================================================ FILE: docs/locale/zh/LC_MESSAGES/ckan.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 09:48+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../ckan.rst:4 msgid "CKAN Configuration" msgstr "CKAN配置" #: ../../ckan.rst:6 msgid "" "CKAN (https://ckan.org) is a powerful data management system that makes " "data accessible – by providing tools to streamline publishing, sharing, " "finding and using data. CKAN is aimed at data publishers (national and " "regional governments, companies and organizations) wanting to make their " "data open and available." msgstr "" "CKAN (http://ckan.org)是一个功能强大的数据管理系统,该系统提高了数据可访" "问性,通过提供工具来简化发布、共享、发现和使用数据。CKAN的目的在于使他们" "变成数据开放并可用的数据发布者(国家和地方政府、公司和组织)。" #: ../../ckan.rst:8 msgid "" "`ckanext-spatial`_ is CKAN's geospatial extension. 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." msgstr "" "`ckanext 空间`_ 是 CKAN 的地理空间扩展。此功能扩展将空间的字段添加到默认" "的 CKAN 数据集架构中,使用 PostGIS 作为后端。这允许执行空间查询并在前端显" "示数据集范围。它还提供了将地理空间元数据从其他来源导入 CKAN 的采集器,以" "及支持 CSW 标准的命令。最后,它还包括用于预览空间格式的插件,例如 " "GeoJSON。" #: ../../ckan.rst:11 msgid "CKAN Setup" msgstr "CKAN设置" #: ../../ckan.rst:13 msgid "" "Installation and configuration Instructions are provided as part of the " "ckanext-spatial `documentation`_." msgstr "安装和配置说明作为 ckanext-spatial `documentation`_ 的一部分提供。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/committers.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-05-28 11:27+0800\n" "PO-Revision-Date: 2022-03-09 09:50+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.3.4\n" "X-Generator: Poedit 3.0.1\n" #: ../../committers.rst:4 msgid "Committers" msgstr "提交者,执行者,管理员" #: ../../../COMMITTERS.txt:2 msgid "Login(s)" msgstr "登录" #: ../../../COMMITTERS.txt:2 msgid "Name" msgstr "名字" #: ../../../COMMITTERS.txt:2 msgid "Email / Contact" msgstr "联系方式/邮件" #: ../../../COMMITTERS.txt:2 msgid "Area(s)" msgstr "区域" #: ../../../COMMITTERS.txt:4 msgid "tomkralidis" msgstr "tomkralidis" #: ../../../COMMITTERS.txt:4 msgid "Tom Kralidis" msgstr "Tom Kralidis" #: ../../../COMMITTERS.txt:4 msgid "tomkralidis at gmail.com" msgstr "tomkralidis at gmail.com" #: ../../../COMMITTERS.txt:4 ../../../COMMITTERS.txt:7 msgid "Overall" msgstr "总计" #: ../../../COMMITTERS.txt:5 msgid "kalxas" msgstr "kalxas" #: ../../../COMMITTERS.txt:5 msgid "Angelos Tzotsos" msgstr "Angelos Tzotsos" #: ../../../COMMITTERS.txt:5 msgid "tzotsos at gmail.com" msgstr "tzotsos at gmail.com" #: ../../../COMMITTERS.txt:5 msgid "INSPIRE, APISO profiles, Packaging" msgstr "INSPIRE, APISO profiles, Packaging" #: ../../../COMMITTERS.txt:6 msgid "adamhinz" msgstr "adamhinz" #: ../../../COMMITTERS.txt:6 msgid "Adam Hinz" msgstr "Adam Hinz" #: ../../../COMMITTERS.txt:6 msgid "hinz dot adam at gmail.com" msgstr "hinz dot adam at gmail.com" #: ../../../COMMITTERS.txt:6 msgid "WSGI/Server Deployment" msgstr "WSGI/服务器部署" #: ../../../COMMITTERS.txt:7 msgid "ricardogsilva" msgstr "ricardogsilva" #: ../../../COMMITTERS.txt:7 msgid "Ricardo Garcia Silva" msgstr "Ricardo Garcia Silva" #: ../../../COMMITTERS.txt:7 msgid "ricardo.garcia.silva at gmail.com" msgstr "ricardo.garcia.silva at gmail.com" ================================================ FILE: docs/locale/zh/LC_MESSAGES/configuration.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 10:27+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../configuration.rst:4 msgid "Configuration" msgstr "配置" #: ../../configuration.rst:6 msgid "" "pycsw's runtime configuration is defined by ``default.yml``. pycsw ships with " "a `sample configuration`_ (``default-sample.yml``). Copy the file to ``default." .yml`` and edit the following:" msgstr "" "pycsw 的运行配置写为此格式 ``default.yml`` 。 pycsw 还有一个示例配置 " "( ``default-sample.yml`` )。 将文件复制到 ``default.yml`` 并编辑以下内容:" #: ../../configuration.rst:8 msgid "**[server]**" msgstr "**[server]**" #: ../../configuration.rst:10 msgid "**home**: the full filesystem path to pycsw" msgstr "**home**: pycsw 的完整文件系统路径" #: ../../configuration.rst:11 msgid "**url**: the URL of the resulting service" msgstr "**url**: 生成服务器的网址" #: ../../configuration.rst:12 msgid "**mimetype**: the MIME type when returning HTTP responses" msgstr "**mimetype**: 当HTTP响应时的MIME型" #: ../../configuration.rst:13 msgid "" "**language**: the ISO 639-1 language and ISO 3166-1 alpha2 country code of the " "service (e.g. ``en-CA``, ``fr-CA``, ``en-US``)" msgstr "" "**language**: ISO 639-1 语言和 ISO 3166-1 α2服务器上的国家/地区代码 (例如 ``en-" "CA`` 、``fr-CA``、 ``EN-US`` )" #: ../../configuration.rst:14 msgid "" "**encoding**: the content type encoding (e.g. ``ISO-8859-1``, see https://docs." "python.org/2/library/codecs.html#standard-encodings). Default value is 'UTF-8'" msgstr "" "**encoding**: 编码的内容类别 (例如 ``ISO-8859-1``,见 https://docs.python.org/2/" "library/codecs.html#standard-encodings ) 。 默认值是 'UTF-8'" #: ../../configuration.rst:15 msgid "" "**maxrecords**: the maximum number of records to return by default. This value " "is enforced if a CSW's client's ``maxRecords`` parameter is greater than " "``server.maxrecords`` to limit capacity. See :ref:`maxrecords-handling` for " "more information" msgstr "" "**maxrecords**: 默认情况下再次浏览记录的最大数目。如果CSW客户端的 " "``maxRecords`` 参数大于 ``server.maxrecords`` ,此值就会被强制性限制。 请参见 :" "ref:`maxrecords-handling` 的详细信息" #: ../../configuration.rst:16 msgid "" "**loglevel**: the logging level (see https://docs.python.org/library/logging." "html#logging-levels)" msgstr "" "**loglevel**:日志级别(参见 https://docs.python.org/library/logging." "html#logging-levels)" #: ../../configuration.rst:17 msgid "**logfile**: the full file path to the logfile" msgstr "**logfile**:日志文件的完整文件系统路径" #: ../../configuration.rst:18 msgid "" "**ogc_schemas_base**: base URL of OGC XML schemas tree file structure (default " "is http://schemas.opengis.net)" msgstr "" "**ogc_schemas_base**: OGC XML 模型文件结构树的网址库 (默认 http://schemas." "opengis.net)" #: ../../configuration.rst:19 msgid "" "**federatedcatalogues**: comma delimited list of CSW endpoints to be used for " "distributed searching, if requested by the client (see :ref:" "`distributedsearching`)" msgstr "" "**federatedcatalogues**: 如果客户端有用户请求加入时, CSW端以逗号分隔的列表就会" "用于分布式搜索 (请参阅 :ref:`distributedsearching` )" #: ../../configuration.rst:20 msgid "" "**pretty_print**: whether to pretty print the output (``true`` or ``false``). " "Default is ``false``" msgstr "" "**pretty_print**: 输出的( ``true`` or ``false`` )来确认是否要优质打印。 默认值" "为 ``false``" #: ../../configuration.rst:21 msgid "" "**gzip_compresslevel**: gzip compression level, lowest is ``1``, highest is " "``9``. Default is off. **NOTE**: if gzip compression is already enabled via " "your web server, do not enable this directive (or else the server will try to " "compress the response twice, resulting in degraded performance)" msgstr "" "**gzip_compresslevel**:gzip 压缩级别,最低为 ``1``,最高为 ``9``。默认为关闭。 " "**注意**:如果 gzip 压缩已通过您的 Web 服务器启用,请不要启用此指令(否则服务器" "将尝试压缩响应两次,从而导致性能下降)" #: ../../configuration.rst:22 msgid "" "**domainquerytype**: for GetDomain operations, how to output domain values. " "Accepted values are ``list`` and ``range`` (min/max). Default is ``list``" msgstr "" "**domainquerytype**: 在GetDomain中应当如何输出域值。 公认的域值有 ``list`` 和 " "``range`` (最小/最大)。默认值是 ``list`` " #: ../../configuration.rst:23 msgid "" "**domaincounts**: for GetDomain operations, whether to provide frequency counts " "for values. Accepted values are ``true`` and ``False``. Default is ``false``" msgstr "" "**domaincounts**:在GetDomain中,是否要提供频率计数值的操作。目前的值有 " "``true`` 和 ``false`` 。默认值为 ``false``" #: ../../configuration.rst:24 msgid "" "**profiles**: comma delimited list of profiles to load at runtime (default is " "none). See :ref:`profiles`" msgstr "" "**profiles**: 是否在运行时加载以逗号分隔的配置文件列表(默认为无)。 请参见 :" "ref:`profiles`" #: ../../configuration.rst:25 msgid "" "**smtp_host**: SMTP host for processing ``csw:ResponseHandler`` parameter via " "outgoing email requests (default is ``localhost``)" msgstr "" "**smtp_host**: SMTP 主机(默认为' 本地主机 ')通过发送电子邮件请求的方式处理 " "``csw:ResponseHandler`` 参数" #: ../../configuration.rst:26 msgid "" "**spatial_ranking**: parameter that enables (``true`` or ``false``) ranking of " "spatial query results as per `K.J. Lanfear 2006 - A Spatial Overlay Ranking " "Method for a Geospatial Search of Text Objects `_." msgstr "" "**spatial_ranking**: 是否在对空间搜索的结果进行排名的一项参数( ``true`` 或 " "``false`` ),此排名参数在每 `K.J. Lanfear 2006 文本对象空间搜索的一个空间覆盖排" "名方法 `_ 。" #: ../../configuration.rst:27 msgid "" "**workers**: set the number of workers used by the wsgi server when lunching " "pycsw using the provided docker/entrypoint.py. If not set, it will use 2 " "workers as Default." msgstr "" "**workers**:使用提供的 docker/entrypoint.py 设置午餐 pycsw 时 wsgi 服务器使用的" "工人数量。如果未设置,它将使用 2 个工人作为默认值。" #: ../../configuration.rst:29 msgid "**[manager]**" msgstr "**[manager]**" #: ../../configuration.rst:31 msgid "" "**transactions**: whether to enable transactions (``true`` or ``false``). " "Default is ``false`` (see :ref:`transactions`)" msgstr "" "**transactions**: 是否可以交易 ( ``true`` 或 ``false`` )。 默认值为否 (请参" "阅 :ref:`transactions` )" #: ../../configuration.rst:32 msgid "" "**allowed_ips**: comma delimited list of IP addresses (e.g. 192.168.0.103), " "wildcards (e.g. 192.168.0.*) or CIDR notations (e.g. 192.168.100.0/24) allowed " "to perform transactions (see :ref:`transactions`)" msgstr "" "**allowed_ips**: IP 地址 (如 192.168.0.103)、 通配符 (如 192.168.0.*) 或 CIDR 表" "示法 (例如 192.168.100.0/24) 以逗号分隔的列表允许执行交易 (请参见 :ref:" "`transactions` )" #: ../../configuration.rst:33 msgid "" "**csw_harvest_pagesize**: when harvesting other CSW servers, the number of " "records per request to page by (default is 10)" msgstr "" "**csw_harvest_pagesize**: 当收集其它CSW服务器时,每项请求的记录数都会显示在各页" "中 (每页默认的数量为 10)" #: ../../configuration.rst:35 msgid "**[metadata:main]**" msgstr "**[metadata:main]**" #: ../../configuration.rst:37 msgid "**identification_title**: the title of the service" msgstr "**identification_title**: 服务项目标题" #: ../../configuration.rst:38 msgid "**identification_abstract**: some descriptive text about the service" msgstr "**identification_abstract**: 一些有关该服务的描述性文本" #: ../../configuration.rst:39 msgid "" "**identification_keywords**: comma delimited list of keywords about the service" msgstr "**identification_keywords**: 以逗号分隔的服务器有关的关键字列表" #: ../../configuration.rst:40 msgid "" "**identification_keywords_type**: keyword type as per the `ISO 19115 " "MD_KeywordTypeCode codelist `_). Accepted values are ``discipline``, " "``temporal``, ``place``, ``theme``, ``stratum``" msgstr "" "**identification_keywords_type**: 每 `ISO 19115 MD_KeywordTypeCode codelist " "`_ )的关键字类型。接受的值是 ``纪律``, ``时间``, ``地点" "``, ``主题``, ``地层``" #: ../../configuration.rst:41 msgid "**identification_fees**: fees associated with the service" msgstr "**identification_fees**: 与服务有关的费用" #: ../../configuration.rst:42 msgid "" "**identification_accessconstraints**: access constraints associated with the " "service" msgstr "**identification_accessconstraints**: 访问与该服务相关的限制条目" #: ../../configuration.rst:43 msgid "**provider_name**: the name of the service provider" msgstr "**provider_name**: 服务提供者的名字" #: ../../configuration.rst:44 msgid "**provider_url**: the URL of the service provider" msgstr "**provider_url**: 服务提供者的网址" #: ../../configuration.rst:45 msgid "**contact_name**: the name of the provider contact" msgstr "**provider_name**: 服务提供者联系人" #: ../../configuration.rst:46 msgid "**contact_position**: the position title of the provider contact" msgstr "**contact_position**:提供者联系人的职位名称" #: ../../configuration.rst:47 msgid "**contact_address**: the address of the provider contact" msgstr "**contact_address**: 提供者联系人的地址" #: ../../configuration.rst:48 msgid "**contact_city**: the city of the provider contact" msgstr "**contact_city**:提供者联系人所在城市" #: ../../configuration.rst:49 msgid "" "**contact_stateorprovince**: the province or territory of the provider contact" msgstr "**contact_stateorprovince**: 提供者联系人所在省份或更详细地址" #: ../../configuration.rst:50 msgid "**contact_postalcode**: the postal code of the provider contact" msgstr "**contact_postalcode**: 提供者联系人所在地区的邮政编码" #: ../../configuration.rst:51 msgid "**contact_country**: the country of the provider contact" msgstr "**contact_country**: 提供者联系人所在国籍" #: ../../configuration.rst:52 msgid "**contact_phone**: the phone number of the provider contact" msgstr "**contact_phone**: 提供者联系人的电话号码" #: ../../configuration.rst:53 msgid "**contact_fax**: the facsimile number of the provider contact" msgstr "**contact_fax**: 提供者联系人的传真号码" #: ../../configuration.rst:54 msgid "**contact_email**: the email address of the provider contact" msgstr "**contact_email**: 提供者联系人的电子邮件地址" #: ../../configuration.rst:55 msgid "**contact_url**: the URL to more information about the provider contact" msgstr "**contact_url**: 提供者联系人的详细URL" #: ../../configuration.rst:56 msgid "**contact_hours**: the hours of service to contact the provider" msgstr "**contact_hours**: 提供者联系人的服务时间" #: ../../configuration.rst:57 msgid "**contact_instructions**: the how to contact the provider contact" msgstr "**contact_instructions**: 如何与提供者取得联系" #: ../../configuration.rst:58 msgid "" "**contact_role**: the role of the provider contact as per the `ISO 19115 " "CI_RoleCode codelist `_). Accepted values are ``author``, " "``processor``, ``publisher``, ``custodian``, ``pointOfContact``, " "``distributor``, ``user``, ``resourceProvider``, ``originator``, ``owner``, " "``principalInvestigator``" msgstr "" "**contact_role**: 在 `ISO 19115 CI_RoleCode codelist `_ )有每位提供者联系人" "的职务。可接受的值包括 ``作者``、``处理器``、``发布者``、``保管人``、" "``pointOfContact``、``分发者``、``用户``、``资源提供者``,``发起人``,``所有者" "``,``主要调查员``" #: ../../configuration.rst:60 msgid "**[repository]**" msgstr "**[repository]**" #: ../../configuration.rst:62 msgid "" "**database**: the full file path to the metadata database, in database URL " "format (see https://docs.sqlalchemy.org/en/latest/core/engines.html#database-" "urls)" msgstr "" "**database**:元数据库中完整的文件路径,采用数据库URL格式(见 http://docs." "sqlalchemy.org/en/latest/core/engines.html#database-urls )" #: ../../configuration.rst:63 msgid "" "**table**: the table name for metadata records (default is ``records``). If " "you are using PostgreSQL with a DB schema other than ``public``, qualify the " "table like ``myschema.table``" msgstr "" "**table**:元数据记录的表名(默认为 ``records``)。如果在使用除了 ``public`` 以" "外的DB模式PostgreSQL,表格就会被限定,如 ``myschema.table``" #: ../../configuration.rst:64 msgid "**mappings**: custom repository mappings (see :ref:`custom_repository`)" msgstr "**mappings**:自定义的映射库(请参见 :ref:`custom_repository` )" #: ../../configuration.rst:65 msgid "" "**source**: the source of this repository only if not local (e.g. :ref:" "`geonode`, :ref:`odc`). Supported values are ``geonode``, ``odc``" msgstr "" "**source**:不在本地的数据库源(例如:请参考 :ref:`geonode` , :ref:`odc` )。现" "有值为`geonode`,`odc`" #: ../../configuration.rst:66 msgid "" "**filter**: server side database filter to apply as mask to all CSW requests " "(see :ref:`repofilters`)" msgstr "" "**filter**:服务器端的数据库过滤器,适用所有CSW请求掩码(请参阅: :ref:" "`repofilters`)" #: ../../configuration.rst:67 msgid "" "**max_retries**: max number of retry attempts when connecting to records-" "repository database" msgstr "**max_retries**:连接到记录存储库数据库时的最大重试次数" #: ../../configuration.rst:71 msgid "" "See :ref:`administration` for connecting your metadata repository and supported " "information models." msgstr "请参阅: :ref:`administration` ,用于连接元数据信息库和支持信息模型。" #: ../../configuration.rst:76 msgid "MaxRecords Handling" msgstr "MaxRecords 处理" #: ../../configuration.rst:78 msgid "" "The The following describes how ``maxRecords`` is handled by the configuration " "when handling OARec items or CSW ``GetRecords`` requests:" msgstr "" "以下描述了在处理 OARec 项目或 CSW 的 ``GetRecords`` 请求时配置如何处理 " "``maxRecords`` :" #: ../../configuration.rst:1 msgid "server.maxrecords" msgstr "server.maxrecords" #: ../../configuration.rst:1 msgid "OARec limit/CSW GetRecords.maxRecords" msgstr "OARec 限制/CSW GetRecords.maxRecords" #: ../../configuration.rst:1 msgid "Result" msgstr "结果" #: ../../configuration.rst:1 msgid "none set" msgstr "未设定" #: ../../configuration.rst:1 msgid "none passed" msgstr "未通过" #: ../../configuration.rst:1 msgid "10 (CSW default)" msgstr "10 (CSW 默认值)" #: ../../configuration.rst:1 msgid "20" msgstr "20" #: ../../configuration.rst:1 msgid "14" msgstr "14" #: ../../configuration.rst:1 msgid "100" msgstr "100" #: ../../configuration.rst:1 msgid "200" msgstr "200" #: ../../configuration.rst:92 msgid "Using environment variables in configuration files" msgstr "在配置文件中使用环境变量" #: ../../configuration.rst:94 msgid "" "pycsw configuration supports using system environment variables, which can be " "helpful for deploying into `12 factor `_ environments " "for example." msgstr "" "pycsw 配置支持使用系统环境变量,例如有助于部署到 `12 factor `_ 环境中。" #: ../../configuration.rst:97 msgid "" "Below is an example of how to integrate system environment variables in pycsw:" msgstr "下面是一个如何在pycsw中集成系统环境变量的例子:" #: ../../configuration.rst:107 msgid "Alternate Configurations" msgstr "备用配置" #: ../../configuration.rst:109 msgid "" "By default, pycsw loads ``default.yml`` at runtime. To load an alternate " "configuration, modify ``csw.py`` to point to the desired configuration. " "Alternatively, pycsw supports explicitly specifiying a configuration by " "appending ``config=/path/to/default.yml`` to the base URL of the service (e.g. " "``http://localhost/pycsw/csw.py?config=tests/suites/default/default." .yml&service=CSW&version=2.0.2&request=GetCapabilities``). When the ``config`` " "parameter is passed by a CSW client, pycsw will override the default " "configuration location and subsequent settings with those of the specified " "configuration." msgstr "" "默认情况下,pycsw在运行时加载的是 ``default.yml`` 。要加载备用配置,请修改 " "``csw.py`` 以指向所需的配置。另外,pycsw还可以通过附加 ``config=/path/to/" "default.yml`` 到服务器的基础URL来显式定义配置,例如 ``http://localhost/pycsw/" "csw.py?config=tests/suites/default/default." .yml&service=CSW&version=2.0.2&request=GetCapabilities`` 。当 ``config`` 参数通过" "CSW客户端时,pycsw就会覆盖默认的配置所在地址,并且用这些指定的配置来完成接下来的" "一系列设置。" #: ../../configuration.rst:111 msgid "" "This also provides the functionality to deploy numerous CSW servers with a " "single pycsw installation." msgstr "这还提供了通过单个 pycsw 安装部署大量 CSW 服务器的功能。" #: ../../configuration.rst:114 msgid "Hiding the Location" msgstr "隐藏的位置" #: ../../configuration.rst:116 msgid "" "Some deployments with alternate configurations prefer not to advertise the base " "URL with the ``config=`` approach. In this case, there are many options to " "advertise the base URL." msgstr "" "一些具有备用配置的部署不喜欢使用 config= 方法公布基 URL。 在这种情况下,有许多选" "项可以宣传基 URL。" #: ../../configuration.rst:119 msgid "Environment Variables" msgstr "环境变量" #: ../../configuration.rst:121 msgid "pycsw supports the following environment variables:" msgstr "pycsw 支持以下环境变量:" #: ../../configuration.rst:123 msgid "``PYCSW_CONFIG``: specifies the filepath to a pycsw configuraiton" msgstr "``PYCSW CONFIG``: 指定 pycsw 配置的文件路径" #: ../../configuration.rst:127 msgid "Configuration file location" msgstr "配置文件位置" #: ../../configuration.rst:129 msgid "" "One option is using Apache's ``Alias`` and ``SetEnvIf`` directives. For " "example, given the base URL ``http://localhost/pycsw/csw.py?config=foo.yml``, " "set the following in your Apache configuration:" msgstr "" "有一种选择是使用 Apache 的 ``Alias`` 和 ``SetEnvIf`` 指令。 例如,可以指定基 " "URL ``http://localhost/pycsw/csw.py?config=foo.yml`` ,在 Apache 的 ``httpd." "conf`` 下配置以下指令:" #: ../../configuration.rst:138 msgid "Apache must be restarted after changes to configuration" msgstr "更改配置后必须重新启动 Apache" #: ../../configuration.rst:140 msgid "" "pycsw will use the configuration as set in the ``PYCSW_CONFIG`` environment " "variable in the same manner as if it was specified in the base URL. Note that " "the configuration value ``server.url`` value must match the ``Request_URI`` " "value so as to advertise correctly in pycsw's Capabilities XML." msgstr "" "pycsw 将以同样的方式配置设置 ``PYCSW_CONFIG`` 的环境变量,就如同它在基 URL 中指" "定了一样。 请注意,配置值 ``server.url`` 值必须匹配 ``Request_URI`` 值,这样在 " "pycsw 的功能 XML 中就可以做正确声明了。" #: ../../configuration.rst:143 msgid "Wrapper Script" msgstr "包装器脚本" #: ../../configuration.rst:145 msgid "" "Another option is to write a simple wrapper (e.g. ``csw-foo.sh``), which " "provides the same functionality and can be deployed without restarting Apache:" msgstr "" "另一个选择是编写一个简单的包装器 (如 ``csw-foo.sh`` ),也会有相同的功能,而且无" "需重新启动 Apache 也可以部署:" #~ msgid "" #~ "**gzip_compresslevel**: gzip compression level, lowest is ``1``, highest is " #~ "``9``. Default is off" #~ msgstr "" #~ "**gzip_compresslevel**: 压缩级别,最低是 ``1`` ,最高是 ``9`` 。 默认值是不" #~ "压缩" ================================================ FILE: docs/locale/zh/LC_MESSAGES/contributing.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 15:36+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../../CONTRIBUTING.rst:2 msgid "Contributing to pycsw" msgstr "pycsw的贡献" #: ../../../CONTRIBUTING.rst:4 msgid "" "The pycsw project openly welcomes contributions (bug reports, bug fixes, " "code enhancements/features, etc.). This document will outline some " "guidelines on contributing to pycsw. As well, the pycsw `community " "`_ is a great place to get an idea of how " "to connect and participate in pycsw community and development." msgstr "" "Pycsw 项目是开源的,欢迎贡献 (bug 报告、 bug 修复、 代码增强功能等)。此" "篇文章将概述pycsw 的一些作用。 pycsw `community `_ ,就是提供一些建议,应该如何连接和参与 pycsw 社区,并如何更" "好地发展。" #: ../../../CONTRIBUTING.rst:9 msgid "pycsw has the following modes of contribution:" msgstr "以下是几项pycsw做出的贡献:" #: ../../../CONTRIBUTING.rst:11 ../../../CONTRIBUTING.rst:25 msgid "GitHub Commit Access" msgstr "GitHub 提交修改的权限" #: ../../../CONTRIBUTING.rst:12 ../../../CONTRIBUTING.rst:33 msgid "GitHub Pull Requests" msgstr "GitHub 的请求" #: ../../../CONTRIBUTING.rst:15 msgid "Code of Conduct" msgstr "行为准则" #: ../../../CONTRIBUTING.rst:17 msgid "" "Contributors to this project are expected to act respectfully toward " "others in accordance with the `OSGeo Code of Conduct `_." msgstr "" "本项目的贡献者应按照`OSGeo 行为准则`_ 以尊重他人的方式行事。" #: ../../../CONTRIBUTING.rst:20 msgid "Contributions and Licensing" msgstr "贡献和许可" #: ../../../CONTRIBUTING.rst:22 msgid "" "Contributors are asked to confirm that they comply with project `license " "`_ " "guidelines." msgstr "" "贡献者应当符合 `许可证 `_ 准则。" #: ../../../CONTRIBUTING.rst:27 msgid "" "proposals to provide developers with GitHub commit access shall be " "emailed to the pycsw-devel `mailing list`_. Proposals shall be approved " "by the pycsw development team. Committers shall be added by the project " "admin" msgstr "" "建议开发人员提供 GitHub 的提交访问权限,此权限应通过电子邮件发送到pycsw-" "devel `mailing list`_。希望 pycsw 开发团队可以允许。应由项目管理员处添加" "访问者" #: ../../../CONTRIBUTING.rst:28 msgid "removal of commit access shall be handled in the same manner" msgstr "应以同样的方式解除提交访问权限" #: ../../../CONTRIBUTING.rst:29 msgid "" "each committer must send an email to the pycsw mailing list agreeing to " "the license guidelines (see `Contributions and Licensing Agreement " "Template <#contributions-and-licensing-agreement-template>`_). **This " "is only required once**" msgstr "" "每个提交的用户必须发送电子邮件到 pycsw 邮件列表中,前得是同意许可证准则 " "(见 `贡献和许可协议模板 <#contributions-and-licensing-agreement-" "template>`_ )。**只需一次即可**" #: ../../../CONTRIBUTING.rst:30 msgid "" "each committer shall be listed in https://github.com/geopython/pycsw/" "blob/master/COMMITTERS.txt" msgstr "" "每个提交的用户会显示在 https://github.com/geopython/pycsw/blob/master/" "COMMITTERS.txt 列表中" #: ../../../CONTRIBUTING.rst:35 msgid "" "pull requests can provide agreement to license guidelines as text in the " "pull request or via email to the pycsw `mailing list`_ (see " "`Contributions and Licensing Agreement Template <#contributions-and-" "licensing-agreement-template>`_). **This is only required for a " "contributor's first pull request. Subsequent pull requests do not " "require this step**" msgstr "" "pull 请求可以提供协议许可准则,在pull请求时可作为文本,也可以电邮至 " "pycsw 邮件列表 (见 `贡献和许可协议模板<#contributions-and-licensing-" "agreement-template>`_ )。**这只需要在第一次Pull请求时使用。后续的请求不" "需要此步骤**" #: ../../../CONTRIBUTING.rst:36 msgid "" "pull requests may include copyright in the source code header by the " "contributor if the contribution is significant or the contributor wants " "to claim copyright on their contribution" msgstr "" "如果有重大贡献或贡献者想要申请版权专利,pull请求可以将源代码设置权限" #: ../../../CONTRIBUTING.rst:37 msgid "" "all contributors shall be listed at https://github.com/geopython/pycsw/" "graphs/contributors" msgstr "" "所有贡献者均在 https://github.com/geopython/pycsw/graphs/contributors 列" "表中" #: ../../../CONTRIBUTING.rst:38 msgid "" "unclaimed copyright, by default, is assigned to the main copyright " "holders as specified in https://github.com/geopython/pycsw/blob/master/" "LICENSE.txt" msgstr "" "若无人声明版权所属,在默认情况下,会指定分配给主要的版权持有人,在 " "https://github.com/geopython/pycsw/blob/master/LICENSE.txt 中强调指出" #: ../../../CONTRIBUTING.rst:41 msgid "Contributions and Licensing Agreement Template" msgstr "贡献和许可协议模板" #: ../../../CONTRIBUTING.rst:43 msgid "" "``Hi all, I'd like to contribute to pycsw. I confirm that my contributions to pycsw will be " "compatible with the pycsw license guidelines at the time of contribution." "``" msgstr "" "``大家好,我愿意在pycsw贡献 。我" "确认对pycsw的贡献将与pycsw 许可指南兼容。``" #: ../../../CONTRIBUTING.rst:49 msgid "GitHub" msgstr "GitHub" #: ../../../CONTRIBUTING.rst:51 msgid "" "Code, tests, documentation, wiki and issue tracking are all managed on " "GitHub. Make sure you have a `GitHub account `_." msgstr "" "代码,测试,文档,wiki和问题都在GitHub上进行追踪管理,以确保每个人均有一" "个自己的 `GitHub的账户 `_ 。" #: ../../../CONTRIBUTING.rst:55 msgid "Code Overview" msgstr "代码概览" #: ../../../CONTRIBUTING.rst:57 msgid "" "the pycsw `wiki `_ documents an overview of the codebase" msgstr "" "在pycsw `维基 `_ 有详细的代码库概述" #: ../../../CONTRIBUTING.rst:60 msgid "Documentation" msgstr "说明文件" #: ../../../CONTRIBUTING.rst:62 msgid "documentation is managed in ``docs/``, in reStructuredText format" msgstr "文档在 ``docs/`` 中管理,以 reStructuredText 格式" #: ../../../CONTRIBUTING.rst:63 msgid "`Sphinx`_ is used to generate the documentation" msgstr "`Sphinx`_ 作用是生成文档" #: ../../../CONTRIBUTING.rst:64 msgid "" "See the `reStructuredText Primer `_ on rST markup and syntax." msgstr "" "请参阅关于 rST 标记和语法的 `reStructuredText Primer `_。" #: ../../../CONTRIBUTING.rst:67 msgid "Bugs" msgstr "漏洞" #: ../../../CONTRIBUTING.rst:69 msgid "" "pycsw's `issue tracker `_ is " "the place to report bugs or request enhancements. To submit a bug be " "sure to specify the pycsw version you are using, the appropriate " "component, a description of how to reproduce the bug, as well as what " "version of Python and platform. For convenience, you can run ``pycsw-" "admin.py get-sysprof`` and copy/paste the output into your issue." msgstr "" "pycsw 的 `问题跟踪器 `_ ,是报" "告错误或要求改进的地方。当提交出现的错误时,一定要指定正在使用的pycsw版" "本,相应的组件,如何操作显示的错误信息,以及Python和平台的版本。为方便起" "见,可运行 ``pycsw-admin.py -c get_sysprof``,并将输出信息复制、粘贴到问" "题中。" #: ../../../CONTRIBUTING.rst:72 msgid "Forking pycsw" msgstr "分叉pycsw" #: ../../../CONTRIBUTING.rst:74 msgid "" "Contributions are most easily managed via GitHub pull requests. `Fork " "`_ pycsw into your own GitHub " "repository to be able to commit your work and submit pull requests." msgstr "" "通过 GitHub pull 请求后,贡献是最容易管理的。'Fork ' _ pycsw 放到自己 GitHub 存储库中,这样可以轻松地提" "交工作,并提交pull请求。" #: ../../../CONTRIBUTING.rst:78 msgid "Development" msgstr "开发" #: ../../../CONTRIBUTING.rst:81 msgid "GitHub Commit Guidelines" msgstr "GitHub 提交指南" #: ../../../CONTRIBUTING.rst:83 msgid "enhancements and bug fixes should be identified with a GitHub issue" msgstr "增强和 bug 修复应该等同于 GitHub 问题" #: ../../../CONTRIBUTING.rst:84 msgid "" "commits should be granular enough for other developers to understand the " "nature / implications of the change(s)" msgstr "提交时粒数应该足够量,为方便其他开发人员了解自然/变化的影响(S)" #: ../../../CONTRIBUTING.rst:85 msgid "" "non-trivial Git commits shall be associated with a GitHub issue. As " "documentation can always be improved, tickets need not be opened for " "improving the docs" msgstr "" "若是重大事件的 Git 提交应与 GitHub 问题部门取得联系。以文档格式是可以修改" "的,但修改文档的tickets则是不必公开的" #: ../../../CONTRIBUTING.rst:86 msgid "Git commits shall include a description of changes" msgstr "Git 提交应包括更改说明" #: ../../../CONTRIBUTING.rst:87 msgid "" "Git commits shall include the GitHub issue number (i.e. ``#1234``) in " "the Git commit log message" msgstr "Git 提交应在Git 提交日志中写入 GitHub 问题编号 (例如 ``#1234`` )" #: ../../../CONTRIBUTING.rst:88 msgid "" "all enhancements or bug fixes must successfully pass all :ref:`ogc-cite` " "tests before they are committed" msgstr "" "在提交之前,所有应改进的或错误修改的必须通过所有 :ref:`ogc-cite` 测试" #: ../../../CONTRIBUTING.rst:89 msgid "" "all enhancements or bug fixes must successfully pass all :ref:`tests` " "tests before they are committed" msgstr "在提交之前,所有应改进的或错误修改的必须通过所有 :ref:`tests` 测试" #: ../../../CONTRIBUTING.rst:90 msgid "" "enhancements which can be demonstrated from the pycsw :ref:`tests` " "should be accompanied by example CSW request XML" msgstr "pycsw加强的部分请参考 :ref:`tests` ,应附有像CSW的 请求 XML" #: ../../../CONTRIBUTING.rst:93 msgid "Coding Guidelines" msgstr "编码准则" #: ../../../CONTRIBUTING.rst:95 msgid "pycsw instead of PyCSW, pyCSW, Pycsw" msgstr "写法应是pycsw,而不是 PyCSW, pyCSW,Pycsw" #: ../../../CONTRIBUTING.rst:96 msgid "always code with `PEP 8`_ conventions" msgstr "应是 `PEP 8`_ 公约代码" #: ../../../CONTRIBUTING.rst:97 msgid "" "always run source code through `flake8`_ and `pylint`_, using all pylint " "defaults except for ``C0111``. ``sbin/pycsw-pylint.sh`` is included for " "convenience" msgstr "" "始终通过 `flake8`_ 和 `pylint`_ 运行源代码,使用除 `C0111` 之外的所有 " "pylint 默认值。为方便起见,包含了``sbin/pycsw-pylint.sh``" #: ../../../CONTRIBUTING.rst:98 msgid "" "for exceptions which make their way to OGC ``ExceptionReport`` XML, " "always specify the appropriate ``locator`` and ``code`` parameters" msgstr "" "除了OGC ``ExceptionReport`` XML运行方式为个别例外,通常会指定合适的 ``定" "位器`` 和 ``代码`` 参数" #: ../../../CONTRIBUTING.rst:102 msgid "Submitting a Pull Request" msgstr "提交pull请求" #: ../../../CONTRIBUTING.rst:104 msgid "" "This section will guide you through steps of working on pycsw. This " "section assumes you have forked pycsw into your own GitHub repository." msgstr "" "这一节将指导操作pycsw的步骤。本节假定在自己GitHub资料库中,有分叉的 " "pycsw。" #: ../../../CONTRIBUTING.rst:128 msgid "" "Your changes are now visible on your pycsw repository on GitHub. You " "are now ready to create a pull request. A member of the pycsw team will " "review the pull request and provide feedback / suggestions if required. " "If changes are required, make them against the same branch and push as " "per above (all changes to the branch in the pull request apply)." msgstr "" "更改在 GitHub自己的 pycsw 存储库为可见状态。现在要创建pull请求。Pycsw的团" "队成员将审查你的pull请求,若有需要,团队成员会提供反馈建议。如果需要改" "动,要另立分支,并push以上步骤 (pull请求中所有更改的分支)。" #: ../../../CONTRIBUTING.rst:132 msgid "" "The pull request will then be merged by the pycsw team. You can then " "delete your local branch (on GitHub), and then update your own " "repository to ensure your pycsw repository is up to date with pycsw " "master:" msgstr "" "然后pycsw 团队将合并pull请求。可删除掉本地的分支(在 GitHub),更新自己的" "库,以确保pycsw 存储库与pycsw总站是同步的:" #~ msgid "" #~ "for trivial commits that do not need `Travis CI `_ to run, include ``[ci skip]`` as part of the " #~ "commit message" #~ msgstr "" #~ "如果是一些琐碎的提交,就像是 ``[ci skip]`` 也是做为提交消息的一部分," #~ "则不需要运行 `Travis CI `_ " ================================================ FILE: docs/locale/zh/LC_MESSAGES/csw-support.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010-2015, Tom Kralidis This work is licensed under a # Creative Commons Attribution 4.0 International License # This file is distributed under the same license as the pycsw package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: pycsw 2.1-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-12-05 22:08+0800\n" "PO-Revision-Date: 2022-03-09 10:38+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.6.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../csw-support.rst:4 msgid "CSW Support" msgstr "CSW支持" #: ../../csw-support.rst:7 msgid "Versions" msgstr "版本" #: ../../csw-support.rst:9 msgid "" "pycsw supports both CSW 2.0.2 and 3.0.0 versions by default. In " "alignment with the CSW specifications, the default version returned is " "the latest supported version. That is, pycsw will always behave like a " "3.0.0 CSW unless the client explicitly requests a 2.0.2 CSW." msgstr "" "pycsw默认支持CSW 2.0.2和3.0.0版本。根据CSW规范,返回的默认版本是受支持的" "最新版本。也就是说,除非客户机明确地请求一个2.0.2 CSW,否则pycsw的行为始" "终类似于一个3.0.0 CSW." #: ../../csw-support.rst:14 msgid "" "The sample URLs below provide examples of how requests behaves against " "various/missing/default version parameters." msgstr "下面的示例 URLs提供了请求对不同/丢失/默认版本参数的行为的示例。" #: ../../csw-support.rst:25 msgid "Request Examples" msgstr "请求实例" #: ../../csw-support.rst:27 msgid "" "The best place to look for sample requests is within the `tests/` " "directory, which provides numerous examples of all supported APIs and " "requests." msgstr "" "查找示例请求的最佳位置是在 `tests/` 目录中,该目录提供了所有支持的 APIs" "和请求的许多示例。" #: ../../csw-support.rst:30 msgid "Additional examples:" msgstr "额外的实例:" #: ../../csw-support.rst:32 msgid "`Data.gov CSW HowTo v2.0`_" msgstr "`Data.gov CSW HowTo v2.0`_" #: ../../csw-support.rst:33 msgid "`pycsw Quickstart on OSGeoLive`_" msgstr "`pycsw Quickstart on OSGeoLive`_" ================================================ FILE: docs/locale/zh/LC_MESSAGES/distributedsearching.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 10:43+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../distributedsearching.rst:4 msgid "Distributed Searching" msgstr "分布式搜索" #: ../../distributedsearching.rst:8 msgid "" "Distributed search is supported for CSW 2/3 APIs. OARec support will be implemented following " "guidance from the OARec specification once available." msgstr "CSW 2/3 API 支持分布式搜索。一旦可用,OARec 支持将按照 OARec 规范的指导实施。" #: ../../distributedsearching.rst:13 msgid "Your server must be able to make outgoing HTTP requests for this functionality." msgstr "此功能的作用就是可以使你的服务器传出HTTP请求。" #: ../../distributedsearching.rst:15 msgid "" "pycsw has the ability to perform distributed searching against other CSW servers. Distributed " "searching is disabled by default; to enable, ``server.federatedcatalogues`` must be set. A CSW " "client must issue a GetRecords request with ``csw:DistributedSearch`` specified, along with an " "optional ``hopCount`` attribute (see subclause 10.8.4.13 of the CSW specification). When enabled, " "pycsw will search all specified catalogues and return a unified set of search results to the " "client. Due to the distributed nature of this functionality, requests will take extra time to " "process compared to queries against the local repository." msgstr "" "pycsw与其它CSW服务器不同的是,它有能力自己实现分布式搜索。此分布式搜索默认为禁用;若想启用,必须设置 " "``server.federatedcatalogues`` 。CSW客户端会发出一个 ``Getrecords`` 指定性请求 ``csw:" "DistributedSearch`` ,以及一个可选的 ``hopCount`` 属性(见CSW规范中第10.8.4.13 )。当启用时,pycsw会" "搜索所有指定的目录并会将一组统一的搜索结果返回给客户端。由于此功能的分布式性质,若要查询本地存储库," "请求可能会需要更多的时间来处理。" #: ../../distributedsearching.rst:18 msgid "Scenario: Federated Search" msgstr "场景:联合搜索" #: ../../distributedsearching.rst:20 msgid "" "pycsw deployment with 3 configurations (CSW-1, CSW-2, CSW-3), subsequently providing three (3) " "endpoints. Each endpoint is based on an opaque metadata repository (based on theme/place/" "discipline, etc.). Goal is to perform a single search against all endpoints." msgstr "" "pycsw部署共有3项配置(CSW-1,CSW-2,CSW-3),同时也会提供3个端点。每个端点是基于一个不透明的元数据信" "息库(基于主题/地点/学科等)。目标是执行对所有端点一对一的搜索。" #: ../../distributedsearching.rst:22 msgid "" "pycsw realizes this functionality by supporting :ref:`alternate configurations `, and exposes the additional CSW endpoint(s) with the following design pattern:" msgstr "" "pycsw 通过支持 :ref:`alternate configuration ` 来实现此功能,并使用以下设计" "模式公开额外的 CSW 端点:" #: ../../distributedsearching.rst:24 msgid "CSW-1: ``http://localhost/pycsw/csw.py?config=CSW-1.yml``" msgstr "CSW-1: ``http://localhost/pycsw/csw.py?config=CSW-1.yml``" #: ../../distributedsearching.rst:26 msgid "CSW-2: ``http://localhost/pycsw/csw.py?config=CSW-2.yml``" msgstr "CSW-2: ``http://localhost/pycsw/csw.py?config=CSW-2.yml``" #: ../../distributedsearching.rst:28 msgid "CSW-3: ``http://localhost/pycsw/csw.py?config=CSW-3.yml``" msgstr "CSW-3: ``http://localhost/pycsw/csw.py?config=CSW-3.yml``" #: ../../distributedsearching.rst:30 msgid "" "...where the ``*.yml`` configuration files are configured for each respective metadata repository. " "The above CSW endpoints can be interacted with as usual." msgstr "" "只要有 ``*.yml`` 配置文件,就可以为每个元数据存储库进行配置。以上的CSW端点也可以像往常一样进行交互。" #: ../../distributedsearching.rst:32 msgid "" "To federate the discovery of the three (3) portals into a unified search, pycsw realizes this " "functionality by deploying an additional configuration which acts as the superset of CSW-1, CSW-2, " "CSW-3:" msgstr "" "将这3个门户联合成统一的搜索,pycsw就可以通过部署超集的CSW-1、 CSW-2、 CSW-3 这些附加配置来实现此功" "能:" #: ../../distributedsearching.rst:34 msgid "CSW-all: ``http://localhost/pycsw/csw.py?config=CSW-all.yml``" msgstr "所有的CSW: ``http://localhost/pycsw/csw.py?config=CSW-all.yml``" #: ../../distributedsearching.rst:36 msgid "" "This allows the client to invoke one (1) CSW GetRecords request, in which the CSW endpoint spawns " "the same GetRecords request to 1..n distributed CSW endpoints. Distributed CSW endpoints are " "advertised in CSW Capabilities XML via ``ows:Constraint``:" msgstr "" "这允许客户端调用 1 CSW GetRecords 请求,其中CSW端点就会生成相同的GetRecords请求,从1到n分布各个CSW 终" "结点。分布式CSW端点通过 'ows:Constraint' 在CSW功能 XML上发布广告:" #: ../../distributedsearching.rst:50 msgid "" "...which advertises which CSW endpoint(s) the CSW server will spawn if a distributed search is " "requested by the client." msgstr "...如果客户端请求分布式搜索,它会通告 CSW 服务器将生成哪些 CSW 端点。" #: ../../distributedsearching.rst:52 msgid "in the CSW-all configuration:" msgstr "在 CSW-all 配置中:" #: ../../distributedsearching.rst:60 msgid "" "At which point a CSW client request to CSW-all with ``distributedsearch=TRUE``, while specifying an " "optional ``hopCount``. Query network topology:" msgstr "" "当指定选项 ``hopCount`` 时,CSW客户端就会用 ``distributedsearch=TRUE`` 请求所有的CSW。 查询网络拓扑:" #: ../../distributedsearching.rst:78 msgid "" "As a result, a pycsw deployment in this scenario may be approached on a per 'theme' basis, or at an " "aggregate level." msgstr "因此,在这个场景中,pycsw 部署就会深入每个 '主题' 的基础部分或总体水平。" #: ../../distributedsearching.rst:80 msgid "" "All interaction in this scenario is local to the pycsw installation, so network performance would " "not be problematic." msgstr "在这个场景中的所有交互都是在本地pycsw 安装的,所以网络性能的好与坏是不会产生影响的。" #: ../../distributedsearching.rst:82 msgid "" "A very important facet of distributed search is as per Annex B of OGC:CSW 2.0.2. Given that all the " "CSW endpoints are managed locally, duplicates and infinite looping are not deemed to present an " "issue." msgstr "" "分布式搜索的一个非常重要的方面是根据 OGC:CSW 2.0.2 的附件 B。鉴于所有 CSW 端点都在本地管理,重复和无" "限循环不被视为存在问题。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/docker.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010-2015, Tom Kralidis This work is licensed under a # Creative Commons Attribution 4.0 International License # This file is distributed under the same license as the pycsw package. # FIRST AUTHOR , 2018. # msgid "" msgstr "" "Project-Id-Version: pycsw 2.3-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 10:56+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../docker.rst:2 msgid "Docker" msgstr "Docker" #: ../../docker.rst:5 msgid "Installation" msgstr "安装" #: ../../docker.rst:7 msgid "" "pycsw provides an official `Docker`_ image which is made available on both the " "`geopython Docker Hub`_ and our `GitHub Container Registry`_." msgstr "" "pycsw 提供了一个官方的 `Docker`_ 镜像,可在 `geopython Docker Hub`_ 和 `GitHub " "Container Registry`_ 上使用。" #: ../../docker.rst:9 msgid "" "Either ``IMAGE`` can be called with the ``docker`` command, ``geopython/pycsw`` from " "DockerHub or ``ghcr.io/geophython/pycsw`` from the GitHub Container Registry. " "Examples below use ``geopython/pygeoapi``." msgstr "" "可以使用 docker 命令、DockerHub 中的 geopython/pycsw 或 GitHub 容器注册表中的 ghcr." "io/geophython/pycsw 调用 IMAGE 。下面的示例使用 ``geopython/pygeoapi``。" #: ../../docker.rst:11 msgid "" "Assuming you already have docker installed, you can get a pycsw instance up and " "running run with the default built-in configuration:" msgstr "假设已经安装了docker,可以通过发出以下命令来启动和运行pycsw实例:" #: ../../docker.rst:21 msgid "...then browse to http://localhost:8000" msgstr "...然后浏览到 http://localhost:8000" #: ../../docker.rst:23 msgid "" "Docker will retrieve the pycsw image (if needed) and then start a new container " "listening on port 8000." msgstr "Docker 将检索 pycsw 映像(如果需要),然后在端口 8000 上启动一个新容器。" #: ../../docker.rst:26 msgid "" "The default configuration will run pycsw with an sqlite repository backend loaded " "with some test data from the CITE test suite. You can use this to take pycsw for a " "test drive." msgstr "" "默认配置将运行pycsw, sqlite存储库后端装载来自CITE测试套件的一些测试数据。可使用它来测" "试pycsw。" #: ../../docker.rst:32 msgid "Inspect logs" msgstr "检查日志" #: ../../docker.rst:34 msgid "" "The default configuration for the docker image outputs logs to stdout. This is " "common practice with docker containers and enables the inspection of logs with the " "``docker logs`` command::" msgstr "" "docker 映像的默认配置将日志输出到标准输出。这是 docker 容器的常见做法,可以使用 " "docker logs 命令检查日志::" #: ../../docker.rst:50 msgid "" "In order to have pycsw logs being sent to standard output you must set ``server." "logfile=`` in the pycsw configuration file." msgstr "" "为了将pycsw日志发送到标准输出,必须在pycsw配置文件中设置 ``server.logfile=`` 。" #: ../../docker.rst:55 msgid "Using pycsw-admin.py" msgstr "使用 pycsw-admin.py" #: ../../docker.rst:57 msgid "" "``pycsw-admin.py`` can be executed on a running container by using ``docker exec``::" msgstr "``pycsw-admin.py`` 可以使用 ``docker exec`` 在正在运行的容器上执行::" #: ../../docker.rst:64 msgid "Running custom pycsw containers" msgstr "运行自定义PysCW容器" #: ../../docker.rst:67 msgid "pycsw configuration" msgstr "pycsw 配置" #: ../../docker.rst:69 msgid "" "It is possible to supply a custom configuration file for pycsw as a bind mount or as " "a docker secret (in the case of docker swarm). The configuration file is searched at " "the value of the ``PYCSW_CONFIG`` environmental variable, which defaults to ``/etc/" "pycsw/pycsw.yml``." msgstr "" "可以为pycsw提供自定义配置文件作为绑定安装或作为docker秘密(在docker群集的情况下)。配" "置文件在 ``PYCSW_CONFIG`` 环境变量的值处进行搜索,该环境变量默认为 ``/etc/pycsw/" "pycsw.yml`` 。" #: ../../docker.rst:74 msgid "Supplying the configuration file via bind mount::" msgstr "通过绑定挂载提供配置文件::" #: ../../docker.rst:83 msgid "Supplying the configuration file via docker secrets::" msgstr "通过docker 机密提供配置文件::" #: ../../docker.rst:95 msgid "sqlite repositories" msgstr "sqlite 存储库" #: ../../docker.rst:97 msgid "" "The default database repository is the CITE database that is used for running " "pycsw's test suites. Docker volumes may be used to specify a custom sqlite database " "path. It should be mounted under ``/var/lib/pycsw``::" msgstr "" "默认的数据库存储库是用于运行pycsw测试套件的CITE数据库。Docker卷可以用来指定自定义" "sqlite数据库路径。它应该安装在 ``/var/lib/pycsw``::" #: ../../docker.rst:112 msgid "PostgreSQL repositories" msgstr "PostgreSQL存储库" #: ../../docker.rst:114 msgid "" "Specifying a PostgreSQL repository is just a matter of configuring a custom pycsw." .yml file with the correct specification." msgstr "指定PostgreSQL存储库只是用正确的规范配置自定义pycsw.yml 文件的问题。" #: ../../docker.rst:117 msgid "" "Check `pycsw's github repository`_ for an example of a docker-compose/stack file " "that spins up a postgis database together with a pycsw instance." msgstr "" "查看 `pycsw's github repository`_ ,例如 docker-compose/stack文件,该文件将postgis数" "据库与pycsw实例一起旋转。" #: ../../docker.rst:122 msgid "Setting up a development environment with docker" msgstr "用docker建立开发环境" #: ../../docker.rst:124 msgid "" "Working on pycsw's code using docker enables an isolated environment that helps " "ensuring reproducibility while at the same time keeping your base system free from " "pycsw related dependencies. This can be achieved by:" msgstr "" "使用docker处理pycsw的代码可以实现一个隔离的环境,它有助于确保可重现性,同时使基本系统" "免受pycsw相关依赖项的影响。这可以通过以下方式实现:" #: ../../docker.rst:128 msgid "Cloning pycsw's repository locally;" msgstr "在本地克隆 pycsw 的仓库;" #: ../../docker.rst:129 msgid "" "Starting up a docker container with appropriately set up bind mounts. In addition, " "the pycsw docker image supports a ``reload`` flag that turns on automatic reloading " "of the gunicorn web server whenever the code changes;" msgstr "" "使用适当的绑定安装启动docker容器。此外,pycsw docker映像支持 ``reload`` 标志,当代码" "发生变化时,该标志将自动重新加载gunicorn web服务器;" #: ../../docker.rst:132 msgid "" "Installing the development dependencies by using ``docker exec`` with the root user;" msgstr "与root用户一起使用 ``docker exec`` 安装开发依赖项;" #: ../../docker.rst:135 msgid "The following instructions set up a fully working development environment::" msgstr "以下说明建立了一个完整工作的开发环境:" #: ../../docker.rst:169 msgid "" "Please note that the pycsw image only uses python 3.5 and that it also does not " "install pycsw in editable mode. As such it is not possible to use ``tox``." msgstr "" "请注意,pycsw映像只使用python 3.5,而且它也不以可编辑模式安装pycsw。因此,不可能使用 " "``tox``。" #: ../../docker.rst:173 msgid "" "Since the docs directory is bind mounted from your host machine into the container, " "after building the docs you may inspect their content visually, for example by " "running::" msgstr "" "由于docs目录是从主机绑定到容器中的,所以在构建docs之后,可以可视化地检查内容,例如," "通过运行::" #: ../../docker.rst:180 msgid "Kubernetes" msgstr "Kubernetes" #: ../../docker.rst:182 msgid "For `Kubernetes`_ orchestration, run the following in ``docker/kubernetes``:" msgstr "对于 `Kubernetes`_ 编排,在 `docker/kubernetes` 中运行以下命令:" #: ../../docker.rst:191 msgid "Helm" msgstr "Helm" #: ../../docker.rst:193 msgid "For Kubernetes deployment via `Helm`_, run the following in ``docker/helm``:" msgstr "对于通过 `Helm`_ 部署 Kubernetes,在 `docker/helm` 中运行以下命令:" #~ msgid "" #~ "pycsw is available as a Docker image. The image is hosted on the `Docker Hub`_." #~ msgstr "pycsw可用作 Docker图像。图像被寄存在 `Docker Hub`_. 上。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/geonode.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 10:58+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../geonode.rst:4 msgid "GeoNode Configuration" msgstr "GeoNode配置" #: ../../geonode.rst:6 msgid "" "GeoNode (https://geonode.org/) is a platform for the management and publication " "of geospatial data. It brings together mature and stable open-source software " "projects under a consistent and easy-to-use interface allowing users, with " "little training, to quickly and easily share data and create interactive maps. " "GeoNode provides a cost-effective and scalable tool for developing information " "management systems. GeoNode uses CSW as a cataloguing mechanism to query and " "present geospatial metadata." msgstr "" "GeoNode (https://geonode.org/) 是一个用于管理和发布地理空间数据的平台。它将成熟" "稳定的开源软件项目汇集在一致且易于使用的界面下,使用户无需培训即可快速轻松地共享" "数据并创建交互式地图。 GeoNode 为开发信息管理系统提供了一种经济高效且可扩展的工" "具。GeoNode 使用 CSW 作为编目机制来查询和呈现地理空间元数据。" #: ../../geonode.rst:8 msgid "" "pycsw supports binding to an existing GeoNode repository for metadata query. " "The binding is read-only (transactions are not in scope, as GeoNode manages " "repository metadata changes in the application proper)." msgstr "" "pycsw绑定到现有GeoNode库,此库用于元数据查询。此绑定是只读文件(交易不在范围内," "GeoNode在适当的应用程序中管理库元数据)。" #: ../../geonode.rst:11 msgid "GeoNode Setup" msgstr "GeoNode设置" #: ../../geonode.rst:13 msgid "" "pycsw is enabled and configured by default in GeoNode, so there are no " "additional steps required once GeoNode is setup. See the ``CATALOGUE`` and " "``PYCSW`` `settings.py entries`_ at for customizing pycsw within GeoNode." msgstr "" "pycsw 在 GeoNode 中默认启用和配置,因此设置 GeoNode 后无需执行其他步骤。有关在 " "GeoNode 中自定义 pycsw,请参阅 ``CATALOGUE`` 和 ``PYCSW`` `settings.py 条目`_。" #: ../../geonode.rst:15 msgid "The GeoNode plugin is managed outside of pycsw within the GeoNode project." msgstr "GeoNode插件不是由 GeoNode 项目中的 pycsw 管理。" #~ msgid "" #~ "pycsw is enabled and configured by default in GeoNode, so there are no " #~ "additional steps required once GeoNode is setup. See the ``CATALOGUE`` and " #~ "``PYCSW`` `settings.py entries`_ at http://docs.geonode.org/en/latest/" #~ "developers/reference/django-apps.html#id1 for customizing pycsw within " #~ "GeoNode." #~ msgstr "" #~ "在GeoNode中,pycsw 的启用和配置都是默认的,所以GeoNode的安装程序不需要额外步" #~ "骤的。若想定制GeoNode-pycsw,请参见 http://docs.geonode.org/en/latest/" #~ "developers/reference/django-apps.html#id1 中 ``CATALOGUE`` 和 ``PYCSW`` " #~ "`settings.py entries`_ 。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/hhypermap.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010-2015, Tom Kralidis This work is licensed under a # Creative Commons Attribution 4.0 International License # This file is distributed under the same license as the pycsw package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 11:01+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../hhypermap.rst:4 msgid "HHypermap-Registry Configuration" msgstr "HHypermap-注册表配置 " #: ../../hhypermap.rst:6 msgid "" "HHypermap (Harvard Hypermap) Registry (https://github.com/cga-harvard/" "Hypermap-Registry) is an application that manages OWS, Esri REST, and " "other types of map service harvesting, and maintains uptime statistics " "for services and layers. HHypermap Registry will publish to HHypermap " "Search (based on Lucene) which provides a fast search and visualization " "environment for spatio-temporal materials." msgstr "" "HHypermap (Harvard Hypermap) Registry (https://github.com/cga-harvard/" "Hypermap-Registry) 是一个应用程序,用于管理 OWS、Esri REST 和其他类型的地" "图服务采集,并维护服务和图层的正常运行时间统计信息。HHypermap Registry 将" "发布到 HHypermap Search(基于 Lucene),为时空材料提供快速搜索和可视化环" "境。" #: ../../hhypermap.rst:8 msgid "" "HHypermap uses CSW as a cataloguing mechanism to ingest, query and " "present geospatial metadata." msgstr "HHypermap使用CSW作为摄取、查询、地理空间元数据显示的编目。" #: ../../hhypermap.rst:10 msgid "" "pycsw supports binding to an existing HHypermap repository for metadata " "query." msgstr "为元数据查询,将pycsw绑定到已有的HHypermap存储库。" #: ../../hhypermap.rst:13 msgid "HHypermap Setup" msgstr "HHypermap设置" #: ../../hhypermap.rst:15 msgid "" "pycsw is enabled and configured by default in HHypermap, so there are no " "additional steps required once HHypermap is setup. See the " "``REGISTRY_PYCSW`` `hypermap/settings.py entries`_ for customizing pycsw " "within HHypermap." msgstr "" "pycsw 在 HHypermap 中默认启用和配置,因此一旦设置 HHypermap,就不需要额外" "的步骤。有关在 HHypermap 中自定义 pycsw 的信息,请参阅 `REGISTRY_PYCSW` " "`hypermap/settings.py 条目`_。" #: ../../hhypermap.rst:17 msgid "" "The HHypermap plugin is managed outside of pycsw within the HHypermap " "project. HHypermap settings must ensure that " "``REGISTRY_PYCSW['repository']['source']`` is set to``hypermap.search." "pycsw_repository``." msgstr "" "HHypermap插件是在HHypermap 项目之外的 pycsw之外进行管理的。HHypermap设置" "必须确保 ``REGISTRY_PYCSW['repository']['source']`` 被设置为 ``hypermap." "search.pycsw_repository``。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/index.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-12-05 22:08+0800\n" "PO-Revision-Date: 2022-03-09 11:02+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.6.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../index.rst:5 msgid "pycsw |release| Documentation" msgstr "pycsw 发布 文档" #: ../../index.rst msgid "Author" msgstr "作者" #: ../../index.rst:7 msgid "Tom Kralidis" msgstr "Tom Kralidis" #: ../../index.rst msgid "Contact" msgstr "联系" #: ../../index.rst:8 msgid "tomkralidis at gmail.com" msgstr "tomkralidis at gmail.com" #: ../../index.rst msgid "Release" msgstr "发布" #: ../../index.rst:9 msgid "|release|" msgstr "|发布|" #: ../../index.rst msgid "Date" msgstr "日期" #: ../../index.rst:10 msgid "|today|" msgstr "|今天|" ================================================ FILE: docs/locale/zh/LC_MESSAGES/installation.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 11:10+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../installation.rst:4 msgid "Installation" msgstr "安装" #: ../../installation.rst:7 msgid "System Requirements" msgstr "系统要求" #: ../../installation.rst:9 msgid "" "pycsw is written in `Python `_, and works with (tested) " "Python 3." msgstr "" "pycsw 由 `Python `_ 编写,可与(经过测试的)Python 3 一起使" "用。" #: ../../installation.rst:11 msgid "pycsw requires the following Python supporting libraries:" msgstr "pycsw 是由以下Python库支撑的:" #: ../../installation.rst:13 msgid "`lxml`_ for XML support" msgstr "`lxml`_ 用于XML 支撑" #: ../../installation.rst:14 msgid "`SQLAlchemy`_ for database bindings" msgstr "`SQLAlchemy`_ 用于数据库绑定" #: ../../installation.rst:15 msgid "`pyproj`_ for coordinate transformations" msgstr "`pyproj`_ 用于变换坐标" #: ../../installation.rst:16 msgid "`Shapely`_ for spatial query / geometry support" msgstr "`Shapely`_ 用于空间查询/ 几何支持" #: ../../installation.rst:17 msgid "`OWSLib`_ for CSW client and metadata parser" msgstr "`OWSLib`_ 用于CSW客户端和元数据分析" #: ../../installation.rst:18 msgid "`xmltodict`_ for working with XML similar to working with JSON" msgstr "`xmltodict`_ ,来像使用 JSON 一样使用 XML" #: ../../installation.rst:19 msgid "`geolinks`_ for dealing with geospatial links" msgstr "`geolinks`_ 处理 地理空间链接" #: ../../installation.rst:22 msgid "OGC API - Records" msgstr "OGC API - 记录" #: ../../installation.rst:24 msgid "OGC API - Records support additionally requires the following:" msgstr "OGC API - 记录支持还需要以下内容:" #: ../../installation.rst:26 msgid "`Flask`_ for pycsw's default OARec endpoint" msgstr "`Flask`_ 用于 pycsw 的默认 OARec 端点" #: ../../installation.rst:27 msgid "`pygeofilter`_ for CQL parsing" msgstr "`pygeofilter`_ 用于 CQL 解析" #: ../../installation.rst:28 msgid "`PyYAML`_ for OpenAPI document handling" msgstr "`PyYAML`_ 用于 OpenAPI 文档处理" #: ../../installation.rst:32 msgid "You can install these dependencies via `pip`_" msgstr "可以通过 `pip`_ 安装这些依赖项" #: ../../installation.rst:36 msgid "" "For :ref:`GeoNode ` or :ref:`Open Data Catalog ` or :ref:" "`HHypermap ` deployments, SQLAlchemy is not required" msgstr "" "对于 :ref:`GeoNode ` 或 :ref:`Open Data Catalog ` ,或 :ref:" "`HHypermap ` 部署,SQLAlchemy 不是必需的" #: ../../installation.rst:39 msgid "Installing from Source" msgstr "从源代码安装" #: ../../installation.rst:41 msgid "" "`Download `_ the latest stable version or fetch from " "Git." msgstr "`下载 `_ 最新稳定版本,或从 Git 获取。" #: ../../installation.rst:44 msgid "For Developers and the Truly Impatient" msgstr "为开发人员和真正Impatient" #: ../../installation.rst:46 msgid "The 4 minute install:" msgstr "安装需要4分钟:" #: ../../installation.rst:63 msgid "To enable OGC API - Records as well as the abovementioned search standards:" msgstr "要启用 OGC API - 记录以及上述搜索标准:" #: ../../installation.rst:84 msgid "The Quick and Dirty Way" msgstr "快速但并非完善的方式" #: ../../installation.rst:90 msgid "" "Ensure that CGI is enabled for the install directory. For example, on Apache, " "if pycsw is installed in ``/srv/www/htdocs/pycsw`` (where the URL will be " "``http://host/pycsw/csw.py``), add the following to ``httpd.conf``:" msgstr "" "确保在安装目录中 CGI已启用。 例如,对 Apache,如果 pycsw 安装在 ``/srv/www/" "htdocs/pycsw`` (这时,URL 就会在 ``http://host/pycsw/csw.py`` ),将以下信息添加" "至 ``httpd.conf`` :" #: ../../installation.rst:101 msgid "" "If pycsw is installed in ``cgi-bin``, this should work as expected. In this " "case, the :ref:`tests ` application must be moved to a different location " "to serve static HTML documents." msgstr "" "如果 pycsw安装在 ``cgi-bin`` 下,工作就能预期进行。在这种情况下, :ref:" "`tests` 应用程序就必须转移到其它位置,成为静态的 HTML 文件。" #: ../../installation.rst:103 msgid "" "Make sure, you have all the dependencies from ``requirements.txt and " "requirements-standalone.txt``" msgstr "" "请确保已从 ``requirements.txt and requirements-standalone.txt`` 获得所有" "dependencies" #: ../../installation.rst:106 msgid "The Clean and Proper Way" msgstr "适当的方式" #: ../../installation.rst:115 msgid "" "At this point, pycsw is installed as a library and requires a CGI ``csw.py`` or " "WSGI ``pycsw/wsgi.py`` script to be served into your web server environment (see " "below for WSGI configuration/deployment)." msgstr "" "在这一点上,pycsw 安装库将 CGI 'csw.py '或 WSGI' pycsw/wsgi.py ' 脚本发送到您的 " "web 服务器环境 (参见下文 WSGI 配置/部署)。" #: ../../installation.rst:122 msgid "Installing from the Python Package Index (PyPI)" msgstr "从 Python 包索引 (PyPI) 安装" #: ../../installation.rst:131 msgid "Installing from OpenSUSE Build Service" msgstr "从 OpenSUSE 生成服务安装" #: ../../installation.rst:133 msgid "" "In order to install the pycsw package in openSUSE Leap (stable distribution), " "one can run the following commands as user ``root``:" msgstr "" "若要在 openSUSE Leap (稳定版本) 安装 pycsw 包,就可以以用户 ``root`` 身份运行以下" "命令:" #: ../../installation.rst:142 msgid "" "In order to install the pycsw package in openSUSE Tumbleweed (rolling " "distribution), one can run the following commands as user ``root``:" msgstr "" "若要在 openSUSE Tumbleweed (滚动版本) 安装 pycsw 包,就可以以用户 ``root`` 身份运" "行以下命令:" #: ../../installation.rst:150 msgid "" "An alternative method is to use the `One-Click Installer `_." msgstr "" "另一种方法是使用 `一键式安装程序 `_ 。" #: ../../installation.rst:155 msgid "Installing on Ubuntu/Mint" msgstr "在 Ubuntu/Mint系统上安装" #: ../../installation.rst:157 msgid "" "In order to install the most recent pycsw release to an Ubuntu-based " "distribution, one can use the UbuntuGIS Unstable repository by running the " "following commands:" msgstr "" "为了在基于 Ubuntu 的发行版安装最新的 pycsw,可以运行以下命令来使用 UbuntuGIS 非稳" "定版本:" #: ../../installation.rst:165 msgid "" "Alternatively, one can use the UbuntuGIS Stable repository which includes older " "but very well tested versions:" msgstr "或者,可以使用UbuntuGIS Stable存储库,其中包含较老但经过良好测试的版本:" #: ../../installation.rst:167 msgid "" "sudo add-apt-repository ppa:ubuntugis/ppa sudo apt-get update sudo apt-get " "install python-pycsw pycsw-cgi" msgstr "" "sudo add-apt-repository ppa:ubuntugis/ppa sudo apt-get update sudo apt-get " "install python-pycsw pycsw-cgi" #: ../../installation.rst:172 msgid "" "Since Ubuntu 16.04 LTS Xenial release, pycsw is included by default in the " "official Multiverse repository." msgstr "自从Ubuntu 16.04LTS Xenial发布以来,pycsw默认包含在官方的多版本存储库中。" #: ../../installation.rst:175 msgid "Running on Windows" msgstr "在 Windows 上运行" #: ../../installation.rst:177 msgid "For Windows installs, change the first line of ``csw.py`` to:" msgstr "对于Windows 安装,更改 ``csw.py`` 的第一行:" #: ../../installation.rst:184 msgid "The use of ``-u`` is required to properly output gzip-compressed responses." msgstr "使用 ``-u`` 需要正确输出 gzip 压缩响应。" #: ../../installation.rst:187 msgid "" "``USERNAME`` should match your username, and the Python version should match " "with your install (e.g. ``Python36``)." msgstr "" "``USERNAME`` 应该匹配用户名,并且 Python 版本应该和你的安装匹配(例如 " "``Python36``)。" #: ../../installation.rst:191 msgid "" "`MS4W `__ (MapServer for Windows) as of its version 4.0 " "release includes pycsw, Apache's mod_wsgi, Python 3.7, and many other tools, all " "ready to use out of the box. After installing, you will find your local pycsw " "catalogue endpoint, and steps for further configuration, on your browser's " "localhost page. You can read more about pycsw inside MS4W `here `__." msgstr "" "`MS4W `__ (MapServer for Windows) 从 4.0 版开始包括 pycsw、" "Apache 的 mod_wsgi、Python 3.7 和许多其他工具,所有这些工具都可以开箱即用。安装" "后,将在浏览器的 localhost 页面上找到本地 pycsw 目录端点以及进一步配置的步骤。可" "以在此处`__阅读更多关于 MS4W 中 " "pycsw 的信息。" #: ../../installation.rst:197 msgid "Security" msgstr "安全性" #: ../../installation.rst:199 msgid "" "By default, ``default.yml`` is at the root of the pycsw install. If pycsw is " "setup outside an HTTP server's ``cgi-bin`` area, this file could be read. The " "following options protect the configuration:" msgstr "" "默认情况下, ``default.yml`` 是 pycsw 安装的根目录。 如果 pycsw 设置在 HTTP 服务" "器 ``cgi-bin`` 区域以外,此文件就可以被读取。 以下是几项保护配置的选项:" #: ../../installation.rst:201 msgid "" "move ``default.yml`` to a non HTTP accessible area, and modify ``csw.py`` to " "point to the updated location" msgstr "" "将 ``default.yml`` 移动到非 HTTP 可访问的区域,并修改 ``csw.py`` 以指向更新的位置" #: ../../installation.rst:202 msgid "" "configure web server to deny access to the configuration. For example, in " "Apache, add the following to ``httpd.conf``:" msgstr "" "配置 web 服务器,拒绝对配置的访问。 例如,在 Apache 中,在 ``httpd.conf`` 下添加" "以下内容:" #: ../../installation.rst:213 msgid "Running on WSGI" msgstr "在 WSGI 上运行" #: ../../installation.rst:215 msgid "" "pycsw supports the `Web Server Gateway Interface`_ (WSGI). To run pycsw in WSGI " "mode, use ``pycsw/wsgi.py`` in your WSGI server environment." msgstr "" "pycsw 支持 `Web Server Gateway Interface`_ (WSGI)。 在 WSGI 模式下运行 pycsw,在 " "WSGI 服务器环境中使用 ``pycsw/wsgi.py`` 。" #: ../../installation.rst:220 msgid "" "``mod_wsgi`` supports only the version of python it was compiled with. If the " "target server already supports WSGI applications, pycsw will need to use the " "same python version. `WSGIDaemonProcess`_ provides a ``python-path`` directive " "that may allow a virtualenv created from the python version ``mod_wsgi`` uses." msgstr "" "``mod_wsgi`` 只支持已编译的python版本。如果目标服务器支持 WSGI 应用,pycsw也是相" "同的 python 版本。`WSGIDaemonProcess`_ 提供 ``python-path`` 指令,其允许从 " "python 版本 ``mod_wsgi`` 进行virtualenv 的创建。" #: ../../installation.rst:224 msgid "Below is an example of configuring with Apache:" msgstr "以下是使用 Apache 进行配置的示例:" #: ../../installation.rst:237 msgid "or use the `WSGI reference implementation`_:" msgstr "或者使用 `WSGI 参考实例`_ :" #: ../../installation.rst:244 msgid "which will publish pycsw to ``http://localhost:8000/``" msgstr "将pycsw发布到 ``http://localhost:8000/``" #~ msgid "`six`_ for Python 2/3 compatibility" #~ msgstr "`six`_ 用于处理 Python 2/3 兼容性" ================================================ FILE: docs/locale/zh/LC_MESSAGES/introduction.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 11:22+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../introduction.rst:4 msgid "Introduction" msgstr "引言" #: ../../introduction.rst:6 msgid "pycsw is an OARec and OGC CSW server implementation written in Python." msgstr "pycsw 是用 Python 编写的 OARec 和 OGC CSW 服务器实现。" #: ../../introduction.rst:9 msgid "Features" msgstr "特性" #: ../../introduction.rst:11 msgid "implements `OGC API - Records - Part 1: Core`_" msgstr "实现`OGC API - 记录 - 第 1 部分:核心`_" #: ../../introduction.rst:12 msgid "" "certified OGC `Compliant`_ and OGC Reference Implementation for both CSW " "2.0.2 and CSW 3.0.0" msgstr "CSW 2.0.2与 CSW 3.0.0 认证 OGC `Compliant`_ 与 OGC 参考实现" #: ../../introduction.rst:13 msgid "harvesting support for WMS, WFS, WCS, WPS, WAF, CSW, SOS" msgstr "WMS、WFS、WCS、WPS、WAF、CSW、SOS得到支持" #: ../../introduction.rst:14 msgid "implements `INSPIRE Discovery Services 3.0`_" msgstr "实现了 `INSPIRE Discovery Services 3.0`_" #: ../../introduction.rst:15 msgid "implements `ISO Metadata Application Profile 1.0.0`_" msgstr "实现了 `ISO Metadata Application Profile 1.0.0`_" #: ../../introduction.rst:16 msgid "implements `FGDC CSDGM Application Profile for CSW 2.0`_" msgstr "实现了 `FGDC CSDGM Application Profile for CSW 2.0`_ " #: ../../introduction.rst:17 msgid "implements the Search/Retrieval via URL (`SRU`_) search protocol" msgstr "实现了通过URL ( `SRU`_ ) 查找接口进行查找或抓取" #: ../../introduction.rst:18 msgid "implements Full Text Search capabilities" msgstr "实现了全文检索的功能" #: ../../introduction.rst:19 msgid "implements OGC OpenSearch Geo and Time Extensions" msgstr "实现了 OGC 开放搜索与时空扩展" #: ../../introduction.rst:20 msgid "implements Open Archives Initiative Protocol for Metadata Harvesting" msgstr "支持元数据主动文档开放协议" #: ../../introduction.rst:21 msgid "supports ISO, Dublin Core, DIF, FGDC, Atom and GM03 metadata models" msgstr "支持 ISO、Dublin Core、DIF、FGDC,Atom与 GM03 元数据模型" #: ../../introduction.rst:22 msgid "CGI or WSGI deployment" msgstr "CGI或WSCI部署" #: ../../introduction.rst:23 msgid "simple configuration" msgstr "简单配置" #: ../../introduction.rst:24 msgid "transactional capabilities (CSW-T)" msgstr "事务功能(CSW-T))" #: ../../introduction.rst:25 msgid "flexible repository configuration" msgstr "灵活的存储配置" #: ../../introduction.rst:26 msgid "`GeoNode`_ connectivity" msgstr "`GeoNode`_ 的连接" #: ../../introduction.rst:27 msgid "`HHypermap`_ connectivity" msgstr "`HHypermap`_ 的连接" #: ../../introduction.rst:28 msgid "`Open Data Catalog`_ connectivity" msgstr "`Open Data Catalog`_ 的连接" #: ../../introduction.rst:29 msgid "`CKAN`_ connectivity" msgstr "`CKAN`_ 的连接" #: ../../introduction.rst:30 msgid "federated catalogue distributed searching" msgstr "联合目录分布式搜索" #: ../../introduction.rst:31 msgid "realtime XML Schema validation" msgstr "实时XML Schema验证" #: ../../introduction.rst:32 msgid "extensible profile plugin architecture" msgstr "可扩展的配置文件插件架构" #: ../../introduction.rst:35 msgid "Standards Support" msgstr "支持的标准" #: ../../introduction.rst:1 msgid "Standard" msgstr "标准" #: ../../introduction.rst:1 msgid "Version(s)" msgstr "版本" #: ../../introduction.rst:1 msgid "`OGC API - Records - Part 1: Core`_" msgstr "`OGC API - Records - Part 1: Core`_" #: ../../introduction.rst:1 msgid "1.0" msgstr "1.0" #: ../../introduction.rst:1 msgid "" "`OGC API - Features - Part 3: Filtering and the Common Query Language " "(CQL)`_" msgstr "" "`OGC API - Features - Part 3: Filtering and the Common Query Language " "(CQL)`_" #: ../../introduction.rst:1 msgid "draft" msgstr "草稿" #: ../../introduction.rst:1 msgid "`OGC CSW`_" msgstr "`OGC CSW`_" #: ../../introduction.rst:1 msgid "2.0.2/3.0.0" msgstr "2.0.2/3.0.0" #: ../../introduction.rst:1 msgid "`OGC Filter`_" msgstr "`OGC Filte`_" #: ../../introduction.rst:1 msgid "1.1.0/2.0.0" msgstr "1.1.0/2.0.0" #: ../../introduction.rst:1 msgid "`OGC OWS Common`_" msgstr "`OGC OWS Common`_" #: ../../introduction.rst:1 msgid "1.0.0/2.0.0" msgstr "1.0.0/2.0.0" #: ../../introduction.rst:1 msgid "`OGC GML`_" msgstr "`OGC GML`_" #: ../../introduction.rst:1 msgid "3.1.1" msgstr "3.1.1" #: ../../introduction.rst:1 msgid "`OGC SFSQL`_" msgstr "`OGC SFSQL`_" #: ../../introduction.rst:1 msgid "1.2.1" msgstr "1.2.1" #: ../../introduction.rst:1 msgid "`Dublin Core`_" msgstr "`Dublin Core`_" #: ../../introduction.rst:1 msgid "1.1" msgstr "1.1" #: ../../introduction.rst:1 msgid "`SOAP`_" msgstr "`SOAP`_" #: ../../introduction.rst:1 msgid "1.2" msgstr "1.2" #: ../../introduction.rst:1 msgid "`ISO 19115`_" msgstr "`ISO 19115`_" #: ../../introduction.rst:1 msgid "2003" msgstr "2003" #: ../../introduction.rst:1 msgid "`ISO 19139`_" msgstr "`ISO 19139`_" #: ../../introduction.rst:1 msgid "2007" msgstr "2007" #: ../../introduction.rst:1 msgid "`ISO 19119`_" msgstr "`ISO 19119`_" #: ../../introduction.rst:1 msgid "2005" msgstr "2005" #: ../../introduction.rst:1 msgid "`NASA DIF`_" msgstr "`NASA DIF`_" #: ../../introduction.rst:1 msgid "9.7" msgstr "9.7" #: ../../introduction.rst:1 msgid "`FGDC CSDGM`_" msgstr "`FGDC CSDGM`_" #: ../../introduction.rst:1 msgid "1998" msgstr "1998" #: ../../introduction.rst:1 msgid "`GM03`_" msgstr "`GM03`_" #: ../../introduction.rst:1 msgid "2.1" msgstr "2.1" #: ../../introduction.rst:1 msgid "`SRU`_" msgstr "`SRU`_" #: ../../introduction.rst:1 msgid "`OGC OpenSearch`_" msgstr "`OGC OpenSearch`_" #: ../../introduction.rst:1 msgid "`OAI-PMH`_" msgstr "`OAI-PMH`_" #: ../../introduction.rst:1 msgid "2.0" msgstr "2.0" #: ../../introduction.rst:60 msgid "OGC API - Records support" msgstr "OGC API - 记录支持" #: ../../introduction.rst:62 msgid "Part 1: Core" msgstr "第 1 部分:核心" #: ../../introduction.rst:65 msgid "OGC API - Features support" msgstr "OGC API - 功能支持" #: ../../introduction.rst:67 msgid "Part 3: Filtering and the Common Query Language (CQL)" msgstr "第 3 部分:过滤和通用查询语言 (CQL)" #: ../../introduction.rst:70 ../../introduction.rst:118 msgid "Supported Output Formats" msgstr "支持的输出格式" #: ../../introduction.rst:72 msgid "JSON (default)" msgstr "JSON(默认)" #: ../../introduction.rst:73 msgid "XML" msgstr "XML" #: ../../introduction.rst:76 ../../introduction.rst:142 msgid "Supported Filters" msgstr "支持的过滤器" #: ../../introduction.rst:78 msgid "q" msgstr "q" #: ../../introduction.rst:79 msgid "datetime" msgstr "时区" #: ../../introduction.rst:80 msgid "filter (CQL)" msgstr "过滤器 (CQL)" #: ../../introduction.rst:81 msgid "bbox" msgstr "bbox" #: ../../introduction.rst:82 msgid "all properties (``property=value``)" msgstr "所有属性(``property=value``)" #: ../../introduction.rst:85 msgid "Paging" msgstr "分页" #: ../../introduction.rst:87 msgid "limit" msgstr "限度" #: ../../introduction.rst:88 msgid "startindex" msgstr "startindex" #: ../../introduction.rst:91 msgid "CSW Support" msgstr "CSW支持" #: ../../introduction.rst:94 msgid "Supported Operations" msgstr "支持的操作" #: ../../introduction.rst:1 msgid "Request" msgstr "请求" #: ../../introduction.rst:1 msgid "Optionality" msgstr "可选性" #: ../../introduction.rst:1 msgid "Supported" msgstr "支持" #: ../../introduction.rst:1 msgid "HTTP method binding(s)" msgstr "HTTP方法绑定" #: ../../introduction.rst:1 msgid "GetCapabilities" msgstr "功能" #: ../../introduction.rst:1 msgid "mandatory" msgstr "强制性的" #: ../../introduction.rst:1 msgid "yes" msgstr "是" #: ../../introduction.rst:1 msgid "GET (KVP) / POST (XML) / SOAP" msgstr "GET (KVP) / POST (XML) / SOAP" #: ../../introduction.rst:1 msgid "DescribeRecord" msgstr "记录详述" #: ../../introduction.rst:1 msgid "GetRecords" msgstr "获取记录" #: ../../introduction.rst:1 msgid "GetRecordById" msgstr "GetRecordById" #: ../../introduction.rst:1 msgid "optional" msgstr "选项" #: ../../introduction.rst:1 msgid "GetRepositoryItem" msgstr "项目库获取" #: ../../introduction.rst:1 msgid "GET (KVP)" msgstr "KVP获取" #: ../../introduction.rst:1 msgid "GetDomain" msgstr "GetDomain" #: ../../introduction.rst:1 msgid "Harvest" msgstr "获取" #: ../../introduction.rst:1 msgid "UnHarvest" msgstr "未收获" #: ../../introduction.rst:1 msgid "no" msgstr "否" #: ../../introduction.rst:1 msgid "Transaction" msgstr "订单" #: ../../introduction.rst:1 msgid "POST (XML) / SOAP" msgstr "POST (XML) / SOAP" #: ../../introduction.rst:111 msgid "" "Asynchronous processing supported for GetRecords and Harvest requests (via " "``csw:ResponseHandler``)" msgstr "异步处理支持 GetRecords 和获取请求 (通过 ' csw:ResponseHandler ')" #: ../../introduction.rst:115 msgid "Supported Harvest Resource Types are listed in :ref:`transactions`" msgstr "获取资源类型请参考: :ref:`transactions` 中列表" #: ../../introduction.rst:120 msgid "XML (default)" msgstr "XML (默认值)" #: ../../introduction.rst:121 msgid "JSON" msgstr "JSON代码" #: ../../introduction.rst:124 msgid "Supported Output Schemas" msgstr "支持的输出模式" #: ../../introduction.rst:126 msgid "Dublin Core" msgstr "Dublin Core" #: ../../introduction.rst:127 msgid "ISO 19139" msgstr "ISO 19139" #: ../../introduction.rst:128 msgid "FGDC CSDGM" msgstr "FGDC CSDGM" #: ../../introduction.rst:129 msgid "NASA DIF" msgstr "NASA DIF" #: ../../introduction.rst:130 msgid "Atom" msgstr "Atom" #: ../../introduction.rst:131 msgid "GM03" msgstr "GM03" #: ../../introduction.rst:134 msgid "Supported Sorting Functionality" msgstr "支持排序功能" #: ../../introduction.rst:136 msgid "ogc:SortBy" msgstr "ogc:SortBy" #: ../../introduction.rst:137 msgid "ascending or descending" msgstr "升序或降序" #: ../../introduction.rst:138 msgid "aspatial (queryable properties)" msgstr "非空间 (可查询属性)" #: ../../introduction.rst:139 msgid "spatial (geometric area)" msgstr "空间 (几何区域)" #: ../../introduction.rst:145 msgid "Full Text Search" msgstr "全文检索" #: ../../introduction.rst:147 msgid "csw:AnyText" msgstr "csw:任意文章" #: ../../introduction.rst:150 msgid "Geometry Operands" msgstr "几何操作" #: ../../introduction.rst:152 msgid "gml:Point" msgstr "gml:点" #: ../../introduction.rst:153 msgid "gml:LineString" msgstr "gml:线" #: ../../introduction.rst:154 msgid "gml:Polygon" msgstr "gml:面" #: ../../introduction.rst:155 msgid "gml:Envelope" msgstr "gml:外框" #: ../../introduction.rst:159 msgid "Coordinate transformations are supported" msgstr "坐标变换" #: ../../introduction.rst:162 msgid "Spatial Operators" msgstr "空间操作" #: ../../introduction.rst:164 msgid "BBOX" msgstr "BBOX" #: ../../introduction.rst:165 msgid "Beyond" msgstr "以外" #: ../../introduction.rst:166 msgid "Contains" msgstr "包括" #: ../../introduction.rst:167 msgid "Crosses" msgstr "交叉" #: ../../introduction.rst:168 msgid "Disjoint" msgstr "不相交" #: ../../introduction.rst:169 msgid "DWithin" msgstr "DWithin" #: ../../introduction.rst:170 msgid "Equals" msgstr "等于" #: ../../introduction.rst:171 msgid "Intersects" msgstr "相交" #: ../../introduction.rst:172 msgid "Overlaps" msgstr "重叠" #: ../../introduction.rst:173 msgid "Touches" msgstr "触动" #: ../../introduction.rst:174 msgid "Within" msgstr "内" #: ../../introduction.rst:177 msgid "Logical Operators" msgstr "逻辑运算符" #: ../../introduction.rst:179 msgid "Between" msgstr "两者之间" #: ../../introduction.rst:180 msgid "EqualTo" msgstr "等于" #: ../../introduction.rst:181 msgid "LessThanEqualTo" msgstr "小于等于" #: ../../introduction.rst:182 msgid "GreaterThan" msgstr "大于" #: ../../introduction.rst:183 msgid "Like" msgstr "似" #: ../../introduction.rst:184 msgid "LessThan" msgstr "小于" #: ../../introduction.rst:185 msgid "GreaterThanEqualTo" msgstr "大于等于" #: ../../introduction.rst:186 msgid "NotEqualTo" msgstr "不等于" #: ../../introduction.rst:187 msgid "NullCheck" msgstr "零检验" #: ../../introduction.rst:190 msgid "Functions" msgstr "功能" #: ../../introduction.rst:191 msgid "length" msgstr "长度" #: ../../introduction.rst:192 msgid "lower" msgstr "低于" #: ../../introduction.rst:193 msgid "ltrim" msgstr "ltrim" #: ../../introduction.rst:194 msgid "rtrim" msgstr "rtrim" #: ../../introduction.rst:195 msgid "trim" msgstr "trim" #: ../../introduction.rst:196 msgid "upper" msgstr "上部" #~ msgid "Python 2 and 3 compatible" #~ msgstr "Python 2和3兼容" ================================================ FILE: docs/locale/zh/LC_MESSAGES/json.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010-2015, Tom Kralidis This work is licensed under a # Creative Commons Attribution 4.0 International License # This file is distributed under the same license as the pycsw package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 11:25+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../json.rst:4 msgid "JSON Support" msgstr "对JSON的支持" #: ../../json.rst:7 msgid "OARec" msgstr "OARec" #: ../../json.rst:9 msgid "" "pycsw fully supports the OARec JSON conformance class, which is the " "default representation provided." msgstr "pycsw 完全支持 OARec JSON 一致性类,这是提供的默认表示。" #: ../../json.rst:13 msgid "CSW" msgstr "CSW" #: ../../json.rst:15 msgid "" "pycsw supports JSON support for ``DescribeRecord``, ``GetRecords`` and " "``GetRecordById`` requests. Adding ``outputFormat=application/json`` to " "your CSW request will return the response as a JSON representation." msgstr "" "pycsw 对JSON 的支持包括 ``DescribeRecord``, ``GetRecords`` 和 " "``GetRecordById`` 的请求。 在CSW请示中添加 ``outputFormat=application/" "json`` 会返回JSON格式表达的响应。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/license.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 13:33+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../license.rst:4 msgid "License" msgstr "授权" #: ../../../LICENSE.txt:2 msgid "The MIT License (MIT)" msgstr "MIT 许可证 (MIT)" #: ../../../LICENSE.txt:4 msgid "" "Copyright © 2010-2022 Tom Kralidis Copyright © 2011-2021 Angelos Tzotsos Copyright © 2012-2015 " "Adam Hinz Copyright © 2015-2021 Ricardo Garcia Silva" msgstr "" "版权 © 2010-2022 Tom Kralidis 版权所有 © 2011-2021 Angelos Tzotsos 版权所有 © 2012-2015 Adam " "Hinz 版权所有 © 2015-2021 Ricardo Garcia Silva" #: ../../../LICENSE.txt:9 msgid "" "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated " "documentation files (the \"Software\"), to deal in the Software without restriction, including without " "limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the " "Software, and to permit persons to whom the Software is furnished to do so, subject to the following " "conditions:" msgstr "" "特此授予权限,此软件是免费的,任何人都可获得本软件副本及相关文档文件 (\"软件\"),处理软件也不受限制,包括使" "用、 复制、 修改、 合并、 发布、 分发、 二次许可,或复印件转卖。给予授权的人应符合以下条件︰" #: ../../../LICENSE.txt:16 msgid "" "The above copyright notice and this permission notice shall be included in all copies or substantial portions " "of the Software." msgstr "上面的版权声明和许可声明应列入所有副本或软件的重要部分。" #: ../../../LICENSE.txt:19 msgid "" "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT " "LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO " "EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN " "AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE " "OR OTHER DEALINGS IN THE SOFTWARE." msgstr "" "该软件为“原版”,不做任何担保(明文或暗文的担保),包括对适销性、特定用途和非侵权性的保证。在任何情况下,不论是" "合同,侵权或其他,软件使用或其他交易。作者或版权持有者是法律责任的任何索赔、损害赔偿或其他责任。" #: ../../license.rst:9 msgid "Documentation" msgstr "说明文件" #: ../../license.rst:11 msgid "" "The documentation is released under the `Creative Commons Attribution 4.0 International (CC BY 4.0)`_ license." msgstr "该文档是 `知识共享署名4.0国际发布(CC BY 4.0)`_ 许可证下发的。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/migration-guide.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010-2015, Tom Kralidis This work is licensed under a # Creative Commons Attribution 4.0 International License # This file is distributed under the same license as the pycsw package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: pycsw 2.1-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 13:40+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../migration-guide.rst:4 msgid "pycsw Migration Guide" msgstr "pycsw 迁移指南" #: ../../migration-guide.rst:6 msgid "" "This page provides migration support across pycsw versions over time to " "help with pycsw change management." msgstr "此页面提供跨 pycsw 版本的迁移支持,以帮助进行 pycsw 变更管理。" #: ../../migration-guide.rst:10 msgid "pycsw 2.x to 3.0 Migration" msgstr "pycsw 2.x 到 3.0 的迁移" #: ../../migration-guide.rst:12 msgid "" "the default endpoint for standalone deployments is now powered by " "``pycsw/wsgi_flask.py`` (based on Flask) which supports ALL pycsw " "supported APIs. Make sure to use ``requirements-standalone.txt`` on top " "of ``requirements.txt`` to install Flask along with other standalone " "requirements" msgstr "" "独立部署的默认端点现在由 ``pycsw/wsgi_flask.py``(基于 Flask)提供支持," "它支持所有 pycsw 支持的 API。确保在 ``requirements.txt`` 之上使用 " "``requirements-standalone.txt`` 来安装 Flask 以及其他独立需求" #: ../../migration-guide.rst:13 msgid "" "the previously used ``pycsw/wsgi.py`` can still be used for CSW only " "deployments or for applications that need to integrate pycsw as a " "library (e.g. Django applications). PyPI installations still use " "``requirements.txt`` which does not install Flask by default" msgstr "" "以前使用的 ``pycsw/wsgi.py`` 仍然可以用于仅 CSW 部署或需要将 pycsw 集成为" "库的应用程序(例如 Django 应用程序)。PyPI 安装仍然使用``requirements." "txt``,默认情况下不安装 Flask" #: ../../migration-guide.rst:14 msgid "the default endpoint ``/`` is now OARec" msgstr "默认端点 ``/`` 现在是 OARec" #: ../../migration-guide.rst:15 msgid "the CSW endpoint is now ``/csw``" msgstr "CSW 端点现在是 ``/csw``" #: ../../migration-guide.rst:16 msgid "the OAI-PMH endpoint is now ``/oaipmh``" msgstr "OAI-PMH 端点现在是 ``/oaipmh``" #: ../../migration-guide.rst:17 msgid "the OpenSearch endpoint is now ``/opensearch``" msgstr "OpenSearch 端点现在是 ``/opensearch``" #: ../../migration-guide.rst:18 msgid "the SRU endpoint is now ``/sru``" msgstr "SRU 端点现在是 ``/sru``" #: ../../migration-guide.rst:19 msgid "the ``pycsw-admin.py`` syntax has been updated" msgstr "pycsw-admin.py 语法已更新" #: ../../migration-guide.rst:21 msgid "" "the ``-c`` flag has been replaced by subcommands (i.e. ``pycsw-admin.py -" "c load_records`` -> ``pycsw-admin.py load-records``)" msgstr "" "``-c`` 标志已被子命令替换(即 ``pycsw-admin.py -c load_records`` -> " "``pycsw-admin.py load-records``)" #: ../../migration-guide.rst:22 msgid "" "subcommands have been slugified (i.e. ``load_records`` -> ``load-" "records``)" msgstr "子命令已被 slugified(即 ``load_records`` -> ``load-records``)" #: ../../migration-guide.rst:23 msgid "consult ``--help`` to use the updated CLI syntax" msgstr "请参阅 ``--help`` 以使用更新的 CLI 语法" #: ../../migration-guide.rst:26 msgid "pycsw 1.x to 2.0 Migration" msgstr "pycsw 1.x到2.0的迁移" #: ../../migration-guide.rst:28 msgid "" "the default CSW version is now 3.0.0. CSW clients need to explicitly " "specify ``version=2.0.2`` for CSW 2 behaviour. Also, pycsw " "administrators can use a WSGI wrapper to the pycsw API to force " "``version=2.0.2`` on init of ``pycsw.server.Csw`` from the server. See :" "ref:`csw-support` for more information." msgstr "" "默认的 CSW 版本现在是 3.0.0。CSW 客户端需要为 CSW 2 行为显式指定 " "``version=2.0.2``。此外,pycsw 管理员可以使用 pycsw API 的 WSGI 包装器来" "强制从服务器初始化 ``pycsw.server.Csw`` 的``version=2.0.2``。更多信息参" "见:ref:`csw-support`。" #: ../../migration-guide.rst:33 msgid "" "``pycsw.server.Csw.dispatch_wsgi()`` previously returned the response " "content as a string. 2.0.0 introduces a compatability break to " "additionally return the HTTP status code along with the response as a " "list" msgstr "" "``pycsw.server.Csw.dispatch_wsgi()`` 之前将响应内容作为字符串返回。2.0.0 " "引入了一个兼容性中断,以额外返回 HTTP 状态代码以及响应作为列表" #: ../../migration-guide.rst:58 msgid "See :ref:`api` for more information." msgstr "更多信息参见:ref:`api`。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/oaipmh.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 13:43+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../oaipmh.rst:4 msgid "OAI-PMH Support" msgstr "OAI-PMH支持" #: ../../oaipmh.rst:6 msgid "" "pycsw supports the `The Open Archives Initiative Protocol for Metadata " "Harvesting`_ (OAI-PMH) standard." msgstr "" "pycsw 支持 `The Open Archives Initiative Protocol for Metadata " "Harvesting`_ (OAI-PMH) 标准。" #: ../../oaipmh.rst:8 msgid "" "OAI-PMH OpenSearch support is enabled by default. There are two ways to " "access OAI-PMH depending on the deployment pattern chosen." msgstr "" "OAI-PMH OpenSearch 支持默认启用。根据选择的部署模式,有两种访问 OAI-PMH " "的方法。" #: ../../oaipmh.rst:12 msgid "OARec deployment" msgstr "OARec 部署" #: ../../oaipmh.rst:19 msgid "CSW legacy deployment" msgstr "CSW 遗留部署" #: ../../oaipmh.rst:21 msgid "" "HTTP requests must be specified with ``mode=oaipmh`` in the base URL for " "OAI-PMH requests, e.g.:" msgstr "" "HTTP 请求必须在 OAI-PMH 请求的基本 URL 中使用 ``mode=oaipmh`` 指定,例" "如: " #: ../../oaipmh.rst:27 msgid "" "See http://www.openarchives.org/OAI/openarchivesprotocol.html for more " "information on OAI-PMH as well as request / reponse examples." msgstr "" "有关 OAI-PMH 以及请求/响应示例的更多信息,请参见 http://www.openarchives." "org/OAI/openarchivesprotocol.html。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/oarec-support.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010-2022, Tom Kralidis This work is licensed under a # Creative Commons Attribution 4.0 International License # This file is distributed under the same license as the pycsw package. # FIRST AUTHOR , 2022. # msgid "" msgstr "" "Project-Id-Version: pycsw 3.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 13:46+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../oarec-support.rst:4 msgid "OGC API - Records Support" msgstr "OGC API - 记录支持" #: ../../oarec-support.rst:7 msgid "Versions" msgstr "版本" #: ../../oarec-support.rst:9 msgid "" "pycsw supports `OGC API - Records - Part 1: Core, version 1.0`_ (OARec) " "by default." msgstr "" "pycsw 默认支持 `OGC API - Records - Part 1: Core, version 1.0`_ (OARec)。" #: ../../oarec-support.rst:12 msgid "Request Examples" msgstr "请求示例" #: ../../oarec-support.rst:14 msgid "" "As the OGC successor to CSW, OARec is a change in paradigm rooted in " "lowering the barrier to entry, being webby/of the web, and focusing on " "developer experience/adoption. JSON and HTML output formats are both " "supported via the ``f`` parameter." msgstr "" "作为 CSW 的 OGC 继任者,OARec 是一种范式变革,其根源在于降低准入门槛、成" "为 webby/web 并专注于开发人员体验/采用。JSON 和 HTML 输出格式都通过 " "``f`` 参数支持。" #: ../../oarec-support.rst:77 msgid "Virtual Collections" msgstr "虚拟馆藏" #: ../../oarec-support.rst:79 msgid "" "In OGC API - Records, pycsw's global repository is named `metadata:" "main`, which serves all metadata records from a given pycsw " "configuration." msgstr "" "在OGC API-Records中,pycsw的全局存储库名为 `metadata:main`,为给定pycsw配" "置中的所有元数据记录提供服务。" #: ../../oarec-support.rst:82 msgid "" "OGC API - Records support exposes parent metadata as distinct " "collections, reducing the barrier for users querying on a specific " "collection, for multiple collections. This functionality is implemented " "by default and does not require additional setup/configuration by the " "user. More information on this feature can be found in `RFC 10: OGC API " "- Records virtual collections support`_." msgstr "" "OGC API - 记录支持将父元数据公开为不同的集合,从而减少用户查询特定集合和" "多个集合的障碍。此功能是默认实现的,不需要用户进行额外的设置/配置。有关此" "功能的更多信息,请参阅 `RFC 10:OGC API - 记录虚拟集合支持`_。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/odc.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-12-17 17:33+0800\n" "PO-Revision-Date: 2018-12-05 10:32+0800\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.3.4\n" "Language: zh\n" "X-Generator: Poedit 2.0.6\n" #: ../../odc.rst:4 msgid "Open Data Catalog Configuration" msgstr "开放性数据目录配置" #: ../../odc.rst:6 msgid "" "Open Data Catalog (https://github.com/azavea/Open-Data-Catalog/) is an " "open data catalog based on Django, Python and PostgreSQL. It was " "originally developed for OpenDataPhilly.org, a portal that provides " "access to open data sets, applications, and APIs related to the " "Philadelphia region. The Open Data Catalog is a generalized version of " "the original source code with a simple skin. It is intended to display " "information and links to publicly available data in an easily searchable " "format. The code also includes options for data owners to submit data " "for consideration and for registered public users to nominate a type of " "data they would like to see openly available to the public." msgstr "" "开放数据目录(https://github.com/azavea/open-data-catalog/)是一种基于" "Django,Python和PostgreSQL的。它最初为opendataphilly.org(一个门户网站)" "提供开放的数据集,应用程序,并其API与费城地区相关。开放数据目录是一个通用" "的原始版本的源代码,其皮肤也很简易。它以显示信息为主,以检索便宜为主。该" "代码还包括数据所有者提交的数据代码,会指定一种数据类型供注册的公共用户参" "考,他们很乐意为公众公开信息。" #: ../../odc.rst:8 msgid "" "pycsw supports binding to an existing Open Data Catalog repository for " "metadata query. The binding is read-only (transactions are not in " "scope, as Open Data Catalog manages repository metadata changes in the " "application proper)." msgstr "" "pycsw绑定到用于元数据查询的现有公开数据目录库。此绑定是只读文件(交易不在" "范围内,Open Data Catalog在适当的应用程序中管理元数据库)" #: ../../odc.rst:11 msgid "Open Data Catalog Setup" msgstr "开放数据目录设置" #: ../../odc.rst:13 msgid "" "Open Data Catalog provides CSW functionality using pycsw out of the box " "(installing ODC will also install pycsw). Settings are defined in " "https://github.com/azavea/Open-Data-Catalog/blob/master/OpenDataCatalog/" "settings.py#L165." msgstr "" "开放数据目录提供了CSW功能,pycsw无需设置,开箱即用(安装ODC需安装pycsw)。" "设置在 https://github.com/azavea/Open-Data-Catalog/blob/master/OpenDataCatalog/settings.py#L165 中。" #: ../../odc.rst:15 msgid "" "ODC settings must ensure that ``REGISTRY_PYCSW['repository']['source']`` " "is set to``hypermap.search.pycsw_repository``." msgstr "" "ODC设置必须确保 ``REGISTRY_PYCSW['repository']['source']`` 被设置为" "``hypermap.search.pycsw_repository`` ." #: ../../odc.rst:17 msgid "" "At this point, pycsw is able to read from the Open Data Catalog " "repository using the Django ORM." msgstr "在这一点上,pycsw 可以用 Django 的 ORM 从数据目录库中读取。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/opensearch.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 13:56+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../opensearch.rst:4 msgid "OpenSearch Support" msgstr "OpenSearch支撑" #: ../../opensearch.rst:6 msgid "" "pycsw OpenSearch support is enabled by default. There are two ways to " "access OpenSearch depending on the deployment pattern chosen." msgstr "" "pycsw OpenSearch 支持默认启用。 根据选择的部署模式,有两种访问 " "OpenSearch 的方法。" #: ../../opensearch.rst:10 msgid "OARec deployment" msgstr "OARec 部署" #: ../../opensearch.rst:17 msgid "CSW legacy deployment" msgstr "CSW 遗留部署" #: ../../opensearch.rst:19 msgid "" "HTTP requests must be specified with ``mode=opensearch`` in the base URL " "for OpenSearch requests, e.g.:" msgstr "" "HTTP请求必须在OpenSearch要求的基准URL中指定 ``mode=opensearch`` ,例如:" #: ../../opensearch.rst:25 msgid "" "This will return the Description document which can then be " "`autodiscovered `_." msgstr "" "这将返回描述文档 `autodiscovered `_。" #: ../../opensearch.rst:28 msgid "OGC OpenSearch Geo and Time Extensions 1.0" msgstr "OGC OpenSearch 地理和时间扩展 1.0" #: ../../opensearch.rst:30 msgid "" "pycsw supports the `OGC OpenSearch Geo and Time Extensions 1.0`_ " "standard via the following conformance classes:" msgstr "" "pycsw 通过以下一致性类支持 `OGC OpenSearch Geo and Time Extensions 1.0`_ " "标准:" #: ../../opensearch.rst:32 msgid "" "Core (GeoSpatial Service) ``{searchTerms}``, ``{geo:box}``, " "``{startIndex}``, ``{count}``" msgstr "" "核心(地理空间服务) ``{searchTerms}`` , ``{geo:box}`` ,``{startIndex}" "`` , ``{count}``" #: ../../opensearch.rst:33 msgid "Temporal Search core ``{time:start}``, ``{time:end}``" msgstr "时间搜索核心 ``{time:start}`` , ``{time:end}``" #: ../../opensearch.rst:36 ../../opensearch.rst:50 msgid "Supported Query Parameters" msgstr "支持的查询参数" #: ../../opensearch.rst:38 msgid "``q``" msgstr "``q``" #: ../../opensearch.rst:39 msgid "``time``" msgstr "``time``" #: ../../opensearch.rst:40 msgid "``bbox``" msgstr "``bbox``" #: ../../opensearch.rst:43 msgid "OGC OpenSearch Extension for Earth Observation" msgstr "用于地球观测的 OGC OpenSearch 扩展" #: ../../opensearch.rst:45 msgid "" "pycsw supports the `OGC OpenSearch Extension for Earth Observation`_ " "standard via the following conformance classes:" msgstr "" "pycsw 通过以下一致性类支持 `OGC OpenSearch Extension for Earth " "Observation`_ 标准:" #: ../../opensearch.rst:47 msgid "Core" msgstr "核心" #: ../../opensearch.rst:52 msgid "``eo:cloudCover``" msgstr "``eo:cloudCover``" #: ../../opensearch.rst:53 msgid "``eo:instrument``" msgstr "``eo:instrument``" #: ../../opensearch.rst:54 ../../opensearch.rst:71 msgid "``eo:orbitDirection``" msgstr "``eo:orbitDirection``" #: ../../opensearch.rst:55 ../../opensearch.rst:70 msgid "``eo:orbitNumber``" msgstr "``eo:orbitNumber``" #: ../../opensearch.rst:56 msgid "``eo:platform``" msgstr "``eo:platform``" #: ../../opensearch.rst:57 ../../opensearch.rst:73 msgid "``eo:processingLevel``" msgstr "``eo:processingLevel``" #: ../../opensearch.rst:58 ../../opensearch.rst:69 msgid "``eo:productType``" msgstr "``eo:productType``" #: ../../opensearch.rst:59 msgid "``eo:sensorType``" msgstr "``eo:sensorType``" #: ../../opensearch.rst:60 ../../opensearch.rst:72 msgid "``eo:snowCover``" msgstr "``eo:snowCover``" #: ../../opensearch.rst:61 msgid "``eo:spectralRange``" msgstr "``eo:spectralRange``" #: ../../opensearch.rst:64 msgid "Mapping of non-19115 Queryable Mappings" msgstr "非 19115 可查询映射的映射" #: ../../opensearch.rst:66 msgid "" "The following queryables are implemented as faceted keywords given they " "are not implemented in generic geospatial metadata standards:" msgstr "" "鉴于以下可查询对象未在通用地理空间元数据标准中实现,它们被实现为分面关键" "字:" #: ../../opensearch.rst:75 msgid "" "This means metadata ingested into pycsw must have these fields " "implemented as keywords, as per the examples below:" msgstr "" "这意味着提取到 pycsw 中的元数据必须将这些字段实现为关键字,如下例所示:" #: ../../opensearch.rst:108 msgid "OpenSearch Temporal Queries Implementation" msgstr "OpenSearch 时态查询实现" #: ../../opensearch.rst:110 msgid "" "By default, pycsw's OpenSearch temporal support will query the Dublin " "Core ``dc:date`` property as a time instant/single point in time. To " "enable temporal extent search, set ``profiles=apiso`` which will query " "the temporal extents of a metadata record (``apiso:TempExtent_begin`` " "and ``apiso:TempExtent_end``)." msgstr "" "默认情况下,pycsw 的 OpenSearch 时间支持将查询 Dublin Core ``dc:date`` 属" "性作为时间瞬间/单个时间点。要启用时间范围搜索,请设置 " "``profiles=apiso``,它将查询元数据记录的时间范围( (``apiso:" "TempExtent_begin``和 ``apiso:TempExtent_end``)。" #: ../../opensearch.rst:114 msgid "" "At the HTTP API level, time is supported via either ``time=t1/t2`` or " "``start=t1&stop=t2``. If the ``time`` parameter is present, it will " "override the ``start`` and ``stop`` parameters respectively." msgstr "" "在 HTTP API 级别,时间通过 ``time=t1/t2`` 或 ``start=t1&stop=t2`` 来支" "持。如果存在 ``time`` 参数,将分别覆盖 ``start`` 和 ``stop`` 参数。" #~ msgid "OpenSearch support is enabled by default." #~ msgstr "OpenSearch启动是默认的。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/outputschemas.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-12-05 20:36+0800\n" "PO-Revision-Date: 2022-03-09 13:59+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.6.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../outputschemas.rst:4 msgid "Output Schema Plugins" msgstr "输出模式插件" #: ../../outputschemas.rst:7 msgid "Overview" msgstr "视图" #: ../../outputschemas.rst:9 msgid "" "pycsw allows for extending the implementation of output schemas to the " "core standard. outputschemas allow for a client to request metadata in " "a specific format (ISO, Dublin Core, FGDC, NASA DIF Atom and GM03 are " "default)." msgstr "" "pycsw 允许将输出模式的实现扩展到核心标准。输出模式允许客户端以特定格式请" "求元数据(默认为 ISO、都柏林核心、FGDC、NASA DIF Atom 和 GM03)。" #: ../../outputschemas.rst:11 msgid "" "All outputschemas must be placed in the ``pycsw/plugins/outputschemas`` " "directory." msgstr "所有输出模式必须放在 ``pycsw/plugins/outputschemas`` 目录中。" #: ../../outputschemas.rst:14 msgid "Requirements" msgstr "要求" #: ../../outputschemas.rst:29 msgid "Implementing a new outputschema" msgstr "实施新的输出架构" #: ../../outputschemas.rst:31 msgid "" "Create a file in ``pycsw/plugins/outputschemas``, which defines the " "following:" msgstr "" "在 ``pycsw/plugins/outputschemas`` 中创建一个文件,定义了以下内容:" #: ../../outputschemas.rst:33 msgid "" "``NAMESPACE``: the default namespace of the outputschema which will be " "advertised" msgstr "``NAMESPACE``:将被公布的输出模式的默认命名空间" #: ../../outputschemas.rst:34 msgid "``NAMESPACE``: dict of all applicable namespaces to outputschema" msgstr "``NAMESPACE``:输出模式的所有适用命名空间的字典" #: ../../outputschemas.rst:35 msgid "" "``XPATH_MAPPINGS``: dict of pycsw core queryables mapped to the " "equivalent XPath of the outputschema" msgstr " ``XPATH_MAPPINGS`` : pycsw 核心查询目录映射到输出空间的等效XPath" #: ../../outputschemas.rst:36 msgid "" "``write_record``: function which returns a record as an ``lxml.etree." "Element`` object" msgstr "``write_record``:将记录作为``lxml.etree.Element``对象返回的函数" #: ../../outputschemas.rst:38 msgid "" "Add the name of the file to ``__init__.py:__all__``. The new " "outputschema is now supported in pycsw." msgstr "" "将文件名添加到 ``__init__.py:__all__`` 。新的输出架构就在 pycsw中。" #: ../../outputschemas.rst:41 msgid "Testing" msgstr "测试" #: ../../outputschemas.rst:43 msgid "" "New outputschemas must add examples to the :ref:`tests` interface, which " "must provide example requests specific to the profile." msgstr "" "新的输出模式必须向 :ref:`tests` 接口添加示例,该接口必须提供特定于配置文" "件的示例请求。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/profiles.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-12-05 20:36+0800\n" "PO-Revision-Date: 2022-03-09 15:44+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.6.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../profiles.rst:4 msgid "Profile Plugins" msgstr "配置文件的插件" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:7 #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:35 #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:7 ../../profiles.rst:7 msgid "Overview" msgstr "视图" #: ../../profiles.rst:9 msgid "" "pycsw allows for the implementation of profiles to the core standard. " "Profiles allow specification of additional metadata format types (i.e. ISO " "19139:2007, NASA DIF, INSPIRE, etc.) to the repository, which can be queried " "and presented to the client. pycsw supports a plugin architecture which " "allows for runtime loading of Python code." msgstr "" "pycsw 使配置文件达到核心标准。配置文件允许其余元数据格式类型 (例如ISO " "19139:2007, NASA DIF, INSPIRE等) 特定到存储库,此配置文件可以查询,也可以提交" "给客户端。pycsw 支持插件体系结构,也支持运行时加载的 Python 代码。" #: ../../profiles.rst:11 msgid "All profiles must be placed in the ``pycsw/plugins/profiles`` directory." msgstr "所有的配置文件必须放在 ``pycsw/plugins/profiles`` 目录中。" #: ../../profiles.rst:14 msgid "Requirements" msgstr "要求" #: ../../profiles.rst:30 msgid "Abstract Base Class Definition" msgstr "抽象基类定义" #: ../../profiles.rst:32 msgid "" "All profile code must be instantiated as a subclass of ``profile.Profile``. " "Below is an example to add a ``Foo`` profile:" msgstr "" "配置文件的所有代码须实例化为 ``profile.Profile`` 。下面是一个添加配置文件 " "``Foo`` 的示例:" #: ../../profiles.rst:53 msgid "" "Your profile plugin class (``FooProfile``) must implement all methods as per " "``profile.Profile``. Profile methods must always return ``lxml.etree." "Element`` types, or ``None``." msgstr "" "配置插件类 ( ``FooProfile`` ) 必须按照 ``profile.Profile`` 完成所有的配置工" "作。配置文件方法须保持 ``lxml.etree.Element`` 类型或 ``None``。" #: ../../profiles.rst:56 msgid "Enabling Profiles" msgstr "启用配置文件" #: ../../profiles.rst:58 msgid "" "All profiles are disabled by default. To specify profiles at runtime, set " "the ``server.profiles`` value in the :ref:`configuration` to the name of the " "package (in the ``pycsw/plugins/profiles`` directory). To enable multiple " "profiles, specify as a comma separated value (see :ref:`configuration`)." msgstr "" "所有配置文件默认是不可用的。若要指定在运行时的配置文件,在参考文件 :ref:" "`configuration` 中设置 ``server.profiles`` 值(在 ``pycsw/plugins/profiles`` " "目录中)。若要启用多个配置文件,请指定值(以逗号分隔) (请参见 :ref:" "`configuration` )。" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:27 #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:27 ../../profiles.rst:61 msgid "Testing" msgstr "测试" #: ../../profiles.rst:63 msgid "" "Profiles must add examples to the :ref:`tests` interface, which must provide " "example requests specific to the profile." msgstr "" "配置文件必须添加到 :ref:`tests` 接口,此接口须提供特定于该配置文件的示例请求。" #: ../../profiles.rst:66 msgid "Supported Profiles" msgstr "支持的配置文件" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:4 msgid "ISO Metadata Application Profile (1.0.0)" msgstr "ISO 元数据应用程序配置文件 (1.0.0)" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:8 msgid "" "The ISO Metadata Application Profile (APISO) is a profile of CSW 2.0.2 which " "enables discovery of geospatial metadata following ISO 19139:2007 and ISO " "19119:2005/PDAM 1." msgstr "" "ISO 元数据应用程序配置文件 (APISO) 是CSW 2.0.2的配置文件,是继地理空间元数据 " "ISO 19139:2007 和 ISO 19119:2005 之后开发的文件。" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:11 #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:40 #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:11 msgid "Configuration" msgstr "配置" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:13 #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:13 msgid "No extra configuration is required." msgstr "不需要其余配置。" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:16 #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:16 msgid "Querying" msgstr "查询" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:18 msgid "**typename**: ``gmd:MD_Metadata``" msgstr "**类型名**:``gmd:MD_Metadata``" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:19 msgid "**outputschema**: ``http://www.isotc211.org/2005/gmd``" msgstr "**输出模式**:``http://www.isotc211.org/2005/gmd``" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:22 msgid "Enabling APISO Support" msgstr "启用 APISO 支持" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:24 msgid "" "To enable APISO support, add ``apiso`` to ``server.profiles`` as specified " "in :ref:`configuration`." msgstr "" "要启用 APISO 支持,请将 ``apiso`` 添加到 ``server.profiles`` 中,如 :ref:" "`configuration` 中指定的那样。" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:29 msgid "" "A testing interface is available in ``tests/index.html`` which contains tests " "specific to APISO to demonstrate functionality. See :ref:`tests` for more " "information." msgstr "" "``tests/index.html`` 中提供了一个测试接口,其中包含特定于 APISO 的测试以演示功" "能。更多信息参见:ref:`tests`。" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:32 msgid "INSPIRE Extension" msgstr "启发扩展" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:37 msgid "" "APISO includes an extension for enabling `INSPIRE Discovery Services 3.0`_ " "support. To enable the INSPIRE extension to APISO, create a ``[metadata:" "inspire]`` section in the main configuration with ``enabled`` set to ``true``." msgstr "" "APISO 包括启用 `INSPIRE Discovery Services 3.0`_ 的扩展。 若要启用 INSPIRE扩展" "到 APISO,需要用 ``enabled`` set to ``true`` 在主要的配置中创建 ``[metadata:" "inspire]`` 部分。" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:42 msgid "**[metadata:inspire]**" msgstr "**[元数据:inspire]**" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:44 msgid "" "**enabled**: whether to enable the INSPIRE extension (``true`` or ``false``)" msgstr "**启用**: 是否启用INSPIRE扩展 ( ``true`` 或 ``false``)" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:45 msgid "" "**languages_supported**: supported languages (see http://inspire.ec.europa.eu/" "schemas/common/1.0/enums/enum_eng.xsd, simpleType ``euLanguageISO6392B``)" msgstr "" "**支持的语言**: (见 http://inspire.ec.europa.eu/schemas/common/1.0/enums/" "enum_eng.xsd ,simpleType ``euLanguageISO6392B`` )" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:46 msgid "" "**default_language**: the default language (see http://inspire.ec.europa.eu/" "schemas/common/1.0/enums/enum_eng.xsd, simpleType ``euLanguageISO6392B``)" msgstr "" "**默认语言**:(见 http://inspire.ec.europa.eu/schemas/common/1.0/enums/" "enum_eng.xsd,simpleType ' euLanguageISO6392B ')" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:47 msgid "**date**: date of INSPIRE metadata offering (in `ISO 8601`_ format)" msgstr "**date**: INSPIRE元数据的日期 ( `ISO 8601`_ 格式)" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:48 msgid "" "**gemet_keywords**: a comma-seperated keyword list of `GEMET INSPIRE theme " "keywords`_ about the service (see http://inspire.ec.europa.eu/schemas/" "common/1.0/enums/enum_eng.xsd, complexType ``inspireTheme_eng``)" msgstr "" "**gemet_keywords**: 关于服务的,以逗号分隔的关键字列表 `GEMET INSPIRE 主题关键" "词`_ (参见 http://inspire.ec.europa.eu/schemas/common/1.0/enums/enum_eng." "xsd,complexType ``inspireTheme_eng`` )" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:49 msgid "" "**conformity_service**: the level of INSPIRE conformance for spatial data " "sets and services (``conformant``, ``notConformant``, ``notEvaluated``)" msgstr "" "conformity_service: 以空间数据集和服务 (``conformant``, ``notConformant``, " "``notEvaluated``)为目标的INSPIRE级别" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:50 msgid "" "**contact_organization**: the organization name responsible for the INSPIRE " "metadata" msgstr "contact_organization: 负责 INSPIRE元数据的组织名称" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:51 msgid "" "**contact_email**: the email address of entity responsible for the INSPIRE " "metadata" msgstr "contact_email: 负责 INSPIRE元数据实体的电子邮件地址" #: ../../../pycsw/plugins/profiles/apiso/docs/apiso.rst:52 msgid "" "**temp_extent**: temporal extent of the service (in `ISO 8601`_ format). " "Either a single date (i.e. ``yyyy-mm-dd``), or an extent (i.e. ``yyyy-mm-dd/" "yyyy-mm-dd``)" msgstr "" "**temp_extent**: ( `ISO 8601`_ 格式)服务时间。 单个日期 ( ``yyyy-mm-dd`` ) " "或多数以 ( ``yyyy-mm-dd/yyyy-mm-dd`` )" #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:4 msgid "CSW-ebRIM Registry Service - Part 1: ebRIM profile of CSW" msgstr "CSW-ebRIM注册服务-第一部分: CSW的ebRIM 配置文件" #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:8 msgid "" "The CSW-ebRIM Registry Service is a profile of CSW 2.0.2 which enables " "discovery of geospatial metadata following the ebXML information model." msgstr "" "CSW-ebRIM注册服务是CSW 2.0.2的配置文件,是继ebXML 信息模型之后的地理空间元数据" "配置文件。" #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:18 msgid "**typename**: ``rim:RegistryObject``" msgstr "类型名称: ' rim: RegistryObject '" #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:19 msgid "**outputschema**: ``urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0``" msgstr "输出模式: ' urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0'" #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:22 msgid "Enabling ebRIM Support" msgstr "启用 ebRIM 支持" #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:24 msgid "" "To enable ebRIM support, add ``ebrim`` to ``server.profiles`` as specified " "in :ref:`configuration`." msgstr "" "若要启用 ebRIM 支持,需添加 ``ebrim`` 到 ``server.profiles`` ,以 作为指定的 :" "ref:`configuration`。" #: ../../../pycsw/plugins/profiles/ebrim/docs/ebrim.rst:29 msgid "" "A testing interface is available in ``tests/index.html`` which contains tests " "specific to ebRIM to demonstrate functionality. See :ref:`tests` for more " "information." msgstr "" "测试接口在 ``tests/index.html`` 可用,其包含特定于ebRIM演示功能的测试。请参" "见 :ref:`tests` 及其它更多信息。" #~ msgid "typename" #~ msgstr "类型名称" #~ msgid "outputschema" #~ msgstr "输出模式" ================================================ FILE: docs/locale/zh/LC_MESSAGES/repofilters.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 14:22+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../repofilters.rst:4 msgid "Repository Filters" msgstr "存储库中的筛选器" #: ../../repofilters.rst:6 msgid "" "pycsw has the ability to perform server side repository / database filters as a " "means to mask all requests to query against a specific subset of the metadata " "repository, thus providing the ability to deploy multiple pycsw instances " "pointing to the same database in different ways via the ``repository.filter`` " "configuration option." msgstr "" "pycsw 能够执行服务器端存储库/数据库过滤器,以屏蔽所有查询以查询元数据存储库的特" "定子集的请求,从而提供通过 ` 以不同方式部署指向同一数据库的多个 pycsw 实例的能" "力 `repository.filter` 配置选项。" #: ../../repofilters.rst:8 msgid "" "Repository filters are a convenient way to subset your repository at the server " "level without the hassle of creating proper database views. For large " "repositories, it may be better to subset at the database level for performance." msgstr "" "存储库过滤器是一种在服务器级别对存储库进行子集化的便捷方式,无需创建适当的数据库" "视图。对于大型存储库,最好在数据库级别进行子集化以提高性能。" #: ../../repofilters.rst:11 msgid "Scenario: One Database, Many Views" msgstr "场景 ︰ 一个数据库,很多种视角" #: ../../repofilters.rst:13 msgid "Imagine a sample database table of records (subset below for brevity):" msgstr "想象一个示例数据库记录表(为简洁起见,下面的子集):" #: ../../repofilters.rst:1 msgid "identifier" msgstr "标识符" #: ../../repofilters.rst:1 msgid "parentidentifier" msgstr "父标识符" #: ../../repofilters.rst:1 msgid "title" msgstr "标题" #: ../../repofilters.rst:1 msgid "abstract" msgstr "摘要" #: ../../repofilters.rst:1 msgid "1" msgstr "1" #: ../../repofilters.rst:1 msgid "33" msgstr "33" #: ../../repofilters.rst:1 msgid "foo1" msgstr "foo1" #: ../../repofilters.rst:1 msgid "bar1" msgstr "bar1" #: ../../repofilters.rst:1 msgid "2" msgstr "2" #: ../../repofilters.rst:1 msgid "foo2" msgstr "foo2" #: ../../repofilters.rst:1 msgid "bar2" msgstr "bar2" #: ../../repofilters.rst:1 msgid "3" msgstr "3" #: ../../repofilters.rst:1 msgid "55" msgstr "55" #: ../../repofilters.rst:1 msgid "foo3" msgstr "foo3" #: ../../repofilters.rst:1 msgid "bar3" msgstr "bar3" #: ../../repofilters.rst:1 msgid "4" msgstr "4" #: ../../repofilters.rst:1 msgid "5" msgstr "5" #: ../../repofilters.rst:1 msgid "21" msgstr "21" #: ../../repofilters.rst:1 msgid "foo5" msgstr "foo5" #: ../../repofilters.rst:1 msgid "bar5" msgstr "bar5" #: ../../repofilters.rst:1 msgid "foo6" msgstr "foo6" #: ../../repofilters.rst:1 msgid "bar6" msgstr "bar6" #: ../../repofilters.rst:25 msgid "" "A default pycsw instance (with no ``repository.filters`` option) will always " "process requests against the entire table. So a CSW `GetRecords` filter like:" msgstr "" "默认的 pycsw 实例(没有 ``repository.filters`` 选项)将始终处理针对整个表的请" "求。因此 CSW `GetRecords` 过滤器如:" #: ../../repofilters.rst:36 msgid "...will return:" msgstr "...将返回:" #: ../../repofilters.rst:44 msgid "" "Suppose you wanted to deploy another pycsw instance which serves metadata from " "the same database, but only from a specific subset. Here we set the " "``repository.filter`` option:" msgstr "" "假设想部署另一个 pycsw 实例,该实例提供来自同一数据库的元数据,但仅来自特定子" "集。在这里,设置了 ``repository.filter`` 选项:" #: ../../repofilters.rst:52 ../../repofilters.rst:67 msgid "" "The same CSW `GetRecords` filter as per above then yields the following results:" msgstr "依上述所说,同一CSW `GetRecords` 过滤器将得到以下结果:" #: ../../repofilters.rst:59 msgid "Another example:" msgstr "另一个例子:" #: ../../repofilters.rst:74 msgid "" "The ``repository.filter`` option accepts all core queryables set in the pycsw " "core model (see ``pycsw.config.StaticContext.md_core_model`` for the complete " "list)." msgstr "" "该 ``repository.filter`` 选项功能是在pycsw核心模式中接收所有核心查询设置(见" "``pycsw.config.StaticContext.md_core_model`` 的完整列表)。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/repositories.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010-2015, Tom Kralidis This work is licensed under a # Creative Commons Attribution 4.0 International License # This file is distributed under the same license as the pycsw package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: pycsw 2.1-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 14:23+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../repositories.rst:4 msgid "Repository Plugins" msgstr "库插件" #: ../../repositories.rst:7 msgid "Overview" msgstr "概述" #: ../../repositories.rst:9 msgid "" "pycsw allows for the implementation of custom repositories in order to connect to a backend different from the pycsw's default. This is especially useful when downstream applications manage their " "own metadata model/database/document store and want pycsw to connect to it directly instead of using pycsw's default model, thus creating duplicate repositories which then require syncronization/" "accounting. Repository plugins enable a single metadata backend which is independent from the pycsw setup. pycsw thereby becomes a pure wrapper around a given backend in providing OARec, CSW and " "other APIs atop a given application." msgstr "" "pycsw 允许实现自定义存储库,以便连接到与 pycsw 默认不同的后端。当下游应用程序管理自己的元数据模型/数据库/文档存储并希望 pycsw 直接连接到它而不是使用 pycsw 的默认模型时,这尤其有用,从而创建了需要同步/" "记帐的重复存储库。存储库插件启用独立于 pycsw 设置的单个元数据后端。因此,pycsw 成为给定后端的纯包装器,在给定应用程序之上提供 OARec、CSW 和其他 API。" #: ../../repositories.rst:11 msgid "All outputschemas must be placed in the ``pycsw/plugins/outputschemas`` directory." msgstr "所有输出模式必须放在 ``pycsw/plugins/outputschemas`` 目录中。" #: ../../repositories.rst:14 msgid "Requirements" msgstr "要求" #: ../../repositories.rst:16 msgid "Repository plugins:" msgstr "存储库插件:" #: ../../repositories.rst:18 msgid "can be developed and referenced / connected external to pycsw" msgstr "可以在PYCSW外部开发和引用/连接" #: ../../repositories.rst:19 msgid "must be accessible within the ``PYTHONPATH`` of a given application" msgstr "必须在给定应用程序的 ``PYTHONPATH`` 内访问" #: ../../repositories.rst:20 msgid "must implement pycsw's ``pycsw.core.repository.Repository`` properties and methods" msgstr "必须实现 pycsw's ``pycsw.core.repository.Repository`` 属性和方法" #: ../../repositories.rst:21 msgid "must be specified in the pycsw :ref:`configuration` as a class reference (e.g. ``path.to.repo_plugin.MyRepository``)" msgstr "必须在 pycsw :ref:`configuration` 中指定为类引用(例如(e.g. ``path.to.repo_plugin.MyRepository`` )" #: ../../repositories.rst:22 msgid "must minimally implement the ``query_insert``, ``query_domain``, ``query_ids``, and ``query`` methods" msgstr "必须最低限度地实现 ``query_insert``, ``query_domain``, ``query_ids``, and ``query`` 方法" #: ../../repositories.rst:25 msgid "Configuration" msgstr "配置" #: ../../repositories.rst:27 msgid "set pycsw's ``repository.source`` setting to the class which implements the custom repository:" msgstr "设置pycsw的``repository.source``,成为实现自定义存储库的类:" ================================================ FILE: docs/locale/zh/LC_MESSAGES/sitemaps.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-23 21:42+0800\n" "PO-Revision-Date: 2022-03-09 14:24+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 3.0.1\n" #: ../../sitemaps.rst:4 msgid "XML Sitemaps" msgstr "XML网站地图" #: ../../sitemaps.rst:6 msgid "`XML Sitemaps`_ can be generated by running:" msgstr "`XML Sitemaps`_ 可以通过运行生成:" #: ../../sitemaps.rst:12 msgid "" "The ``sitemap.xml`` file should be saved to an an area on your web server " "(parallel to or above your pycsw install location) to enable web crawlers " "to index your repository." msgstr "" "``sitemap.xml`` 文件应该保存到网络服务器上的一个区域(平行于或高于你的 " "pycsw 安装位置),以使网络爬虫能够索引你的存储库。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/soap.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 14:26+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../soap.rst:4 msgid "SOAP" msgstr "简单对象访问协议" #: ../../soap.rst:6 msgid "" "pycsw's CSW implementation supports handling of SOAP encoded requests and " "responses as per subclause 10.3.2 of OGC:CSW 2.0.2. SOAP request examples can " "be found in ``tests/index.html``." msgstr "" "pycsw 的 CSW 实现支持按照 OGC:CSW 2.0.2 的子条款 10.3.2 处理 SOAP 编码的请求和响" "应。SOAP 请求示例可以在 ``tests/index.html`` 中找到。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/sru.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 14:28+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../sru.rst:4 msgid "Search/Retrieval via URL (SRU) Support" msgstr "通过 URL (SRU) 支持搜索/检索" #: ../../sru.rst:6 msgid "" "pycsw supports the `Search/Retrieval via URL`_ search protocol " "implementation as per subclause 8.4 of the OpenGIS Catalogue Service " "Implementation Specification." msgstr "" "根据 OpenGIS 目录服务实现规范的第 8.4 条,pycsw 支持 `通过 URL 搜索/检索`_ " "搜索协议实现。" #: ../../sru.rst:8 msgid "" "SRU support is enabled by default. There are two ways to access SRU " "depending on the deployment pattern chosen." msgstr "SRU 支持默认启用。根据所选的部署模式,有两种访问 SRU 的方法。" #: ../../sru.rst:12 msgid "OARec deployment" msgstr "OARec 部署" #: ../../sru.rst:19 msgid "CSW legacy deployment" msgstr "CSW 遗留部署" #: ../../sru.rst:21 msgid "" "HTTP GET requests must be specified with ``mode=sru`` for SRU requests, e." "g.:" msgstr "对于 SRU 请求,HTTP GET 请求必须使用 ``mode=sru`` 指定,例如:" #: ../../sru.rst:27 msgid "" "See https://www.loc.gov/standards/sru/misc/simple.html for example SRU " "requests." msgstr "" "有关 SRU 请求的示例,请参见 https://www.loc.gov/standards/sru/misc/simple." "html。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/stac.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010-2022, Tom Kralidis This work is licensed under a # Creative Commons Attribution 4.0 International License # This file is distributed under the same license as the pycsw package. # FIRST AUTHOR , 2022. # msgid "" msgstr "" "Project-Id-Version: pycsw 3.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 14:31+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../stac.rst:4 msgid "SpatioTemporal Asset Catalog (STAC) API Support" msgstr "时空资产目录 (STAC) API 支持" #: ../../stac.rst:7 msgid "Versions" msgstr "版本" #: ../../stac.rst:9 msgid "" "pycsw supports `SpatioTemporal Asset Catalog API version v1.0.0`_ " "by default." msgstr "" "pycsw 默认支持 `SpatioTemporal Asset Catalog API version v1.0.0`_。" #: ../../stac.rst:11 msgid "pycsw implements provides STAC support in the following manner:" msgstr "pycsw 实现以下列方式提供 STAC 支持:" #: ../../stac.rst:13 msgid "a pycsw repository is equivalent to a STAC collection" msgstr "pycsw 存储库相当于一个 STAC 集合" #: ../../stac.rst:14 msgid "pycsw metadata records are equivalent to STAC items" msgstr "pycsw 元数据记录等同于 STAC 项" #: ../../stac.rst:16 msgid "" "The STAC specification is designed with the same principles as OGC API - " "Records." msgstr "STAC 规范的设计原则与 OGC API - Records 相同。" #: ../../stac.rst:19 msgid "Request Examples" msgstr "请求示例" #: ../../stac.rst:21 msgid "" "As the OGC successor to CSW, OARec is a change in paradigm rooted in " "lowering the barrier to entry, being webby/of the web, and focusing on " "developer experience/adoption. JSON and HTML output formats are both " "supported via the ``f`` parameter." msgstr "" "作为 CSW 的 OGC 继任者,OARec 是一种范式变革,其根源在于降低准入门槛、成" "为 webby/web 并专注于开发人员体验/采用。JSON 和 HTML 输出格式都通过 " "``f`` 参数支持。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/support.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 14:32+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../support.rst:4 msgid "Support" msgstr "技术支持" #: ../../support.rst:7 msgid "Community" msgstr "团队" #: ../../support.rst:9 msgid "" "Please see the `Community`_ page for information on the pycsw community, " "getting support, and how to get involved." msgstr "" "有关 pycsw 社区、获得支持以及如何参与的信息,请参阅 `Community`_ 页面。" ================================================ FILE: docs/locale/zh/LC_MESSAGES/testing.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-10 10:12+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../testing.rst:4 msgid "Testing" msgstr "测试" #: ../../testing.rst:6 msgid "pycsw uses `pytest`_ for managing its automated tests." msgstr "pycsw 使用 `pytest`_ 来管理其自动化测试。" #: ../../testing.rst:9 msgid "OGC API - Records" msgstr "OGC API - 记录" #: ../../testing.rst:11 msgid "" "Tests for OGC API - Records are located in ``tests/unittests/test_oarec.py``. " "They can be run as follows:" msgstr "" "OGC API 的测试 - 记录位于 ``tests/unittests/test_oarec.py`` 中。可以按如下方式运" "行:" #: ../../testing.rst:20 msgid "OGC CSW" msgstr "OGC CSW" #: ../../testing.rst:22 msgid "" "There are a number of test suites that perform mostly functional testing. These " "tests ensure that pycsw is compliant with the various supported standards. There " "is also a growing set of unit tests. These focus on smaller scope testing, in " "order to verify that individual bits of code are working as expected." msgstr "" "有许多测试套件主要执行功能测试。这些测试确保 pycsw 符合各种支持的标准。还有越来越" "多的单元测试。专注于较小范围的测试,以验证各个代码位是否按预期工作。" #: ../../testing.rst:28 msgid "" "Tests can be run locally as part of the development cycle. They are also run on " "pycsw's `GitHub Actions`_ continuous integration setup against all pushes and " "pull requests to the code repository." msgstr "" "测试可以作为开发周期的一部分在本地运行。它们还在 pycsw 的 `GitHub Actions`_ 持续" "集成设置上运行,针对所有对代码存储库的推送和拉取请求。" #: ../../testing.rst:36 msgid "OGC CITE" msgstr "OGC引用" #: ../../testing.rst:38 msgid "" "In addition to pycsw's own tests, all public releases are also tested via the " "OGC `Compliance & Interoperability Testing & Evaluation Initiative`_ (CITE). The " "pycsw `wiki`_ documents CITE testing procedures and status." msgstr "" "除了 pycsw 自己的测试之外,所有公开版本还通过 OGC `Compliance & Interoperability " "Testing & Evaluation Initiative`_ (CITE) 进行测试。pycsw `wiki`_ 记录了 CITE 测试" "程序和状态。" #: ../../testing.rst:44 msgid "Functional test suites" msgstr "功能测试套件" #: ../../testing.rst:46 msgid "" "Currently most of pycsw's tests are `functional tests`_. This means that each " "test case is based on the requirements mandated by the specifications of the " "various standards that pycsw implements. These tests focus on making sure that " "pycsw works as expected." msgstr "" "目前大部分 pycsw 的测试都是`功能测试`_。这意味着每个测试用例都基于 pycsw 实施的各" "种标准的规范所规定的要求。这些测试的重点是确保 pycsw 按预期工作。" #: ../../testing.rst:51 msgid "Each test follows the same workflow:" msgstr "每个测试都遵循相同的工作流程:" #: ../../testing.rst:53 msgid "" "Create a new pycsw instance with a custom configuration and data repository for " "each suite of tests;" msgstr "为每个测试套件创建一个新的pycsw实例,该实例具有自定义配置和数据存储库;" #: ../../testing.rst:56 msgid "Perform a series of GET and POST requests to the running pycsw instance;" msgstr "对正在运行的 pycsw 实例执行一系列 GET 和 POST 请求;" #: ../../testing.rst:58 msgid "" "Compare the results of each request against a previously prepared expected " "result. If the test result matches the expected outcome the test passes, " "otherwise it fails." msgstr "" "将每个请求的结果与预先准备的预期结果进行比较。如果测试结果与预期结果一致,则测试" "通过,否则失败." #: ../../testing.rst:63 msgid "" "A number of different test suites exist under ``tests/functionaltests/suites``. " "Each suite specifies the following structure:" msgstr "" "在 ``tests/functionaltests/suites`` 下存在许多不同的测试套件。每个套件指定以下结" "构:" #: ../../testing.rst:66 msgid "" "A mandatory ``default.yml`` file with the pycsw configuration that must be used " "by the test suite;" msgstr "测试套件必须使用的带有 pycsw 配置的强制 ``default.yml`` 文件;" #: ../../testing.rst:69 msgid "" "A mandatory ``expected/`` directory containing the expected results for each " "request;" msgstr "包含每个请求的预期结果的强制性 ``expected/`` 目录;" #: ../../testing.rst:72 msgid "" "An optional ``data/`` directory that contains ``.xml`` files with testing data " "that is to be loaded into the suite's database before running the tests. The " "presence of this directory and its contents have the following meaning for tests:" msgstr "" "一个可选的 ``data/`` 目录,包含 ``.xml`` 文件,其中包含要在运行测试之前加载到套件" "数据库中的测试数据。该目录及其内容的存在对测试具有以下意义:" #: ../../testing.rst:77 msgid "" "If ``data/`` directory is present and contains files, they will be loaded into a " "new database for running the tests of the suite;" msgstr "" "如果 ``data/`` 目录存在并且包含文件,它们将被加载到一个新的数据库中,用于运行套件" "的测试;" #: ../../testing.rst:80 msgid "" "If ``data/`` directory is present and does not contain any data files, a new " "empty database is used in the tests;" msgstr "如果存在 ``data/`` 目录并且不包含任何数据文件,则在测试中使用新的空数据库;" #: ../../testing.rst:83 msgid "" "If ``data/`` directory is absent, the suite will use a database populated with " "test data from the ``CITE`` suite." msgstr "" "如果 ``data/`` 目录不存在,套件将使用填充有 ``CITE`` 套件的测试数据的数据库." #: ../../testing.rst:86 msgid "" "An optional ``get/requests.txt`` file that holds request parameters used for " "making HTTP GET requests." msgstr "" "一个可选的 ``get/requests.txt`` 文件,其中保存用于生成HTTP GET请求的请求参数." #: ../../testing.rst:89 msgid "Each line in the file must be formatted with the following scheme:" msgstr "文件中的每一行必须用以下方案格式化:" #: ../../testing.rst:91 msgid "test_id,request_query_string" msgstr "test_id,request_query_string" #: ../../testing.rst:93 ../../testing.rst:111 msgid "For example:" msgstr "例如:" #: ../../testing.rst:95 msgid "TestGetCapabilities,service=CSW&version=2.0.2&request=GetCapabilities" msgstr "TestGetCapabilities,service=CSW&version=2.0.2&request=GetCapabilities" #: ../../testing.rst:97 msgid "" "When tests are run, the *test_id* is used for naming each test and for finding " "the expected result." msgstr "运行测试时,*test_id* 用于命名每个测试并查找预期结果。" #: ../../testing.rst:100 msgid "" "An optional ``post/`` directory that holds ``.xml`` files used for making HTTP " "POST requests" msgstr "一个可选的 ``post/`` 目录,它包含用于制作HTTP POST请求的 ``.xml`` 文件" #: ../../testing.rst:105 msgid "Test identifiers" msgstr "测试标识符" #: ../../testing.rst:107 msgid "Each test has an identifier that is built using the following rule:" msgstr "每个测试都有一个标识符,该标识符是使用以下规则构建的:" #: ../../testing.rst:109 msgid "[__]" msgstr "[__]" #: ../../testing.rst:113 msgid "test_suites[default_post_GetRecords-end]" msgstr "test_suites[default_post_GetRecords-end]" #: ../../testing.rst:117 msgid "Functional tests' implementation" msgstr "功能测试的实现" #: ../../testing.rst:119 msgid "" "Functional tests are generated for each suite directory present under `tests/" "functionaltests/suites`. Test generation uses pytest's `pytest_generate_tests`_ " "function. This function is implemented in `tests/functionaltests/conftest.py`. " "It provides an automatic parametrization of the `tests/functionaltests/" "test_suites_functional:test_suites` function. This parametrization causes the " "generation of a test for each of the GET and POST requests defined in a suite's " "directory." msgstr "" "对 `tests/functionaltests/suites` 下出现的每个套件目录生成功能测试。测试生成使用" "pytest's `pytest_generate_tests`_ 功能。这个功能在 `tests/functionaltests/" "conftest.py` 中实现。它提供了 `tests/functionaltests/test_suites_functional:" "test_suites` 功能的自动参数化。此参数化导致为套件目录中定义的每个 GET 和 POST 请" "求生成测试。" #: ../../testing.rst:129 msgid "Adding New Tests" msgstr "添加新测试" #: ../../testing.rst:131 msgid "To add tests to an existing suite:" msgstr "在现有套件中添加测试:" #: ../../testing.rst:133 msgid "" "for HTTP POST tests, add XML documents to ``tests/functionaltests/suites//" "post``" msgstr "" "对于HTTP POST测试,在 ``tests/functionaltests/suites//post`` 添加XML文档" #: ../../testing.rst:135 msgid "" "for HTTP GET tests, add tests (one per line) to ``tests/functionaltests/suites/" "/get/requests.txt``" msgstr "" "对于HTTP GET测试,在 ``tests/functionaltests/suites//get/requests.txt`` 中" "添加测试(每行的第一项)" #: ../../testing.rst:138 msgid "To add a new test suite:" msgstr "添加新的测试套件:" #: ../../testing.rst:140 msgid "" "Create a new directory under ``tests/functionaltests/suites`` (e.g. ``foo``)" msgstr "在 ``tests/functionaltests/suites`` (如 ``foo`` )下创建一个新目录" #: ../../testing.rst:141 msgid "Create a new configuration in ``tests/suites/foo/default.yml``" msgstr "在 ``tests/suites/foo/default.yml`` 创建一个新的配置" #: ../../testing.rst:142 msgid "Populate HTTP POST requests in ``tests/suites/foo/post``" msgstr "在 ``tests/suites/foo/post`` 填写HTTP POST请求" #: ../../testing.rst:143 msgid "Populate HTTP GET requests in ``tests/suites/foo/get/requests.txt``" msgstr "在 ``tests/suites/foo/get/requests.txt`` 填写HTTP GET请求" #: ../../testing.rst:144 msgid "" "If the test suite requires test data, create ``tests/suites/foo/data`` and store " "XML files there. These will be inserted in the test catalogue at test runtime" msgstr "" "如果需要测试组件的测试数据,创建 ``tests/suites/foo/data``,以存储XML文件。这会在" "运行时插入到测试目录" #: ../../testing.rst:147 msgid "Use pytest or tox as described above in order to run the tests" msgstr "使用如上所述的pytest或者 tox来运行测试" #: ../../testing.rst:149 msgid "" "The new test suite database will be created automatically and used as part of " "tests." msgstr "新的测试套件数据库将自动创建,并且会成为测试的一部分。" #: ../../testing.rst:154 msgid "Unit tests" msgstr "单元测试" #: ../../testing.rst:156 msgid "" "pycsw also features unit tests. These deal with testing the expected behaviour " "of individual functions." msgstr "pycsw 还具有单元测试功能。这些处理测试单个函数的预期行为。" #: ../../testing.rst:159 msgid "" "The usual implementation of unit tests is to import the function/method under " "test, run it with a set of known arguments and assert that the result matches " "the expected outcome." msgstr "" "单元测试的通常实现是导入被测函数/方法,使用一组已知参数运行它,并断言结果与预期结" "果匹配。" #: ../../testing.rst:163 msgid "Unit tests are defined in `pycsw/tests/unittests/`." msgstr "单元测试在 `pycsw/tests/unittests/` 中定义。" #: ../../testing.rst:165 msgid "" "pycsw's unit tests are marked with the `unit` marker. This makes it easy to run " "them in isolation:" msgstr "pycsw 的单元测试用 `unit` 标记。这使得单独运行它们变得容易:" #: ../../testing.rst:176 msgid "Running tests" msgstr "运行测试" #: ../../testing.rst:178 msgid "" "Since pycsw uses `pytest`_, tests are run with the ``py.test`` runner. A basic " "test run can be made with:" msgstr "" "由于 pycsw 使用 `pytest`_,测试使用 ``py.test`` 运行程序运行。可以使用以下方法进" "行基本测试运行:" #: ../../testing.rst:185 msgid "" "This command will run all tests and report on the number of successes, failures " "and also the time it took to run them. The `py.test` command accepts several " "additional parameters that can be used in order to customize the execution of " "tests. Look into `pytest's invocation documentation`_ for a more complete " "description. You can also get a description of the available parameters by " "running:" msgstr "" "这个命令将运行所有测试,并报告成功、失败次数以及运行它们所花费的时间。`py.test` " "命令接受几个额外的参数,这些参数可用于自定义测试的执行。查看 `pytest's " "invocation documentation`_,以获得更完整的描述。还可以通过运行来获得可用参数的描" "述:" #: ../../testing.rst:198 msgid "Running specific suites and test cases" msgstr "运行特定套件和测试用例" #: ../../testing.rst:200 msgid "" "py.test allows tagging tests with markers. These can be used to selectively run " "some tests. pycsw uses two markers:" msgstr "" "py.test 允许标记测试。这些可以用来选择性地运行一些测试。 pycsw 使用两个标记:" #: ../../testing.rst:203 msgid "``unit`` - run only inut tests" msgstr "``unit`` - 只运行inut测试" #: ../../testing.rst:204 msgid "``functional``- run onyl functional tests" msgstr "``functional``- 只运行功能测试" #: ../../testing.rst:206 msgid "Markers can be specified by using the ``-m `` flag." msgstr "标记可以通过使用 ``-m `` 标志来指定。" #: ../../testing.rst:212 msgid "" "You can also use the ``-k `` flag to select which tests to run. " "Since each test's name includes the suite name, http method and an identifier " "for the test, it is easy to run only certain tests." msgstr "" "您还可以使用 ``-k `` 标志来选择要运行哪些测试。由于每个测试的名" "称都包含套件名称、http方法和测试的标识符,因此仅运行某些测试很容易。" #: ../../testing.rst:223 msgid "The ``-m`` and ``-k`` flags can be combined." msgstr "``-m`` and ``-k`` 标志可以组合起来。" #: ../../testing.rst:227 msgid "Exiting fast" msgstr "快速退出" #: ../../testing.rst:229 msgid "" "The ``--exitfirst`` (or ``-x``) flag can be used to stop the test runner " "immediately as soon as a test case fails." msgstr "" "``--exitfirst`` (or ``-x`` ) 标志可用于在测试用例失败时立即停止测试运行程序。" #: ../../testing.rst:238 msgid "Seeing more output" msgstr "看到更多的输出" #: ../../testing.rst:240 msgid "There are three main ways to get more output from running tests:" msgstr "从运行测试中获得更多输出的主要方法有三种:" #: ../../testing.rst:242 msgid "The ``--verbose`` (or ``-v``) flag;" msgstr "``--verbose`` (or ``-v`` ) 标志;" #: ../../testing.rst:244 msgid "" "The ``--capture=no`` flag - Messages sent to stdout by a test are not suppressed;" msgstr "测试发送到stdout的 ``--capture=no`` flag - Messages不会被抑制;" #: ../../testing.rst:247 msgid "" "The ``--pycsw-loglevel`` flag - Sets the log level of the pycsw instance under " "test. Set this value to ``debug`` in order to see all debug messages sent by " "pycsw while processing a request." msgstr "" "``--pycsw-loglevel`` 标志 - 设置被测试的pycsw实例的日志级别。将此值设置为 " "``debug`` ,以便查看pycsw在处理请求时发送的所有调试消息。" #: ../../testing.rst:260 msgid "Comparing results with difflib instead of XML c14n" msgstr "将结果与difflib而不是XML c14n进行比较" #: ../../testing.rst:262 msgid "" "The functional tests compare results with their expected values by using [XML " "canonicalisation - XML c14n](https://www.w3.org/TR/xml-c14n/). Alternatively, " "you can call py.test with the ``--functional-prefer-diffs`` flag. This will " "enable comparison based on Python's ``difflib``. Comparison is made on a line-by-" "line basis and in case of failure, a unified diff will be printed to standard " "output." msgstr "" "功能测试使用 [XML canonicalisation - XML c14n](https://www.w3.org/TR/xml-c14n/) " "将结果与期望值进行比较。或者,也可以调用py, 使用 ``--functional-prefer-diffs`` 标" "志进行测试。这将支持基于 Python's ``difflib`` 的比较。在逐行比较的基础上,如果失" "败,将把统一的差异打印到标准输出。" #: ../../testing.rst:275 msgid "Saving test results for disk" msgstr "在磁盘中保存测试结果" #: ../../testing.rst:277 msgid "" "The result of each functional test can be saved to disk by using the ``--" "functional-save-results-directory`` option. Each result file is named after the " "test identifier it has when running with pytest." msgstr "" "通过使用 ``--functional-save-results-directory`` 选项,可以将每个功能测试的结果保" "存到磁盘上。每个结果文件都是根据使用pytest运行时的测试标识符命名的。" #: ../../testing.rst:288 msgid "Test coverage" msgstr "测试覆盖率" #: ../../testing.rst:290 msgid "" "Use the `--cov pycsw` flag in order to see information on code coverage. It is " "possible to get output in a variety of formats." msgstr "使用 `--cov pycsw` 标志来查看代码覆盖率的信息。可以各种格式获得输出。" #: ../../testing.rst:299 msgid "Specifying a timeout for tests" msgstr "指定测试超时" #: ../../testing.rst:301 msgid "" "The `--timeout ` option can be used to specify that if a test takes " "more than `` to run it is considered to have failed. Seconds can be a " "float, so it is possibe to specify sub-second timeouts" msgstr "" "`--timeout ` 选项可用于指定如果测试运行时间超过 ``,则认为它已" "经失败。秒可以是一个浮点,所以可以指定次秒超时" #: ../../testing.rst:311 msgid "Linting with flake8" msgstr "Linting with flake8" #: ../../testing.rst:313 msgid "" "Use the `--flake8` flag to also check if the code complies with Python's style " "guide" msgstr "使用 `--flake8` 标志也检查代码是否符合Python风格指南" #: ../../testing.rst:322 msgid "Testing multiple Python versions" msgstr "测试多个Python版本" #: ../../testing.rst:324 msgid "" "For testing multiple Python versions and configurations simultaneously you can " "use `tox`_. pycsw includes a `tox.ini` file with a suitable configuration. It " "can be used to run tests against multiple Python versions and also multiple " "database backends. When running `tox` you can send arguments to the `py.test` " "runner by using the invocation `tox -- `. " "Examples:" msgstr "" "为了同时测试多个Python版本和配置,可以使用 `tox`_ 。 pycsw包含一个具有适当配置的 " "`tox.ini` 文件它可以用于对多个Python版本和多个数据库后端进行测试。在运行 `tox` " "时,可以通过调用 `tox -- ` 向 `py.test` 运行程" "序发送参数。例如:" #: ../../testing.rst:348 msgid "Web Testing" msgstr "Web测试" #: ../../testing.rst:350 msgid "" "You can also use the pycsw tests via your web browser to perform sample requests " "against your pycsw install. The tests are is located in ``tests/``. To " "generate the HTML page:" msgstr "" "还可以通过Web浏览器使用pycsw测试,来执行pycsw安装样例申请。这些测试在 ``tests/`` " "中。生成HTML页面:" #: ../../testing.rst:358 msgid "Then navigate to ``http://host/path/to/pycsw/tests/index.html``." msgstr "导航到 ``http://host/path/to/pycsw/tests/index.html`` 。" #~ msgid "" #~ "Compliance benchmarking is done via the OGC `Compliance & Interoperability " #~ "Testing & Evaluation Initiative`_. The pycsw `wiki `_ documents testing procedures and " #~ "status." #~ msgstr "" #~ "合规性基准是通过OGC `合规性和互操作性测试与自发性评估`_ 完成的。该pycsw维基 " #~ "``_ 文档测试程序" #~ "和状态。" #~ msgid "Tester" #~ msgstr "测试仪" #~ msgid "" #~ "The pycsw tests framework (in ``tests``) is a collection of testsuites to " #~ "perform automated regession testing of the codebase. Test are run against " #~ "all pushes to the GitHub repository via `Travis CI`_." #~ msgstr "" #~ "该pycsw测试框架(在 ``tests`` 里)是测试包的集合体,用来执行代码库的自动" #~ "regession测试。通过 `Travis CI`_ ,测试在GitHub的库中运行。" #~ msgid "Running Locally" #~ msgstr "本地运行" #~ msgid "" #~ "The tests perform HTTP GET and POST requests against ``http://" #~ "localhost:8000``. The expected output for each test can be found in " #~ "``expected``. Results are categorized as ``passed``, ``failed``, or " #~ "``initialized``. A summary of results is output at the end of the run." #~ msgstr "" #~ "针对 ``http://localhost:8000``,测试执行HTTP GET和POST请求。每个测试的输出都在" #~ "``expected``中。结果被归类为``通过``,``失败``,或``初始化``。总结的结果会在运" #~ "行结束时输出。" #~ msgid "Failed Tests" #~ msgstr "测试失败" #~ msgid "" #~ "If a given test has failed, the output is saved in ``results``. The " #~ "resulting failure can be analyzed by running ``diff tests/expected/" #~ "name_of_test.xml tests/results/name_of_test.xml`` to find variances. The " #~ "task returns a status code which indicates the number of tests which " #~ "have failed (i.e. ``echo $?``)." #~ msgstr "" #~ "如果某个测试失败,输出将保存在``结果``中。 运行``diff tests/expected/" #~ "name_of_test.xml tests/results/name_of_test.xml`` ,会自动统计失败结果以找到差" #~ "异。任务会返回一个状态代码,表示已失败的测试数目(即``echo $?``)。" #~ msgid "Test Suites" #~ msgstr "测试套件" #~ msgid "" #~ "The tests framework is run against a series of 'suites' (in ``tests/" #~ "suites``), each of which specifies a given configuration to test various " #~ "functionality of the codebase. Each suite is structured as follows:" #~ msgstr "" #~ "测试框架将针对一系列“套件”(在``测试/ suites``)完成运行,其中每一项均指定一个" #~ "给定的配置,以测试基本代码的各种功能。每个套件的结构如下:" #~ msgid "``tests/suites/suite/default.yml``: the configuration for the suite" #~ msgstr "`tests/suites/suite/default.yml`:对于该套件的配置" #~ msgid "" #~ "``tests/suites/suite/post``: directory of XML documents for HTTP POST requests" #~ msgstr "`tests/suites/suite/post`:XML文档目录的HTTP POST请求" #~ msgid "" #~ "``tests/suites/suite/get/requests.txt``: directory and text file of KVP for " #~ "HTTP GET requests" #~ msgstr "" #~ "`tests/suites/suite/get/requests.txt`:KVP的目录和文本文件,用于HTTP GET请求" #~ msgid "" #~ "``tests/suites/suite/data``: directory of sample XML data required for the " #~ "test suite. Database and test data are setup/loaded automatically as part of " #~ "testing" #~ msgstr "" #~ "`tests/suites/suite/data`:测试套件所需样本的XML数据目录。作为测试的一部分,数" #~ "据库和测试数据是自动设置或自动加载的" #~ msgid "When the tests are invoked, the following operations are run:" #~ msgstr "当测试被调用,将执行以下操作:" #~ msgid "pycsw configuration is set to ``tests/suites/suite/default.yml``" #~ msgstr "pycsw配置设置为`tests/suites/suite/default.yml`" #~ msgid "HTTP POST requests are run against ``tests/suites/suite/post/*.xml``" #~ msgstr "HTTP POST请求是针对 `tests/suites/suite/post/*.xml` 运行的" #~ msgid "" #~ "HTTP GET requests are run against each request in ``tests/suites/suite/get/" #~ "requests.txt``" #~ msgstr "HTTP GET请求是针对 ``tests/suites/suite/get/requests.txt`` 运行的" #~ msgid "" #~ "The CSV format of ``tests/suites/suite/get/requests.txt`` is ``testname," #~ "request``, with one line for each test. The ``testname`` value is a unique " #~ "test name (this value sets the name of the output file in the test results). " #~ "The ``request`` value is the HTTP GET request. The ``PYCSW_SERVER`` token is " #~ "replaced at runtime with the URL to the pycsw install." #~ msgstr "" #~ "在每项测试的第一行中, `tests/suites/suite/get/requests.txt` 的CSV格式是 " #~ "`testname,request` 。该 ``testname`` 值是唯一的测试名(此值设置在测试结果输出" #~ "文件的名称内)。该 ``request`` 值是HTTP GET请求的值。该 ``PYCSW_SERVER`` 在" #~ "URL pycsw安装运行时会被替换掉的。" #~ msgid "Ensure that all file paths are relative to ``path/to/pycsw``" #~ msgstr "确保所有文件的路径都关联 ``path/to/pycsw`` " #~ msgid "" #~ "Ensure that ``repository.database`` points to an SQLite3 database called " #~ "``tests/suites/foo/data/records.db``. The database *must* be called " #~ "``records.db`` and the directory ``tests/suites/foo/data`` *must* exist" #~ msgstr "" #~ "确保 ``repository.database`` 指定于 ``tests/suites/foo/data/records.db`` 的一" #~ "个sqlite3数据库。该数据库*必须*被写为 ``records.db``,目录 ``tests/suites/foo/" #~ "data`` 也必须存在" #~ msgid "" #~ "Pycsw uses `pytest`_ for managing its automated tests. There are a number of " #~ "test suites that perform mostly functional testing. These tests ensure that " #~ "pycsw is compliant with the various supported standards. There is also a " #~ "growing set of unit tests. These focus on smaller scope testing, in order to " #~ "verify that individual bits of code are working as expected." #~ msgstr "" #~ "Pycsw使用 `pytest`_ 管理它的自动化测试。有许多测试套件主要执行功能测试。这些测" #~ "试确保pycsw符合各种受支持的标准。还有一组不断增长的单元测试。这些测试集中在较" #~ "小的范围内,以便验证各个代码位是否按预期工作." ================================================ FILE: docs/locale/zh/LC_MESSAGES/tools.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-09 14:34+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../tools.rst:4 msgid "Cataloguing and Metadata Tools" msgstr "编目和元数据工具" #: ../../tools.rst:7 msgid "OARec Clients and Servers" msgstr "OARec 客户端和服务器" #: ../../tools.rst:9 msgid "" "https://github.com/opengeospatial/ogcapi-records/blob/master/" "implementations.md" msgstr "" "https://github.com/opengeospatial/ogcapi-records/blob/master/" "implementations.md" #: ../../tools.rst:12 msgid "CSW Clients" msgstr "CSW客户端" #: ../../tools.rst:14 msgid "" "`Geoportal CSW Clients `_" msgstr "" "`Geoportal CSW 客户端 `_" #: ../../tools.rst:15 msgid "`OWSLib `_" msgstr "`OWSLib `_" #: ../../tools.rst:16 msgid "" "`QGIS MetaSearch `_" msgstr "" "`QGIS MetaSearch `_" #: ../../tools.rst:19 msgid "CSW Servers" msgstr "CSW服务器" #: ../../tools.rst:21 msgid "`deegree `_" msgstr "`deegree `_" #: ../../tools.rst:22 msgid "`GeoNetwork opensource `_" msgstr "`GeoNetwork 开源 `_" #: ../../tools.rst:25 msgid "Metadata Editing Tools" msgstr "元数据编辑工具" #: ../../tools.rst:27 msgid "`pygeometa `_" msgstr "`pygeometa `_" #: ../../tools.rst:28 msgid "" "`CatMDEdit `_" msgstr "" "`CatMDEdit `_" #: ../../tools.rst:29 msgid "`EUOSME `_" msgstr "`EUOSME `_" #: ../../tools.rst:30 msgid "`GIMED `_" msgstr "`GIMED `_" #: ../../tools.rst:31 msgid "" "`Metatools `_ (`QGIS `_ plugin)" msgstr "" "`元工具`_(`QGIS `_插件)" #~ msgid "" #~ "`Geoportal CSW Clients `_" #~ msgstr "" #~ "`Geoportal CSW客户端 `_" #~ msgid "" #~ "`MetaSearch `_ " #~ "(`QGIS `_ plugin)" #~ msgstr "" #~ "`联合检索 `_ (`QGIS " #~ "`_ 插件)" #~ msgid "`eXcat `_" #~ msgstr "`eXcat `_" #~ msgid "`CatMDEdit `_" #~ msgstr "`CatMDEdit `_" #~ msgid "`GIMED `_" #~ msgstr "`GIMED `_" #~ msgid "" #~ "`QSphere `_ (`QGIS `_ plugin)" #~ msgstr "" #~ "`QSphere `_ (`QGIS `_ plugin)" ================================================ FILE: docs/locale/zh/LC_MESSAGES/transactions.po ================================================ # msgid "" msgstr "" "Project-Id-Version: pycsw 2.0-dev\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-08 22:54+0800\n" "PO-Revision-Date: 2022-03-10 09:22+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.8.0\n" "X-Generator: Poedit 3.0.1\n" #: ../../transactions.rst:4 ../../transactions.rst:67 msgid "Transactions" msgstr "事务" #: ../../transactions.rst:6 msgid "" "pycsw's CSW implementation has the ability to process CSW Harvest and " "Transaction requests (CSW-T). Transactions are disabled by default; to " "enable, ``manager.transactions`` must be set to ``true``. Access to " "transactional functionality is limited to IP addresses which must be set in " "``manager.allowed_ips``." msgstr "" "pycsw 的 CSW 实现具有处理 CSW Harvest 和 Transaction 请求(CSW-T)的能力。默认" "情况下禁用事务;要启用,必须将 ``manager.transactions`` 设置为 ``true``。对事务" "功能的访问仅限于必须在``manager.allowed_ips`` 中设置的 IP 地址。" #: ../../transactions.rst:9 msgid "Supported Resource Types" msgstr "支持的资源类型" #: ../../transactions.rst:11 msgid "" "For transactions and harvesting, pycsw supports the following metadata " "resource types by default:" msgstr "对于事务和收获,pycsw 默认支持以下元数据资源类型:" #: ../../transactions.rst:1 msgid "Resource Type" msgstr "源类型" #: ../../transactions.rst:1 msgid "Namespace" msgstr "命名空间" #: ../../transactions.rst:1 msgid "Transaction" msgstr "业务" #: ../../transactions.rst:1 msgid "Harvest" msgstr "获取" #: ../../transactions.rst:1 msgid "Dublin Core" msgstr "Dublin Core" #: ../../transactions.rst:1 msgid "``http://www.opengis.net/cat/csw/2.0.2``" msgstr "``http://www.opengis.net/cat/csw/2.0.2``" #: ../../transactions.rst:1 msgid "yes" msgstr "是" #: ../../transactions.rst:1 msgid "FGDC" msgstr "FGDC" #: ../../transactions.rst:1 msgid "``http://www.opengis.net/cat/csw/csdgm``" msgstr "``http://www.opengis.net/cat/csw/csdgm``" #: ../../transactions.rst:1 msgid "GM03" msgstr "GM03" #: ../../transactions.rst:1 msgid "``http://www.interlis.ch/INTERLIS2.3``" msgstr "``http://www.interlis.ch/INTERLIS2.3``" #: ../../transactions.rst:1 msgid "ISO 19139" msgstr "ISO 19139" #: ../../transactions.rst:1 msgid "``http://www.isotc211.org/2005/gmd``" msgstr "``http://www.isotc211.org/2005/gmd``" #: ../../transactions.rst:1 msgid "ISO GMI" msgstr "ISO GMI" #: ../../transactions.rst:1 msgid "``http://www.isotc211.org/2005/gmi``" msgstr "``http://www.isotc211.org/2005/gmi``" #: ../../transactions.rst:1 msgid "OGC:CSW 2.0.2" msgstr "OGC:CSW 2.0.2" #: ../../transactions.rst:1 msgid "OGC:WMS 1.1.1/1.3.0" msgstr "OGC:WMS 1.1.1/1.3.0" #: ../../transactions.rst:1 msgid "``http://www.opengis.net/wms``" msgstr "``http://www.opengis.net/wms``" #: ../../transactions.rst:1 msgid "OGC:WMTS 1.0.0" msgstr "OGC:WMTS 1.0.0" #: ../../transactions.rst:1 msgid "``http://www.opengis.net/wmts/1.0``" msgstr "``http://www.opengis.net/wmts/1.0``" #: ../../transactions.rst:1 msgid "OGC:WFS 1.0.0/1.1.0/2.0.0" msgstr "OGC:WFS 1.0.0/1.1.0/2.0.0" #: ../../transactions.rst:1 msgid "``http://www.opengis.net/wfs``" msgstr "``http://www.opengis.net/wfs``" #: ../../transactions.rst:1 msgid "OGC:WCS 1.0.0" msgstr "OGC:WCS 1.0.0" #: ../../transactions.rst:1 msgid "``http://www.opengis.net/wcs``" msgstr "``http://www.opengis.net/wcs``" #: ../../transactions.rst:1 msgid "OGC:WPS 1.0.0" msgstr "OGC:WPS 1.0.0" #: ../../transactions.rst:1 msgid "``http://www.opengis.net/wps/1.0.0``" msgstr "``http://www.opengis.net/wps/1.0.0``" #: ../../transactions.rst:1 msgid "OGC:SOS 1.0.0" msgstr "OGC:SOS 1.0.0" #: ../../transactions.rst:1 msgid "``http://www.opengis.net/sos/1.0``" msgstr "``http://www.opengis.net/sos/1.0``" #: ../../transactions.rst:1 msgid "OGC:SOS 2.0.0" msgstr "OGC:SOS 2.0.0" #: ../../transactions.rst:1 msgid "``http://www.opengis.net/sos/2.0``" msgstr "``http://www.opengis.net/sos/2.0``" #: ../../transactions.rst:1 msgid "`WAF`_" msgstr "`WAF`_" #: ../../transactions.rst:1 msgid "``urn:geoss:waf``" msgstr "``urn:geoss:waf``" #: ../../transactions.rst:31 msgid "" "Additional metadata models are supported by enabling the appropriate :ref:" "`profiles`." msgstr "通过启用适当的 :ref:`profiles` 来支持其他元数据模型。" #: ../../transactions.rst:35 msgid "" "For transactions to be functional when using SQLite3, the SQLite3 database " "file (**and its parent directory**) must be fully writable. For example:" msgstr "" "为了在使用 SQLite3 时事务能够正常工作,SQLite3 数据库文件(**及其父目录**)必须" "是完全可写的。例如:" #: ../../transactions.rst:44 msgid "" "For CSW-T deployments, it is strongly advised that this directory reside in an " "area that is not accessible by HTTP." msgstr "对于 CSW-T 部署,强烈建议将此目录驻留在 HTTP 无法访问的区域中。" #: ../../transactions.rst:47 msgid "Harvesting" msgstr "获取" #: ../../transactions.rst:51 msgid "" "Your server must be able to make outgoing HTTP requests for this functionality." msgstr "服务器必须能够为此功能发出传出 HTTP 请求。" #: ../../transactions.rst:53 msgid "" "pycsw supports the CSW-T ``Harvest`` operation. Records which are harvested " "require to setup a cronjob to periodically refresh records in the local " "repository. A sample cronjob is available in ``etc/harvest-all.cron`` which " "points to ``pycsw-admin.py`` (you must specify the correct path to your " "configuration). Harvest operation results can be sent by email (via ``mailto:" "``) or ftp (via ``ftp://``) if the Harvest request specifies ``csw:" "ResponseHandler``." msgstr "" "pycsw 支持 CSW-T ``Harvest`` 操作。收集的记录需要设置一个 cronjob 来定期刷新本" "地存储库中的记录。``etc/harvest-all.cron`` 中提供了一个示例 cronjob,它指向 " "``pycsw-admin.py``(必须指定正确的配置路径)。如果 Harvest 请求指定了 ``csw:" "ResponseHandler``,则 Harvest 操作结果可以通过电子邮件(通过 ``mailto:``)或 " "ftp(通过 ``ftp://``)发送。" #: ../../transactions.rst:57 msgid "" "For ``csw:ResponseHandler`` values using the ``mailto:`` protocol, you must " "have ``server.smtp_host`` set in your :ref:`configuration `." msgstr "" "对于使用 ``mailto:`` 协议的 ``csw:ResponseHandler`` 值,必须在 :ref:" "`configuration ` 中设置 ``server.smtp_host``。" #: ../../transactions.rst:60 msgid "OGC Web Services" msgstr "OGC Web服务" #: ../../transactions.rst:62 msgid "" "When harvesting OGC web services, requests can provide the base URL of the " "service as part of the Harvest request. pycsw will construct a " "``GetCapabilities`` request dynamically." msgstr "" "获取 OGC Web 服务时,请求可以提供服务的基本 URL 作为 Harvest 请求的一部分。" "pycsw 将动态构造一个 ``GetCapabilities`` 请求。" #: ../../transactions.rst:64 msgid "" "When harvesting other CSW servers, pycsw pages through the entire CSW in " "default increments of 10. This value can be modified via the ``manager." "csw_harvest_pagesize`` :ref:`configuration ` option. It is " "strongly advised to use the ``csw:ResponseHandler`` parameter for harvesting " "large CSW catalogues to prevent HTTP timeouts." msgstr "" "当收获其他 CSW 服务器时,pycsw 以默认增量 10 对整个 CSW 进行分页。这个值可以通" "过 ``manager.csw_harvest_pagesize`` :ref:`configuration ` 选项进" "行修改。强烈建议使用``csw:ResponseHandler`` 参数来收集大型 CSW 目录以防止 HTTP " "超时。" #: ../../transactions.rst:69 msgid "" "pycsw supports 3 modes of the ``Transaction`` operation (``Insert``, " "``Update``, ``Delete``):" msgstr "" "pycsw支持 ``Transaction`` 操作( ``Insert`` , ``Update`` , ``Delete`` )的3种" "模式:" #: ../../transactions.rst:71 msgid "**Insert**: full XML documents can be inserted as per CSW-T" msgstr "**Insert**:完整的XML文档可以用CSW-T插入" #: ../../transactions.rst:72 msgid "" "**Update**: updates can be made as full record updates or record properties " "against a ``csw:Constraint``" msgstr "" "**更新**:更新可以作为完整记录更新或针对 ``csw:Constraint`` 的记录属性进行" #: ../../transactions.rst:73 msgid "**Delete**: deletes can be made against a ``csw:Constraint``" msgstr "**删除**:可以针对 ``csw:Constraint`` 进行删除" #: ../../transactions.rst:75 msgid "" "Transaction operation results can be sent by email (via ``mailto:``) or ftp " "(via ``ftp://``) if the Transaction request specifies ``csw:ResponseHandler``." msgstr "" "事务操作结果可以通过电子邮件(通过 ``mailto:``)或 ftp(通过 ``ftp://``)发送," "如果事务请求指定了``csw:ResponseHandler``。" #: ../../transactions.rst:77 msgid "The :ref:`tests` contain CSW-T request examples." msgstr ":ref:`tests` 包含 CSW-T 请求示例。" ================================================ FILE: docs/metadata-model-reference.rst ================================================ .. _metadata-model-reference: Metadata Model Reference ======================== pycsw's metadata repository model is designed to support queryable elements as well full-text search. The model is rooted in ISO 19115 and is updated as required to be able to support additional metadata models in a generic fashion. Overview -------- Model Crosswalk --------------- .. list-table:: pycsw model :widths: 20 20 20 20 20 20 20 20 :class: metadata-model-table :header-rows: 1 * - Database column - pycsw mapping name - Queryable name - ISO 19115 (XPath) - CSW Record/Dublin Core (XPath) - OGC API - Records (JSONPath) - STAC (JSONPath) - Description * - ``identifier`` - ``pycsw:Identifier`` - ``apiso:Identifier`` - ``gmd:fileIdentifier/gco:CharacterString`` - ``dc:identifier`` - ``id`` - ``id`` - Record identifier (Primary key) * - ``typename`` - ``pycsw:Typename`` - - - - - - CSW typename (e.g. ``csw:Record``, ``gmd:MD_Metadata``), see also ref:`existing-repository-requirements` * - ``schema`` - ``pycsw:Schema`` - - - - - - Schema namespace, i.e. http://www.opengis.net/cat/csw/2.0.2, http://www.isotc211.org/2005/gmd, http://www.opengis.net/spec/ogcapi-records-1/1.0/req/record-core * - ``mdsource`` - ``pycsw:MdSource`` - - - - - - Origin of resource, either ``local`` (default), or URL to location of record/resource/service * - ``insert_date`` - ```pycsw:InsertDate`` - - - - - - Date of insertion of the metadata record, see also ref:`existing-repository-requirements` * - ``xml`` - ``pycsw:XML`` - - - - - - Raw XML metadata as it was inserted into the repository. Note that this field is deprecated for the ``metadata`` field, and will be removed in a future release, see also ref:`existing-repository-requirements` * - ``metadata`` - ``pycsw:Metadata`` - - - - - - Raw metadata payload (replaces ``xml`` field, supports any metadata type [JSON, XML, etc.]), see also ref:`existing-repository-requirements` * - ``metadata_type`` - pycsw:MetadataType - - - - - - Media type of the metadata payload (``application/xml`` [default], ``application/json`` for OGC API - Records and STAC) * - ``anytext`` - ``pycsw:AnyText`` - ``apiso:AnyText`` - ``//text()`` (``csw:AnyText`` [queryable only, not a returnable]) - ``//text()`` (``csw:AnyText`` [queryable only, not a returnable]) - ``q=`` (for API) - ``q=`` (for API) - Bag of metadata element and attributes content ONLY, no XML tags or JSON element names, see also :ref:`existing-repository-requirements` * - ``language`` - ``pycsw:Language`` - ``apiso:Language`` - ``gmd:language/gmd:LanguageCode``, ``gmd:language/gco:CharacterString`` - ``dc:language`` - ``properties.language`` - ``properties.language`` - * - ``title`` - ``pycsw:Title`` - ``apiso:Title`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString`` - ``dc:title`` - ``properties.title`` - ``properties.title`` - * - ``abstract`` - ``pycsw:Abstract`` - ``apiso:Abstract`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:abstract/gco:CharacterString`` - ``dct:abstract`` - ``properties.description`` - ``properties.description`` - * - ``edition`` - ``pycsw:Edition`` - ``apiso:Edition`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:edition/gco:CharacterString`` - - - - * - ``keywords`` - ``pycsw:Keywords`` - ``apiso:Subject`` - ``gmd:identificationInfo/gmd:MD_Identification/gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:keyword/gco:CharacterString``, ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:topicCategory/gmd:MD_TopicCategoryCode`` - ``dc:subject`` - ``properties.keywords`` - - CSV of keywords, see also :ref:`existing-repository-requirements` * - ``keywordstype`` - ``pycsw:KeywordType`` - ``apiso:KeywordType`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:type/gmd:MD_KeywordTypeCode`` - - - - * - ``themes`` - ``pycsw:Themes`` - - - - ``properties.themes`` - - JSON list of concepts/schemes, see also :ref:`existing-repository-requirements` * - ``format`` - ``pycsw:Format`` - ``apiso:Format`` - ``gmd:distributionInfo/gmd:MD_Distribution/gmd:distributionFormat/gmd:MD_Format/gmd:name/gco:CharacterString`` - ``dc:format`` - ``properties.formats`` - - * - ``source`` - ``pycsw:Source`` - - - ``dc:source`` - ``properties.externalIds`` - - * - ``date`` - ``pycsw:Date`` - - - ``dc:date`` - ``time`` - ``properties.datetime`` - * - ``date_modified`` - ``pycsw:Modified`` - ``apiso:Modified`` - ``gmd:dateStamp/gco:Date`` - ``dct:modified`` - ``properties.updated`` - ``properties.updated`` - * - ``type`` - ``pycsw:Type`` - ``apiso:Type`` - ``gmd:hierarchyLevel/gmd:MD_ScopeCode`` - ``dc:type`` - ``properties.type`` - - * - ``wkt_geometry`` - ``pycsw:BoundingBox`` - ``apiso:BoundingBox`` - ``apiso:BoundingBox`` - ``ows:BoundingBox`` - ``geometry`` - ``geometry`` - WKT/EWKT of geometry * - ``crs`` - ``pycsw:CRS`` - ``apiso:CRS`` - ``gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:codeSpace/gco:CharacterString``, ``gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:version/gco:CharacterString``, ``gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:code/gco:CharacterString`` - ``dct:spatial`` - - - * - ``title_alternate`` - ``pycsw:AlternateTitle`` - ``apiso:AlternateTitle`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:alternateTitle/gco:CharacterString`` - ``dct:alternative`` - - - * - ``date_revision`` - ``pycsw:RevisionDate`` - ``apiso:RevisionDate`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:date/gmd:CI_Date[gmd:dateType/gmd:CI_DateTypeCode/@codeListValue="revision"]/gmd:date/gco:Date`` - - ``properties.updated`` - ``created`` or ``properties.updated`` - * - ``date_creation`` - ``pycsw:CreationDate`` - ``apiso:CreationDate`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:date/gmd:CI_Date[gmd:dateType/gmd:CI_DateTypeCode/@codeListValue="creation"]/gmd:date/gco:Date`` - - ``properties.created`` - ``created`` or ``properties.created`` - * - ``date_publication`` - ``pycsw:PublicationDate`` - ``apiso:PublicationDate`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:date/gmd:CI_Date[gmd:dateType/gmd:CI_DateTypeCode/@codeListValue="publication"]/gmd:date/gco:Date`` - - - - * - ``organization`` - ``pycsw:OrganizationName`` - ``apiso:OrganisationName`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName/gco:CharacterString`` - - - - * - ``securityconstraints`` - ``pycsw:SecurityConstraints`` - ``apiso:HasSecurityConstraints`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_SecurityConstraints`` - - - - * - ``parentidentifier`` - ``pycsw:ParentIdentifier`` - ``apiso:ParentIdentifier`` - ``gmd:parentIdentifier/gco:CharacterString`` - - ``collection`` - ``collection`` - * - ``topicategory`` - ``pycsw:TopicCategory`` - ``apiso:TopicCategory`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:topicCategory/gmd:MD_TopicCategoryCode`` - - - - * - ``resourcelanguage`` - ``pycsw:ResourceLanguage`` - ``apiso:ResourceLanguage`` - ``md:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:code/gmd:MD_LanguageTypeCode`` - - - - * - ``geodescode`` - ``pycsw:GeographicDescriptionCode`` - ``apiso:GeographicDescriptionCode`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:geographicElement/gmd:EX_GeographicDescription/gmd:geographicIdentifier/gmd:MD_Identifier/gmd:code/gco:CharacterString`` - - - - * - ``denominator`` - ``pycsw:Denominator`` - ``apiso:Denominator`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:equivalentScale/gmd:MD_RepresentativeFraction/gmd:denominator/gco:Integer`` - - - - * - ``distancevalue`` - ``pycsw:DistanceValue`` - ``apiso:DistanceValue`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance`` - - - ``gsd`` or ``properties.gsd`` - * - ``distanceuom`` - ``pycsw:DistanceUOM`` - ``apiso:DistanceUOM`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance/@uom`` - - - fixed to ``m`` - * - ``time_begin`` - ``pycsw:TempExtent_begin`` - ``apiso:TempExtent_begin`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:beginPosition`` - - ``properties.extent.temporal.interval[0]`` - ``properties.start_datetime`` - * - ``time_end`` - ``pycsw:TempExtent_end`` - ``apiso:TempExtent_end`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:endPosition`` - - ``properties.extent.temporal.interval[1]`` - ``properties.end_datetime`` - * - ``servicetype`` - ``pycsw:ServiceType`` - ``apiso:ServiceType`` - ``gmd:identificationInfo/srv:SV_ServiceIdentification/srv:serviceType/gco:LocalName`` - - - - * - ``servicetypeversion`` - ``pycsw:ServiceTypeVersion`` - ``apiso:ServiceTypeVersion`` - ``gmd:identificationInfo/srv:SV_ServiceIdentification/srv:serviceTypeVersion/gco:CharacterString`` - - - - * - ``operation`` - ``pycsw:Operation`` - ``apiso:Operation`` - ``gmd:identificationInfo/srv:SV_ServiceIdentification/srv:containsOperations/srv:SV_OperationMetadata/srv:operationName/gco:CharacterString`` - - - - * - ``couplingtype`` - ``pycsw:CouplingType`` - ``apiso:CouplingType`` - ``gmd:identificationInfo/srv:SV_ServiceIdentification/srv:couplingType/srv:SV_CouplingType`` - - - - * - ``operateson`` - ``pycsw:OperatesOn`` - ``apiso:OperatesOn`` - ``gmd:identificationInfo/srv:SV_ServiceIdentification/srv:operatesOn/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier/gmd:code/gco:CharacterString`` - - - - * - ``operatesonidentifier`` - ``pycsw:OperatesOnIdentifier`` - ``apiso:OperatesOnIdentifier`` - ``gmd:identificationInfo/srv:SV_ServiceIdentification/srv:coupledResource/srv:SV_CoupledResource/srv:identifier/gco:CharacterString`` - - - - * - ``operatesoname`` - ``pycsw:OperatesOnName`` - ``apiso:OperatesOnName`` - ``gmd:identificationInfo/srv:SV_ServiceIdentification/srv:coupledResource/srv:SV_CoupledResource/srv:operationName/gco:CharacterString`` - - - - * - ``degree`` - ``pycsw:Degree`` - ``apiso:Degree`` - ``gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:pass/gco:Boolean`` - - - - * - ``accessconstraints`` - ``pycsw:AccessConstraints`` - ``apiso:AccessConstraints`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_RestrictionCode`` - ``dc:rights`` - - - * - ``otherconstraints`` - ``pycsw:OtherConstraints`` - ``apiso:OtherConstraints`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:otherConstraints/gco:CharacterString`` - - ``properties.license`` - - * - ``classification`` - ``pycsw:Classification`` - ``apiso:Classification`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_ClassificationCode`` - - - - * - ``conditionapplyingtoaccessanduse`` - ``pycsw:ConditionApplyingToAccessAndUse`` - ``apiso:ConditionApplyingToAccessAndUse`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:useLimitation/gco:CharacterString`` - - - - * - ``lineage`` - ``pycsw:Lineage`` - ``apiso:Lineage`` - ``gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:lineage/gmd:LI_Lineage/gmd:statement/gco:CharacterString`` - - - - * - ``responsiblepartyrole`` - ``pycsw:ResponsiblePartyRole`` - ``apiso:ResponsiblePartyRole`` - ``gmd:contact/gmd:CI_ResponsibleParty/gmd:role/gmd:CI_RoleCode`` - - - - * - ``specificationtitle`` - ``pycsw:SpecificationTitle`` - ``apiso:SpecificationTitle`` - ``gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:title/gco:CharacterString`` - - - - * - ``specificationdate`` - ``pycsw:SpecificationDate`` - ``apiso:SpecificationDate`` - ``gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:date/gco:Date`` - - - - * - ``specificationdatetype`` - ``pycsw:SpecificationDateType`` - ``apiso:SpecificationDateType`` - ``gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:dateType/gmd:CI_DateTypeCode`` - - - - * - ``creator`` - ``pycsw:Creator`` - ``apiso:Creator`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName[gmd:role/gmd:CI_RoleCode/@codeListValue="originator"]/gco:CharacterString`` - ``dc:creator`` - ``properties.providers`` - - * - ``publisher`` - ``pycsw:Publisher`` - ``apiso:Publisher`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName[gmd:role/gmd:CI_RoleCode/@codeListValue="publisher"]/gco:CharacterString`` - ``dc:publisher`` - ``properties.providers`` - - * - ``contributor`` - ``pycsw:Contributor`` - ``apiso:Contributor`` - ``gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName[gmd:role/gmd:CI_RoleCode/@codeListValue="contributor"]/gco:CharacterString`` - ``dc:contributor`` - ``properties.providers`` - - * - ``relation`` - ``pycsw:Relation`` - ``apiso:Relation`` - ``gmd:identificationInfo/gmd:MD_Data_Identification/gmd:aggregationInfo`` - ``dc:relation`` - - - * - ``platform`` - ``pycsw:Platform`` - ``apiso:Platform`` - ``gmi:acquisitionInfo/gmi:MI_AcquisitionInformation/gmi:platform/gmi:MI_Platform/gmi:identifier`` - - - ``platform`` or ``properties.platform`` - * - ``instrument`` - ``pycsw:Instrument`` - ``apiso:Instrument`` - ``gmi:acquisitionInfo/gmi:MI_AcquisitionInformation/gmi:platform/gmi:MI_Platform/gmi:instrument/gmi:MI_Instrument/gmi:identifier`` - - - ``instruments`` or ``properties.instruments`` - * - ``sensortype`` - ``pycsw:SensorType`` - ``apiso:SensorType`` - ``gmi:acquisitionInfo/gmi:MI_AcquisitionInformation/gmi:platform/gmi:MI_Platform/gmi:instrument/gmi:MI_Instrument/gmi:type`` - - - - * - ``cloudcover`` - ``pycsw:CloudCover`` - ``apiso:CloudCover`` - ``gmd:contentInfo/gmd:MD_ImageDescription/gmd:cloudCoverPercentage`` - - - - * - ``bands`` - ``pycsw:Bands`` - ``apiso:Bands`` - ``gmd:contentInfo/gmd:MD_ImageDescription/gmd:dimension/MD_Band/@id`` - - - - JSON list of band information, see also :ref:`existing-repository-requirements` * - ``links`` - ``pycsw:Links`` - - - - ``links`` - ``links``, ``assets`` - List of dicts with properties: ``name``, ``description``, ``protocol``, ``url``, see also :ref:`existing-repository-requirements` * - ``contacts`` - ``pycsw:Contacts`` - - ``//gmd:CI_ResponsibleParty`` - - ``properties.providers`` - - List of dicts with properties: name, organization, address, postcode, city, region, country, email, phone, fax, onlineresource, position, role ================================================ FILE: docs/migration-guide.rst ================================================ .. _migration-guide: pycsw Migration Guide ===================== This page provides migration support across pycsw versions over time to help with pycsw change management. pycsw 2.x to 3.0 Migration -------------------------- - the default configuration is now in YAML format. See :ref:`configuration` for more information. A helper script (``pycsw-admin.py migrate-config``) is included for updating from the previous configuration format - the default endpoint for standalone deployments is now powered by ``pycsw/wsgi_flask.py`` (based on Flask) which supports ALL pycsw supported APIs. Make sure to use ``requirements-standalone.txt`` on top of ``requirements.txt`` to install Flask along with other standalone requirements - the previously used ``pycsw/wsgi.py`` can still be used for CSW only deployments or for applications that need to integrate pycsw as a library (e.g. Django applications). PyPI installations still use ``requirements.txt`` which does not install Flask by default - the default endpoint ``/`` is now OGC API - Records - the CSW endpoint is now ``/csw`` - the OAI-PMH endpoint is now ``/oaipmh`` - the OpenSearch endpoint is now ``/opensearch`` - the SRU endpoint is now ``/sru`` - the ``pycsw-admin.py`` syntax has been updated - the ``-c`` flag has been replaced by subcommands (i.e. ``pycsw-admin.py -c load_records`` -> ``pycsw-admin.py load-records``) - subcommands have been slugified (i.e. ``load_records`` -> ``load-records``) - consult ``--help`` to use the updated CLI syntax - use the following migration script to add new model fields .. code-block:: sql alter table records add column metadata TEXT; alter table records add column metadata_type TEXT default 'application/xml'; alter table records add column edition TEXT; alter table records add column contacts TEXT; alter table records add column themes TEXT; vacuum; pycsw 1.x to 2.0 Migration -------------------------- - the default CSW version is now 3.0.0. CSW clients need to explicitly specify ``version=2.0.2`` for CSW 2 behaviour. Also, pycsw administrators can use a WSGI wrapper to the pycsw API to force ``version=2.0.2`` on init of ``pycsw.server.Csw`` from the server. See :ref:`csw-support` for more information. - ``pycsw.server.Csw.dispatch_wsgi()`` previously returned the response content as a string. 2.0.0 introduces a compatability break to additionally return the HTTP status code along with the response as a list .. code-block:: python from pycsw.server import Csw my_csw = Csw(my_dict) # add: env=some_environ_dict, version='2.0.2' if preferred # using pycsw 1.x response = my_csw.dispatch_wsgi() # using pycsw 2.0 http_status_code, response = my_csw.dispatch_wsgi() # covering either pycsw version content = csw.dispatch_wsgi() # pycsw 2.0 has an API break: # pycsw < 2.0: content = xml_response # pycsw >= 2.0: content = [http_status_code, content] # deal with the API break if isinstance(content, list): # pycsw 2.0+ http_response_code, response = content See :ref:`api` for more information. ================================================ FILE: docs/oaipmh.rst ================================================ .. _oaipmh: OAI-PMH Support =============== pycsw supports the `The Open Archives Initiative Protocol for Metadata Harvesting`_ (OAI-PMH) standard. OAI-PMH OpenSearch support is enabled by default. There are two ways to access OAI-PMH depending on the deployment pattern chosen. OGC API - Records deployment ---------------------------- .. code-block:: bash http://localhost:8000/oaipmh CSW legacy deployment --------------------- HTTP requests must be specified with ``mode=oaipmh`` in the base URL for OAI-PMH requests, e.g.: .. code-block:: bash http://localhost/pycsw/csw.py?mode=oaipmh&verb=Identify See http://www.openarchives.org/OAI/openarchivesprotocol.html for more information on OAI-PMH as well as request / reponse examples. .. _`The Open Archives Initiative Protocol for Metadata Harvesting`: http://www.openarchives.org/OAI/openarchivesprotocol.html ================================================ FILE: docs/oarec-support.rst ================================================ .. _oarec-support: OGC API - Records Support ========================= Versions -------- pycsw supports `OGC API - Records - Part 1: Core, version 1.0`_ by default. Request Examples ---------------- As the OGC successor to CSW, OGC API - Records is a change in paradigm rooted in lowering the barrier to entry, being webby/of the web, and focusing on developer experience/adoption. JSON and HTML output formats are both supported via the ``f`` parameter. .. code-block:: bash # landing page http://localhost:8000/ # landing page explictly as JSON http://localhost:8000/?f=json # landing page as HTML http://localhost:8000/?f=html # conformance classes http://localhost:8000/conformance # all collections http://localhost:8000/collections # default collection http://localhost:8000/collections/metadata:main # default collection queryables http://localhost:8000/collections/metadata:main/queryables # collection queries # query parameters can be combined (exclusive/AND) # collection query, all records http://localhost:8000/collections/metadata:main/items # collection query, full text search http://localhost:8000/collections/metadata:main/items?q=lorem # collection query, full text search (multiple terms result in an exclusive (AND) search http://localhost:8000/collections/metadata:main/items?q=lorem dolor # collection query, spatial query http://localhost:8000/collections/metadata:main/items?bbox=-142,42,-52,84 # collection query, temporal query http://localhost:8000/collections/metadata:main/items?datetime=2001-10-30/2007-10-30 # collection query, temporal query, before http://localhost:8000/collections/metadata:main/items?datetime=../2007-10-30 # collection query, temporal query, after http://localhost:8000/collections/metadata:main/items?datetime=2007-10-30/.. # collection query, property query http://localhost:8000/collections/metadata:main/items?title=Lorem%20ipsum # collection query, CQL filter http://localhost:8000/collections/metadata:main/items?filter-lang=cql-text&filter=title LIKE '%lorem%' # collection query, limiting results http://localhost:8000/collections/metadata:main/items?limit=1 # collection query, paging http://localhost:8000/collections/metadata:main/items?limit=10&offset=10 # collection query, paging and sorting (default ascending) http://localhost:8000/collections/metadata:main/items?limit=10&offset=10&sortby=title # collection query, paging and sorting (descending) http://localhost:8000/collections/metadata:main/items?limit=10&offset=10&sortby=-title # collection query as CQL JSON (HTTP POST), as curl request curl http://localhost:8000/collections/metadata:main/items --request POST -H "Content-Type: application/json" --data '{ "eq": [{ "property": "title" }, "Lorem ipsum"]}' # collection query as CQL JSON (HTTP POST), limiting results, as curl request curl http://localhost:8000/collections/metadata:main/items?limit=0 --request POST -H "Content-Type: application/json" --data '{ "eq": [{ "property": "title" }, "Lorem ipsum"]}' # collection item as GeoJSON http://localhost:8000/collections/metadata:main/items/{itemId} # collection item as HTML http://localhost:8000/collections/metadata:main/items/{itemId}?f=html # collection item as XML http://localhost:8000/collections/metadata:main/items/{itemId}?f=xml Virtual Collections ------------------- In OGC API - Records, pycsw's global repository is named `metadata:main`, which serves all metadata records from a given pycsw configuration. OGC API - Records support exposes parent metadata as distinct collections, reducing the barrier for users querying on a specific collection, for multiple collections. This functionality is implemented by default and does not require additional setup/configuration by the user. More information on this feature can be found in `RFC 10: OGC API - Records virtual collections support`_. .. _`OGC API - Records - Part 1: Core, version 1.0`: https://ogcapi.ogc.org/records .. _`RFC 10: OGC API - Records virtual collections support`: https://pycsw.org/development/rfc/rfc-10.html ================================================ FILE: docs/odc.rst ================================================ .. _odc: Open Data Catalog Configuration =============================== Open Data Catalog (https://github.com/azavea/Open-Data-Catalog/) is an open data catalog based on Django, Python and PostgreSQL. It was originally developed for OpenDataPhilly.org, a portal that provides access to open data sets, applications, and APIs related to the Philadelphia region. The Open Data Catalog is a generalized version of the original source code with a simple skin. It is intended to display information and links to publicly available data in an easily searchable format. The code also includes options for data owners to submit data for consideration and for registered public users to nominate a type of data they would like to see openly available to the public. pycsw supports binding to an existing Open Data Catalog repository for metadata query. The binding is read-only (transactions are not in scope, as Open Data Catalog manages repository metadata changes in the application proper). Open Data Catalog Setup ----------------------- Open Data Catalog provides CSW functionality using pycsw out of the box (installing ODC will also install pycsw). Settings are defined in https://github.com/azavea/Open-Data-Catalog/blob/master/OpenDataCatalog/settings.py#L165. ODC settings must ensure that ``REGISTRY_PYCSW['repository']['source']`` is set to``hypermap.search.pycsw_repository``. At this point, pycsw is able to read from the Open Data Catalog repository using the Django ORM. ================================================ FILE: docs/opensearch.rst ================================================ .. _opensearch: OpenSearch Support ================== pycsw OpenSearch support is enabled by default. There are two ways to access OpenSearch depending on the deployment pattern chosen. OGC API - Records deployment ---------------------------- .. code-block:: bash http://localhost:8000/opensearch CSW legacy deployment --------------------- HTTP requests must be specified with ``mode=opensearch`` in the base URL for OpenSearch requests, e.g.: .. code-block:: bash http://localhost/pycsw/csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetCapabilities This will return the Description document which can then be `autodiscovered `_. OGC OpenSearch Geo and Time Extensions 1.0 ------------------------------------------ pycsw supports the `OGC OpenSearch Geo and Time Extensions 1.0`_ standard via the following conformance classes: - Core (GeoSpatial Service) ``{searchTerms}``, ``{geo:box}``, ``{startIndex}``, ``{count}`` - Temporal Search core ``{time:start}``, ``{time:end}`` Supported Query Parameters ^^^^^^^^^^^^^^^^^^^^^^^^^^ - ``q`` - ``time`` - ``bbox`` OGC OpenSearch Extension for Earth Observation ---------------------------------------------- pycsw supports the `OGC OpenSearch Extension for Earth Observation`_ standard via the following conformance classes: - Core Supported Query Parameters ^^^^^^^^^^^^^^^^^^^^^^^^^^ - ``eo:cloudCover`` - ``eo:instrument`` - ``eo:orbitDirection`` - ``eo:orbitNumber`` - ``eo:platform`` - ``eo:processingLevel`` - ``eo:productType`` - ``eo:sensorType`` - ``eo:snowCover`` - ``eo:spectralRange`` - ``eo:illuminationElevationAngle`` Mapping of non-19115 Queryable Mappings ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following queryables are implemented as faceted keywords given they are not implemented in generic geospatial metadata standards: - ``eo:productType`` - ``eo:orbitNumber`` - ``eo:orbitDirection`` - ``eo:snowCover`` - ``eo:processingLevel`` This means metadata ingested into pycsw must have these fields implemented as keywords, as per the examples below: .. code-block:: xml eo:productType:S2MSI2A eo:orbitNumber:50 eo:orbitDirection:DESCENDING eo:snowCover:0.0 eo:procesingLevel:Level-2A .. code-block:: xml eo:productType:S2MSI2A eo:orbitNumber:50 eo:orbitDirection:DESCENDING eo:snowCover:0.0 eo:procesingLevel:Level-2A OpenSearch Temporal Queries Implementation ------------------------------------------ By default, pycsw's OpenSearch temporal support will query the Dublin Core ``dc:date`` property as a time instant/single point in time. To enable temporal extent search, set ``profiles=apiso`` which will query the temporal extents of a metadata record (``apiso:TempExtent_begin`` and ``apiso:TempExtent_end``). At the HTTP API level, time is supported via either ``time=t1/t2`` or ``start=t1&stop=t2``. If the ``time`` parameter is present, it will override the ``start`` and ``stop`` parameters respectively. .. _`OGC OpenSearch Extension for Earth Observation`: https://docs.ogc.org/is/13-026r9/13-026r9.html .. _`OGC OpenSearch Geo and Time Extensions 1.0`: https://www.ogc.org/standards/opensearchgeo ================================================ FILE: docs/outputschemas.rst ================================================ .. _outputschemas: Output Schema Plugins ===================== Overview -------- pycsw allows for extending the implementation of output schemas to the core standard. outputschemas allow for a client to request metadata in a specific format (ISO, Dublin Core, FGDC, NASA DIF Atom and GM03 are default). All outputschemas must be placed in the ``pycsw/plugins/outputschemas`` directory. Requirements ------------ .. code-block:: none pycsw/ plugins/ __init__.py # empty outputschemas/ __init__.py # __all__ is a list of all provided outputschemas atom.py # default dif.py # default fgdc.py # default gm03.py # default Implementing a new outputschema ------------------------------- Create a file in ``pycsw/plugins/outputschemas``, which defines the following: - ``NAMESPACE``: the default namespace of the outputschema which will be advertised - ``NAMESPACE``: dict of all applicable namespaces to outputschema - ``XPATH_MAPPINGS``: dict of pycsw core queryables mapped to the equivalent XPath of the outputschema - ``write_record``: function which returns a record as an ``lxml.etree.Element`` object Add the name of the file to ``__init__.py:__all__``. The new outputschema is now supported in pycsw. Testing ------- New outputschemas must add examples to the :ref:`tests` interface, which must provide example requests specific to the profile. ================================================ FILE: docs/profiles.rst ================================================ .. _profiles: Profile Plugins =============== Overview -------- pycsw allows for the implementation of profiles to the core standard. Profiles allow specification of additional metadata format types (i.e. ISO 19139:2007, NASA DIF, INSPIRE, etc.) to the repository, which can be queried and presented to the client. pycsw supports a plugin architecture which allows for runtime loading of Python code. All profiles must be placed in the ``pycsw/plugins/profiles`` directory. Requirements ------------ .. code-block:: none pycsw/ plugins/ __init__.py # empty profiles/ # directory to store profiles __init__.py # empty profile.py # defines abstract profile object (properties and methods) and functions to load plugins apiso/ # profile directory __init__.py # empty apiso.py # profile code ... # supporting files, etc. Abstract Base Class Definition ------------------------------ All profile code must be instantiated as a subclass of ``profile.Profile``. Below is an example to add a ``Foo`` profile: .. code-block:: python from pycsw.plugins.profiles import profile class FooProfile(profile.Profile): profile.Profile.__init__(self, name='foo', version='1.0.3', title='My Foo Profile', url='http://example.org/fooprofile/docs', namespace='http://example.org/foons', typename='foo:RootElement', outputschema=http://example.org/foons', prefixes=['foo'], model=model, core_namespaces=namespaces, added_namespaces={'foo': 'http://example.org/foons'} repository=REPOSITORY['foo:RootElement']) Your profile plugin class (``FooProfile``) must implement all methods as per ``profile.Profile``. Profile methods must always return ``lxml.etree.Element`` types, or ``None``. Enabling Profiles ----------------- All profiles are disabled by default. To specify profiles at runtime, set the ``profiles`` value in the :ref:`configuration` to the name of the package (in the ``pycsw/plugins/profiles`` directory). To enable multiple profiles, specify as a comma separated value (see :ref:`configuration`). Testing ------- Profiles must add examples to the :ref:`tests` interface, which must provide example requests specific to the profile. Supported Profiles ================== .. include:: ../pycsw/plugins/profiles/apiso/docs/apiso.rst .. include:: ../pycsw/plugins/profiles/ebrim/docs/ebrim.rst ================================================ FILE: docs/pubsub.rst ================================================ .. _pubsub: Publish-Subscribe integration (Pub/Sub) ======================================= pycsw supports Publish-Subscribe (Pub/Sub) integration by implementing the `OGC API Publish-Subscribe Workflow - Part 1: Core`_ (draft) specification. Pub/Sub integration can be enabled by defining a broker that pycsw can use to publish notifications on given topics using CloudEvents (as per the specification). When enabled, core functionality of Pub/Sub includes: - displaying the broker link in the OGC API - Records landing (using the ``rel=hub`` link relation) - sending a notification message on metadata transactions (create, replace, update, delete) The following message queuing protocols are supported: MQTT ---- Example directive: .. code-block:: yaml pubsub: broker: type: mqtt url: mqtt://localhost:1883 channel: messages/a/data # optional show_link: false # default true HTTP ---- Example directive: .. code-block:: yaml pubsub: broker: type: http url: https://ntfy.sh channel: messages-a-data # optional show_link: true # default true .. note:: For any Pub/Sub endpoints requiring authentication, encode the ``url`` value as follows: * ``mqtt://username:password@localhost:1883`` * ``https://username:password@localhost`` As with any section of the pycsw configuration, environment variables may be used as needed, for example to set username/password information in a URL. If ``pubsub.broker.url`` contains authentication, and ``pubsub.broker.show_link`` is ``true``, the authentication information will be stripped from the URL before displaying it on the landing page. .. note:: If a ``channel`` is defined, it is used as a prefix to the relevant OGC API endpoint is used. If a ``channel`` is not defined, only the relevant OGC API endpoint is used. .. _`OGC API Publish-Subscribe Workflow - Part 1: Core`: https://docs.ogc.org/DRAFTS/25-030.html ================================================ FILE: docs/repofilters.rst ================================================ .. _repofilters: Repository Filters ================== pycsw has the ability to perform server side repository / database filters as a means to mask all requests to query against a specific subset of the metadata repository, thus providing the ability to deploy multiple pycsw instances pointing to the same database in different ways via the ``repository.filter`` configuration option. Repository filters are a convenient way to subset your repository at the server level without the hassle of creating proper database views. For large repositories, it may be better to subset at the database level for performance. Scenario: One Database, Many Views ---------------------------------- Imagine a sample database table of records (subset below for brevity): .. csv-table:: :header: identifier,parentidentifier,title,abstract 1,33,foo1,bar1 2,33,foo2,bar2 3,55,foo3,bar3 4,55,foo1,bar1 5,21,foo5,bar5 5,21,foo6,bar6 A default pycsw instance (with no ``repository.filters`` option) will always process requests against the entire table. So a CSW `GetRecords` filter like: .. code-block:: xml apiso:Title foo1 ...will return: .. csv-table:: :header: identifier,parentidentifier,title,abstract 1,33,foo1,bar1 4,55,foo1,bar1 Suppose you wanted to deploy another pycsw instance which serves metadata from the same database, but only from a specific subset. Here we set the ``repository.filter`` option: .. code-block:: yaml repository: database: sqlite:///records.db filter: pycsw:ParentIdentifier = '33' The same CSW `GetRecords` filter as per above then yields the following results: .. csv-table:: :header: identifier,parentidentifier,title,abstract 1,33,foo1,bar1 Another example: .. code-block:: text repository:0 database: sqlite:///records.db filter: "pycsw:ParentIdentifier != '33'" The same CSW `GetRecords` filter as per above then yields the following results: .. csv-table:: :header: identifier,parentidentifier,title,abstract 4,55,foo1,bar1 The ``repository.filter`` option accepts all core queryables set in the pycsw core model (see ``pycsw.config.StaticContext.md_core_model`` for the complete list). ================================================ FILE: docs/repositories.rst ================================================ .. _repositories: Repository Plugins ================== Overview -------- pycsw allows for the implementation of custom repositories in order to connect to a backend different from the pycsw's default. This is especially useful when downstream applications manage their own metadata model/database/document store and want pycsw to connect to it directly instead of using pycsw's default model, thus creating duplicate repositories which then require syncronization/accounting. Repository plugins enable a single metadata backend which is independent from the pycsw setup. pycsw thereby becomes a pure wrapper around a given backend in providing OGC API - Records, CSW and other APIs atop a given application. All outputschemas must be placed in the ``pycsw/plugins/outputschemas`` directory. Requirements ------------ Repository plugins: - can be developed and referenced / connected external to pycsw - must be accessible within the ``PYTHONPATH`` of a given application - must implement pycsw's ``pycsw.core.repository.Repository`` properties and methods - must be specified in the pycsw :ref:`configuration` as a class reference (e.g. ``path.to.repo_plugin.MyRepository``) - must minimally implement the ``query_insert``, ``query_domain``, ``query_ids``, and ``query`` methods Configuration ------------- - set pycsw's ``repository.source`` setting to the class which implements the custom repository: .. code-block:: yaml repository: mappings: 'path.to.repo_plugin.MyRepository' ================================================ FILE: docs/requirements-mocked.txt ================================================ # This file holds some fake requirements to fool the readthedocs service into # building the documentation. For more information, see # https://github.com/geopython/pycsw/issues/521 sphinx ================================================ FILE: docs/sitemaps.rst ================================================ .. _sitemaps: XML Sitemaps ============ `XML Sitemaps`_ can be generated by running: .. code-block:: bash pycsw-admin.py gen-sitemap --config default.yml --output sitemap.xml The ``sitemap.xml`` file should be saved to an an area on your web server (parallel to or above your pycsw install location) to enable web crawlers to index your repository. .. _`XML Sitemaps`: https://www.sitemaps.org/index.html ================================================ FILE: docs/soap.rst ================================================ .. _soap: SOAP ==== pycsw's CSW implementation supports handling of SOAP encoded requests and responses as per subclause 10.3.2 of OGC:CSW 2.0.2. SOAP request examples can be found in ``tests/index.html``. ================================================ FILE: docs/sru.rst ================================================ .. _sru: Search/Retrieval via URL (SRU) Support ====================================== pycsw supports the `Search/Retrieval via URL`_ search protocol implementation as per subclause 8.4 of the OpenGIS Catalogue Service Implementation Specification. SRU support is enabled by default. There are two ways to access SRU depending on the deployment pattern chosen. OGC API - Records deployment ---------------------------- .. code-block:: bash http://localhost:8000/sru CSW legacy deployment --------------------- HTTP GET requests must be specified with ``mode=sru`` for SRU requests, e.g.: .. code-block:: bash http://localhost/pycsw/csw.py?mode=sru&operation=searchRetrieve&query=foo See https://www.loc.gov/standards/sru/misc/simple.html for example SRU requests. .. _`Search/Retrieval via URL`: https://www.loc.gov/standards/sru ================================================ FILE: docs/stac.rst ================================================ .. _stac: SpatioTemporal Asset Catalog (STAC) API Support =============================================== Versions -------- pycsw supports `SpatioTemporal Asset Catalog API version v1.0.0`_ by default. pycsw implements provides STAC support in the following manner: * a pycsw repository is equivalent to a STAC collection * pycsw metadata records are equivalent to STAC items The STAC specification is designed with the same principles as OGC API - Records. Implementation -------------- The following design patterns are put forth for STAC support: Collections ^^^^^^^^^^^ * any pycsw record that is ingested as a STAC Collection will appear on ``/stac/collections`` as a collection Search ^^^^^^ * In addition to OGC API - Records ``/collections/metadata:main/items`` search, STAC API specific searches are realized via ``/stac/search`` which conforms to the STAC API items-search conformance class. Filtering ^^^^^^^^^ STAC API filtering is realized by `OGC Common Query Language (CQL2)`_ via HTTP GET and POST. For GET requests, the `filter=` query parameter can be used. For POST requests, a JSON payload with a `filter` property expressing the CQL2 can be used. Links and Assets ^^^^^^^^^^^^^^^^ STAC support will render links as follows: * links that are enclosures will be encoded as STAC assets (in ``assets``) * all other links remain as record links (in ``links``) Transactions ^^^^^^^^^^^^ STAC Transactions are supported as per the following STAC API specifications: * `STAC API - Transaction Extension Specification`_. * `STAC API - Collection Transaction Extension`_. Request Examples ---------------- .. code-block:: bash # landing page http://localhost:8000/stac # collections http://localhost:8000/stac/collections # collection queries # query parameters can be combined (exclusive/AND) # landing page http://localhost:8000/stac # OpenAPI http://localhost:8000/stac/openapi # collections http://localhost:8000/stac/collections # collections query, full text search http://localhost:8000/stac/collections?q=sentinel # collections query, spatial query http://localhost:8000/stac/collections?bbox=-142,42,-52,84 # collections query, full text search and spatial query http://localhost:8000/stac/collections?q=sentinel,bbox=-142,42,-52,84 # collections query, limiting results http://localhost:8000/stac/collections?limit=2 # collections query, spatial query # single collection http://localhost:8000/stac/collections/metadata:main # collection queryables, all records http://localhost:8000/stac/queryables # collection query, all records http://localhost:8000/stac/search # collection query, full text search http://localhost:8000/stac/search?q=lorem # collection query, spatial query http://localhost:8000/stac/search?bbox=-142,42,-52,84 # collection query, temporal query http://localhost:8000/stac/search?datetime=2001-10-30/2007-10-30 # collection query, temporal query, before http://localhost:8000/stac/search?datetime=../2007-10-30 # collection query, temporal query, after http://localhost:8000/stac/search?datetime=2007-10-30/.. # collection query, property query http://localhost:8000/stac/search?title=Lorem%20ipsum # collection query, CQL filter http://localhost:8000/stac/search?filter=title like "%lorem%" # collection query, limiting results http://localhost:8000/stac/search?limit=1 # collection filter query, limiting results http://localhost:8000/stac/search?limit=1&collections=landsat # collection ids filter query, limiting results http://localhost:8000/stac/search?limit=1&ids=id1,id2 # collection query, paging http://localhost:8000/stac/search?limit=10&offset=10 # collection query, paging and sorting (default ascending) http://localhost:8000/stac/search?limit=10&offset=10&sortby=title # collection query, paging and sorting (descending) http://localhost:8000/stac/search?limit=10&offset=10&sortby=-title # collection item as GeoJSON http://localhost:8000/stac/collections/metadata:main/items/{itemId} # CQL2 JSON (as curl commands) # search by creation date curl --location --request POST 'http://localhost:8000/stac/search' \ --header 'Content-Type: application/query-cql-json' \ --data-raw '{ "filter-lang": "cql2-json", "filter": { "op": "<=", "args": [ { "property": "date_creation" }, "2025-12-15" ] } }' # search by creation date curl --location --request POST 'http://localhost:8000/stac/search' \ --header 'Content-Type: application/query-cql-json' \ --data-raw '{ "filter-lang": "cql2-json", "filter": { "op": "and", "args": [ { "op": "in", "args": [ { "property": "parentidentifier" }, [ "sentinel-2-l2a" ] ] } ] } }' .. _`SpatioTemporal Asset Catalog API version v1.0.0`: https://github.com/radiantearth/stac-api-spec .. _`STAC API - Transaction Extension Specification`: https://github.com/stac-api-extensions/transaction .. _`STAC API - Collection Transaction Extension`: https://github.com/stac-api-extensions/collection-transaction .. _`OGC Common Query Language (CQL2)`: https://docs.ogc.org/is/21-065r2/21-065r2.html ================================================ FILE: docs/support.rst ================================================ .. _support: Support ======= Community --------- Please see the `Community`_ page for information on the pycsw community, getting support, and how to get involved. .. _`Community`: https://pycsw.org/community ================================================ FILE: docs/testing.rst ================================================ .. _tests: Testing ======= There are a number of test suites that perform mostly functional testing. These tests ensure that pycsw operates correctly and is compliant with the various supported standards. There is also a growing set of unit tests. These focus on smaller scope testing, in order to verify that individual bits of code are working as expected. Tests can be run locally as part of the development cycle. They are also run on pycsw's `GitHub Actions`_ continuous integration setup against all pushes and pull requests to the code repository. pycsw uses `pytest`_ for managing its automated tests. Install pytest from the development requirements. .. code:: bash pip3 install -r requirements-dev.txt OGC API - Records ----------------- Tests for OGC API - Records are located in ``tests/functionaltests/suites/oarec``. They can be run as follows: .. code:: bash pytest tests/functionaltests/suites/oarec OGC CSW ------- Tests for OGC CSW are located in ``tests/functionaltests/suites/csw30``. They can be run as follows: .. code:: bash pytest tests/functionaltests/suites/csw30 .. _ogc-cite: OGC CITE -------- In addition to pycsw's own tests, all public releases are also tested via the OGC `Compliance & Interoperability Testing & Evaluation Initiative`_ (CITE). The pycsw `wiki`_ documents CITE testing procedures and status. Tests for OGC CITE are located in ``tests/functionaltests/suites/cite``. They can be run as follows: .. code:: bash pytest tests/functionaltests/suites/cite Functional test suites ---------------------- Most of pycsw's tests are `functional tests`_. This means that each test case is based on the requirements mandated by the specifications of the various standards that pycsw implements. These tests focus on making sure that pycsw works as expected. Suites for xml-based standards (CSW, ATOM, etc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A number of different test suites exist under ``tests/functionaltests/suites``. Each suite specifies the following structure: * A mandatory ``default.yml`` file with the pycsw configuration that must be used by the test suite; * A mandatory ``expected/`` directory containing the expected results for each request; * An optional ``data/`` directory that contains ``.xml`` files with testing data that is to be loaded into the suite's database before running the tests. The presence of this directory and its contents have the following meaning for tests: * If ``data/`` directory is present and contains files, they will be loaded into a new database for running the tests of the suite; * If ``data/`` directory is present and does not contain any data files, a new empty database is used in the tests; * If ``data/`` directory is absent, the suite will use a database populated with test data from the ``CITE`` suite. * An optional ``get/requests.txt`` file that holds request parameters used for making HTTP GET requests. Each line in the file must be formatted with the following scheme: test_id,request_query_string For example: TestGetCapabilities,service=CSW&version=2.0.2&request=GetCapabilities When tests are run, the *test_id* is used for naming each test and for finding the expected result. * An optional ``post/`` directory that holds ``.xml`` files used for making HTTP POST requests Test generation uses pytest's `pytest_generate_tests`_ function. This function is implemented in `tests/functionaltests/conftest.py`. It provides an automatic parametrization of the `tests/functionaltests/test_suites_functional:test_suites` test. This parametrization causes the generation of a test for each of the GET and POST requests defined in a suite's directory. Suites for JSON-based standards (OGC API - Records, STAC API, etc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ These are implemented as simple pytest-based tests, for which no custom test generation function exists. They are simpler to generate - look into the implementation in `tests/functionaltests/suites/oarec` for examples. Unit tests ---------- pycsw also features unit tests. These deal with testing the expected behaviour of individual functions. The usual implementation of unit tests is to import the function/method under test, run it with a set of known arguments and assert that the result matches the expected outcome. Unit tests are defined in `pycsw/tests/unittests/`. pycsw's unit tests are marked with the `unit` marker. This makes it easy to run them in isolation: .. code:: bash # running only the unit tests (not the functional ones) pytest -m unit Running tests ------------- Since pycsw uses `pytest`_, tests are run with the ``pytest`` runner. A basic test run can be made with: .. code:: bash pytest This command will run all tests and report on the number of successes, failures and also the time it took to run them. The `pytest` command accepts several additional parameters that can be used in order to customize the execution of tests. Look into `pytest's invocation documentation`_ for a more complete description. You can also get a description of the available parameters by running: .. code:: bash pytest --help Running specific suites and test cases ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pytest allows tagging tests with markers. These can be used to selectively run some tests. pycsw uses two markers: * ``unit`` - run only input tests * ``functional``- run only functional tests Markers can be specified by using the ``-m `` flag. .. code:: bash pytest -m functional # run only functional tests You can also use the ``-k `` flag to select which tests to run. Since each test's name includes the suite name, http method and an identifier for the test, it is easy to run only certain tests. .. code:: bash pytest -k "apiso and GetRecords" # run only tests from the apiso suite that have GetRecords in their name pytest -k "post and GetRecords" # run only tests that use HTTP POST and GetRecords in their name pytest -k "not harvesting" # run all tests except those from the harvesting suite The ``-m`` and ``-k`` flags can be combined. Exiting fast ^^^^^^^^^^^^ The ``--exitfirst`` (or ``-x``) flag can be used to stop the test runner immediately as soon as a test case fails. .. code:: bash pytest --exitfirst Seeing more output ^^^^^^^^^^^^^^^^^^ There are three main ways to get more output from running tests: * The ``--verbose`` (or ``-v``) flag; * The ``--capture=no`` flag - Messages sent to stdout by a test are not suppressed; * The ``--pycsw-loglevel`` flag - Sets the log level of the pycsw instance under test. Set this value to ``debug`` in order to see all debug messages sent by pycsw while processing a request. .. code:: bash pytest --verbose pytest --pycsw-loglevel=debug pytest -v --capture=no --pycsw-loglevel=debug Comparing xml-based suite results with difflib instead of XML c14n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Functional tests for XML-based suites compare results with their expected values by using `XML canonicalisation - XML c14n`_. Alternatively, you can call pytest with the ``--functional-prefer-diffs`` flag. This will enable comparison based on Python's ``difflib``. Comparison is made on a line-by-line basis and in case of failure, a unified diff will be printed to standard output. .. code:: bash pytest -m functional -k 'harvesting' --functional-prefer-diffs Saving test results for disk ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The result of each XML-based suite test can be saved to disk by using the ``--functional-save-results-directory`` option. Each result file is named after the test identifier it has when running with pytest. .. code:: bash pytest -m functional -k 'not harvesting' --functional-save-results-directory=/tmp/pycsw-test-results Test coverage ^^^^^^^^^^^^^ Use the `--cov pycsw` flag in order to see information on code coverage. It is possible to get output in a variety of formats. .. code:: bash pytest --cov pycsw Specifying a timeout for tests ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The `--timeout ` option can be used to specify that if a test takes more than `` to run it is considered to have failed. Seconds can be a float, so it is possibe to specify sub-second timeouts .. code:: bash pytest --timeout=1.5 Linting with flake8 ^^^^^^^^^^^^^^^^^^^ Use the `--flake8` flag to also check if the code complies with Python's style guide .. code:: bash pytest --flake8 Testing multiple Python versions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For testing multiple Python versions and configurations simultaneously you can use `tox`_. pycsw includes a `tox.ini` file with a suitable configuration. It can be used to run tests against multiple Python versions and also multiple database backends. When running `tox` you can send arguments to the `pytest` runner by using the invocation `tox -- `. Examples: .. code:: bash # install tox on your system sudo pip3 install tox # run all tests on multiple Python versions against all databases, # with default arguments tox # run tests only with python3.7 and using sqlite as backend tox -e py37 -sqlite # run only csw30 suite tests with python3.7 and postgresql as backend tox -e py37-postgresql -- -k 'csw30' Web Testing ^^^^^^^^^^^ You can also use the pycsw tests via your web browser to perform sample requests against your pycsw install. The tests are is located in ``tests/``. To generate the HTML page: .. code-block:: bash python3 gen_html.py > index.html Then navigate to ``http://host/path/to/pycsw/tests/index.html``. .. _Compliance & Interoperability Testing & Evaluation Initiative: https://github.com/opengeospatial/cite/wiki .. _functional tests: https://en.wikipedia.org/wiki/Functional_testing .. _pytest's invocation documentation: https://docs.pytest.org/en/stable/usage.html .. _pytest: https://docs.pytest.org .. _Github Actions: https://github.com/geopython/pycsw/actions .. _tox: https://tox.readthedocs.io .. _wiki: https://github.com/geopython/pycsw/wiki/OGC-CITE-Compliance .. _pytest_generate_tests: #basic-pytest-generate-tests-example .. _XML canonicalisation - XML c14n: https://www.w3.org/TR/xml-c14n/ ================================================ FILE: docs/tools.rst ================================================ .. _tools: Cataloguing and Metadata Tools ============================== OGC API - Records Clients and Servers ------------------------------------- - `OGC API - Records official implementations `_ CSW Clients ----------- - `Geoportal CSW Clients `_ - `OWSLib `_ - `QGIS MetaSearch `_ CSW Servers ----------- - `deegree `_ - `GeoNetwork opensource `_ Metadata Editing Tools ---------------------- - `pygeometa `_ - `CatMDEdit `_ - `EUOSME `_ - `GIMED `_ - `Metatools `_ (`QGIS `_ plugin) ================================================ FILE: docs/transactions.rst ================================================ .. _transactions: Transactions using CSW ====================== pycsw's CSW implementation has the ability to process CSW Harvest and Transaction requests (CSW-T). Transactions are disabled by default; to enable, ``manager.transactions`` must be set to ``true``. Access to transactional functionality is limited to IP addresses which must be set in ``manager.allowed_ips``. Supported Resource Types ------------------------ For transactions and harvesting, pycsw supports the following metadata resource types by default: .. csv-table:: :header: Resource Type,Namespace,Transaction,Harvest Dublin Core,``http://www.opengis.net/cat/csw/2.0.2``,yes,yes FGDC,``http://www.opengis.net/cat/csw/csdgm``,yes,yes GM03,``http://www.interlis.ch/INTERLIS2.3``,yes,yes ISO 19139,``http://www.isotc211.org/2005/gmd``,yes,yes ISO GMI,``http://www.isotc211.org/2005/gmi``,yes,yes OGC:CSW 2.0.2,``http://www.opengis.net/cat/csw/2.0.2``,,yes OGC:WMS 1.1.1/1.3.0,``http://www.opengis.net/wms``,,yes OGC:WMTS 1.0.0,``http://www.opengis.net/wmts/1.0``,,yes OGC:WFS 1.0.0/1.1.0/2.0.0,``http://www.opengis.net/wfs``,,yes OGC:WCS 1.0.0,``http://www.opengis.net/wcs``,,yes OGC:WPS 1.0.0,``http://www.opengis.net/wps/1.0.0``,,yes OGC:SOS 1.0.0,``http://www.opengis.net/sos/1.0``,,yes OGC:SOS 2.0.0,``http://www.opengis.net/sos/2.0``,,yes `WAF`_,``urn:geoss:waf``,,yes Additional metadata models are supported by enabling the appropriate :ref:`profiles`. .. note:: For transactions to be functional when using SQLite3, the SQLite3 database file (**and its parent directory**) must be fully writable. For example: .. code-block:: bash $ mkdir /path/data $ chmod 777 /path/data $ chmod 666 test.db $ mv test.db /path/data For CSW-T deployments, it is strongly advised that this directory reside in an area that is not accessible by HTTP. Harvesting ---------- .. note:: Your server must be able to make outgoing HTTP requests for this functionality. pycsw supports the CSW-T ``Harvest`` operation. Records which are harvested require to setup a cronjob to periodically refresh records in the local repository. A sample cronjob is available in ``etc/harvest-all.cron`` which points to ``pycsw-admin.py`` (you must specify the correct path to your configuration). Harvest operation results can be sent by email (via ``mailto:``) or ftp (via ``ftp://``) or ftps (via ``ftps://``) if the Harvest request specifies ``csw:ResponseHandler``. .. note:: For ``csw:ResponseHandler`` values using the ``mailto:`` protocol, you must have ``server.smtp_host`` set in your :ref:`configuration `. OGC Web Services ^^^^^^^^^^^^^^^^ When harvesting OGC web services, requests can provide the base URL of the service as part of the Harvest request. pycsw will construct a ``GetCapabilities`` request dynamically. When harvesting other CSW servers, pycsw pages through the entire CSW in default increments of 10. This value can be modified via the ``manager.csw_harvest_pagesize`` :ref:`configuration ` option. It is strongly advised to use the ``csw:ResponseHandler`` parameter for harvesting large CSW catalogues to prevent HTTP timeouts. Transaction operations ---------------------- pycsw supports 3 modes of the ``Transaction`` operation (``Insert``, ``Update``, ``Delete``): - **Insert**: full XML documents can be inserted as per CSW-T - **Update**: updates can be made as full record updates or record properties against a ``csw:Constraint`` - **Delete**: deletes can be made against a ``csw:Constraint`` Transaction operation results can be sent by email (via ``mailto:``) or ftp (via ``ftp://``) or ftps (via ``ftps://``) if the Transaction request specifies ``csw:ResponseHandler``. The :ref:`tests` contain CSW-T request examples. .. _`WAF`: https://seabass.ieee.org/groups/geoss/index.php?option=com_sir_200&Itemid=157&ID=183 Transactions using OGC API - Records ==================================== pycsw's OGC API - Records support provides transactional capabilities via the `OGC API - Features - Part 4: Create, Replace, Update and Delete`_ draft specification, which follows RESTful patterns for insert/update/delete of resources. Supported Resource Types ------------------------ All resource types supported by CSW Transactions are supported via OGC API - Records transactional workflow. Note that the HTTP ``Content-Type`` header MUST be set according to the media type of the given resource (i.e. ``application/json``, ``application/xml``, etc.). Transaction operations ---------------------- The below examples demonstrate transactional workflow using pycsw's OGC API - Records endpoint: .. code-block:: bash # insert GeoJSON metadata curl -v -H "Content-Type: application/geo+json" -XPOST http://localhost:8000/collections/metadata:main/items -d @foorecord.json # update metadata curl -v -H "Content-Type: application/geo+json" -XPUT http://localhost:8000/collections/metadata:main/items/foorecord -d @foorecord.json # delete metadata curl -v -XDELETE http://localhost:8000/collections/metadata:main/items/foorecord # insert XML metadata curl -v -H "Content-Type: application/xml" -XPOST http://localhost:8000/collections/metadata:main/items -d @foorecord.xml Harvesting ---------- Harvesting is not yet supported via OGC API - Records. Transactions using STAC API =========================== pycsw's STAC API support provides transactional capabilities via the `STAC API - Transaction Extension Specification`_ and `STAC API - Collection Transaction Extension`_ specifications, which follows RESTful patterns for insert/update/delete of resources. Supported Resource Types ------------------------ STAC Collections, Items and Item Collections are supported via OGC API - Records transactional workflow. Note that the HTTP ``Content-Type`` header MUST be set to (i.e. ``application/json``). Transaction operations ---------------------- The below examples demonstrate transactional workflow using pycsw's OGC API - Records endpoint: .. code-block:: bash # insert STAC Item curl -v -H "Content-Type: application/json" -XPOST http://localhost:8000/stac/collections/metadata:main/items -d @fooitem.json # update STAC Item curl -v -H "Content-Type: application/json" -XPUT http://localhost:8000/stac/collections/metadata:main/items/fooitem -d @fooitem.json # delete STAC Item curl -v -XDELETE http://localhost:8000/stac/collections/metadata:main/items/fooitem # insert STAC Item Collection curl -v -H "Content-Type: application/json" -XPOST http://localhost:8000/stac/collections/metadata:main/items -d @fooitemcollection.json # insert STAC Collection curl -v -H "Content-Type: application/json" -XPOST http://localhost:8000/stac/collections -d @foocollection.json # update STAC Collection curl -v -H "Content-Type: application/json" -XPUT http://localhost:8000/stac/collections/foocollection -d @foocollection.json # delete STAC Collection curl -v -XDELETE http://localhost:8000/stac/collections/foocollection .. _`OGC API - Features - Part 4: Create, Replace, Update and Delete`: https://docs.ogc.org/DRAFTS/20-002.html .. _`STAC API - Transaction Extension Specification`: https://github.com/stac-api-extensions/transaction .. _`STAC API - Collection Transaction Extension`: https://github.com/stac-api-extensions/collection-transaction ================================================ FILE: docs/xslt.rst ================================================ .. _xslt: XSLT Support ============ By default, pycsw performs metadata transformations using a generic framework that attempts to cover generic use cases. pycsw users can also specify custom XSLT transformations for specific use cases or communities. To specify a custom XSLT transformation, you must map to input and output outputschemas supported by pycsw, where the input outputschema must match the metadata as ingested and stored in the repository. .. code-block:: yaml xslt: - input_os: http://www.opengis.net/cat/csw/2.0.2 output_os: http://www.isotc211.org/2005/gmd transform: tests/functionaltests/suites/xslt/custom.xslt The ``xslt`` directive must point to a valid XSLT document on disk. .. note:: You may also use environment variables to point to XSLT files. ================================================ FILE: etc/harvest-all.cron ================================================ # run cronjob daily at 0400h # # info on setting up cron at http://www.unixgeeks.org/security/newbie/unix/cron-1.html 00 04 * * * /path/to/pycsw-admin.py refresh-harvested-records --config /path/to/default.yml ================================================ FILE: etc/mappings.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= # sample mappings.py # # use this file to bind to an existing alternate metadata database model # # steps: # - update the 'mappings' dict to the column names of your existing database # - set repository.mappings to the location of this file MD_CORE_MODEL = { 'typename': 'pycsw:CoreMetadata', 'outputschema': 'http://pycsw.org/metadata', 'mappings': { 'pycsw:Identifier': 'identifier', 'pycsw:Typename': 'typename', 'pycsw:Schema': 'schema', 'pycsw:MdSource': 'mdsource', 'pycsw:InsertDate': 'insert_date', 'pycsw:XML': 'xml', 'pycsw:AnyText': 'anytext', 'pycsw:Language': 'language', 'pycsw:Title': 'title', 'pycsw:Abstract': 'abstract', 'pycsw:Keywords': 'keywords', 'pycsw:KeywordType': 'keywordstype', 'pycsw:Themes': 'themes', 'pycsw:Format': 'format', 'pycsw:Source': 'source', 'pycsw:Date': 'date', 'pycsw:Modified': 'date_modified', 'pycsw:Type': 'type', 'pycsw:BoundingBox': 'wkt_geometry', 'pycsw:CRS': 'crs', 'pycsw:AlternateTitle': 'title_alternate', 'pycsw:RevisionDate': 'date_revision', 'pycsw:CreationDate': 'date_creation', 'pycsw:PublicationDate': 'date_publication', 'pycsw:OrganizationName': 'organization', 'pycsw:SecurityConstraints': 'securityconstraints', 'pycsw:ParentIdentifier': 'parentidentifier', 'pycsw:TopicCategory': 'topicategory', 'pycsw:ResourceLanguage': 'resourcelanguage', 'pycsw:GeographicDescriptionCode': 'geodescode', 'pycsw:Denominator': 'denominator', 'pycsw:DistanceValue': 'distancevalue', 'pycsw:DistanceUOM': 'distanceuom', 'pycsw:TempExtent_begin': 'time_begin', 'pycsw:TempExtent_end': 'time_end', 'pycsw:ServiceType': 'servicetype', 'pycsw:ServiceTypeVersion': 'servicetypeversion', 'pycsw:Operation': 'operation', 'pycsw:CouplingType': 'couplingtype', 'pycsw:OperatesOn': 'operateson', 'pycsw:OperatesOnIdentifier': 'operatesonidentifier', 'pycsw:OperatesOnName': 'operatesoname', 'pycsw:Degree': 'degree', 'pycsw:AccessConstraints': 'accessconstraints', 'pycsw:OtherConstraints': 'otherconstraints', 'pycsw:Classification': 'classification', 'pycsw:ConditionApplyingToAccessAndUse': 'conditionapplyingtoaccessanduse', 'pycsw:Lineage': 'lineage', 'pycsw:ResponsiblePartyRole': 'responsiblepartyrole', 'pycsw:SpecificationTitle': 'specificationtitle', 'pycsw:SpecificationDate': 'specificationdate', 'pycsw:SpecificationDateType': 'specificationdatetype', 'pycsw:Creator': 'creator', 'pycsw:Publisher': 'publisher', 'pycsw:Contributor': 'contributor', 'pycsw:Relation': 'relation', 'pycsw:Links': 'links', } } ================================================ FILE: etc/migrations/2.x-3.0/migrate.sql ================================================ alter table records add column metadata TEXT; alter table records add column metadata_type TEXT default 'application/xml'; alter table records add column edition TEXT; alter table records add column contacts TEXT; alter table records add column themes TEXT; alter table records add column illuminationelevationangle TEXT; alter table records alter column cloudcover type real using cast(cloudcover as float); alter table records alter column distancevalue type real using cast(distancevalue as float); drop index ix_records_links; vacuum; ================================================ FILE: etc/pycsw ================================================ Options FollowSymLinks +ExecCGI Allow from all AddHandler cgi-script .py ================================================ FILE: etc/pycsw.conf ================================================ Options +FollowSymLinks +ExecCGI Require all granted AddHandler cgi-script .py ================================================ FILE: etc/pycsw.desktop ================================================ [Desktop Entry] Type=Application Encoding=UTF-8 Name=pycsw Comment=pycsw catalog server Exec=xdg-open http://localhost/pycsw/tests/index.html Icon=/var/www/html/pycsw/docs/_static/pycsw-logo.png Terminal=false StartupNotify=false Categories=Education;Geography; ================================================ FILE: pycsw/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Ricardo Garcia Silva # # Copyright (c) 2024 Tom Kralidis # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= __version__ = '3.0-dev' ================================================ FILE: pycsw/broker/__init__.py ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2025 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import importlib from pycsw.broker.base import BasePubSubClient def load_client(def_: dict) -> BasePubSubClient: """ Load Pub/Sub client plugin :param def: `dict` of client definition :returns: PubSubClient object """ module, class_ = CLIENTS[def_['type']].rsplit('.', 1) module = importlib.import_module(module) return getattr(module, class_)(def_) CLIENTS = { 'mqtt': 'pycsw.broker.mqtt.MQTTPubSubClient', 'http': 'pycsw.broker.http.HTTPPubSubClient' } ================================================ FILE: pycsw/broker/base.py ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2025 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging import random from urllib.parse import urlparse from pycsw.core.util import remove_url_auth LOGGER = logging.getLogger(__name__) class BasePubSubClient: """Base Pub/Sub client""" def __init__(self, publisher_def: dict): """ Initialize object :param publisher_def: publisher definition :returns: pycsw.broker.base.BasePubSubClient """ self.type = None self.client_id = f'pycsw-pubsub-{random.randint(0, 1000)}' self.channel = publisher_def.get('channel') self.show_link = publisher_def.get('show_link', True) self.broker = publisher_def['url'] self.broker_url = urlparse(publisher_def['url']) self.broker_safe_url = remove_url_auth(self.broker) def connect(self) -> None: """ Connect to a Pub/Sub broker :returns: None """ raise NotImplementedError() def pub(self, channel: str, message: str) -> bool: """ Publish a message to a broker/channel :param channel: `str` of channel :param message: `str` of message :returns: `bool` of publish result """ raise NotImplementedError() def __repr__(self): return f' {self.broker_safe_url}' ================================================ FILE: pycsw/broker/http.py ================================================ # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2025 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging import requests from pycsw.broker.base import BasePubSubClient LOGGER = logging.getLogger(__name__) class HTTPPubSubClient(BasePubSubClient): """HTTP client""" def __init__(self, broker_url): """ Initialize object :param publisher_def: provider definition :returns: pycsw.pubsub.http.HTTPPubSubClient """ super().__init__(broker_url) self.type = 'http' self.auth = None msg = f'Initializing to broker {self.broker_safe_url} with id {self.client_id}' # noqa LOGGER.debug(msg) if None not in [self.broker_url.username, self.broker_url.password]: LOGGER.debug('Setting credentials') self.auth = ( self.broker_url.username, self.broker_url.password ) def connect(self) -> None: """ Connect to an HTTP broker :returns: None """ LOGGER.debug('Passing; connection to HTTP is lazy') def pub(self, channel: str, message: str, qos: int = 1) -> bool: """ Publish a message to a broker/channel :param channel: `str` of topic :param message: `str` of message :returns: `bool` of publish result """ LOGGER.debug(f'Publishing to broker {self.broker_safe_url}') LOGGER.debug(f'Channel: {channel}') LOGGER.debug(f'Message: {message}') LOGGER.debug(f'Sanitizing channel for HTTP') channel = channel.replace('/', '-') channel = channel.replace(':', '-') LOGGER.debug(f'Sanitized channel: {channel}') url = f'{self.broker}/{channel}' try: response = requests.post(url, auth=self.auth, json=message) response.raise_for_status() except Exception as err: LOGGER.debug(f'Message publishing failed: {err}') def __repr__(self): return f' {self.broker_safe_url}' ================================================ FILE: pycsw/broker/mqtt.py ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2025 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from paho.mqtt import client as mqtt_client from pycsw.broker.base import BasePubSubClient LOGGER = logging.getLogger(__name__) class MQTTPubSubClient(BasePubSubClient): """MQTT client""" def __init__(self, broker_url): """ Initialize object :param publisher_def: provider definition :returns: pycsw.pubsub.mqtt.MQTTPubSubClient """ super().__init__(broker_url) self.type = 'mqtt' self.port = self.broker_url.port self.userdata = {} msg = f'Connecting to broker {self.broker_safe_url} with id {self.client_id}' # noqa LOGGER.debug(msg) self.conn = mqtt_client.Client(mqtt_client.CallbackAPIVersion.VERSION2, client_id=self.client_id) self.conn.enable_logger(logger=LOGGER) if None not in [self.broker_url.username, self.broker_url.password]: LOGGER.debug('Setting credentials') self.conn.username_pw_set( self.broker_url.username, self.broker_url.password) if self.port is None: if self.broker_url.scheme == 'mqtts': self.port = 8883 else: self.port = 1883 if self.broker_url.scheme == 'mqtts': self.conn.tls_set(tls_version=2) def connect(self) -> None: """ Connect to an MQTT broker :returns: None """ self.conn.connect(self.broker_url.hostname, self.port) LOGGER.debug('Connected to broker') def pub(self, channel: str, message: str, qos: int = 1) -> bool: """ Publish a message to a broker/channel :param channel: `str` of channel :param message: `str` of message :returns: `bool` of publish result """ LOGGER.debug(f'Publishing to broker {self.broker_safe_url}') LOGGER.debug(f'Channel: {channel}') LOGGER.debug(f'Message: {message}') result = self.conn.publish(channel, message, qos) LOGGER.debug(f'Result: {result}') # TODO: investigate implication # result.wait_for_publish() if result.is_published: LOGGER.debug('Message published') return True else: msg = f'Publishing error code: {result[1]}' LOGGER.warning(msg) return False def __repr__(self): return f' {self.broker_safe_url}' ================================================ FILE: pycsw/core/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/core/admin.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import json import logging import os import sys from glob import glob import click from pycsw import __version__ from pycsw.core import config as pconfig from pycsw.core import metadata, repository, util from pycsw.core.etree import etree from pycsw.core.etree import PARSER from pycsw.core.util import parse_ini_config, str2bool from pycsw.ogc.api.util import get_typed_value, yaml_dump, yaml_load LOGGER = logging.getLogger(__name__) def load_records(context, database, table, xml_dirpath, recursive=False, force_update=False): """Load metadata records from directory of files to database""" repo = repository.Repository(database, context, table=table) file_list = [] loaded_files = set() if os.path.isfile(xml_dirpath): file_list.append(xml_dirpath) elif recursive: for root, dirs, files in os.walk(xml_dirpath): for mfile in files: if mfile.endswith('.xml'): file_list.append(os.path.join(root, mfile)) else: files = glob(os.path.join(xml_dirpath, '*.xml')) + glob(os.path.join(xml_dirpath, '*.json')) for rec in files: file_list.append(rec) total = len(file_list) counter = 0 for recfile in sorted(file_list): counter += 1 metadata_record = None LOGGER.info('Processing file %s (%d of %d)', recfile, counter, total) # read document try: with open(recfile) as fh: metadata_record = json.load(fh) except json.decoder.JSONDecodeError: metadata_record = etree.parse(recfile, context.parser) except etree.XMLSyntaxError: LOGGER.error('XML document "%s" is not well-formed', recfile, exc_info=True) continue except Exception: LOGGER.exception('XML document "%s" is not well-formed', recfile) continue try: record = metadata.parse_record(context, metadata_record, repo) except Exception: LOGGER.exception('Could not parse "%s" as an XML record', recfile) continue for rec in record: LOGGER.info('Inserting %s %s into database %s, table %s ....', rec.typename, rec.identifier, database, table) # TODO: do this as CSW Harvest try: repo.insert(rec, 'local', util.get_today_and_now()) loaded_files.add(recfile) LOGGER.info('Inserted %s', recfile) except Exception as err: if force_update: LOGGER.info('Record exists. Updating.') repo.update(rec) LOGGER.info('Updated %s', recfile) loaded_files.add(recfile) else: if err.args: # Pull a decent error message LOGGER.error('ERROR: %s not inserted: %s', recfile, err.args[0], exc_info=True) else: LOGGER.error('ERROR: %s not inserted: %s', recfile, err, exc_info=True) return tuple(loaded_files) def export_records(context, database, table, xml_dirpath): """Export metadata records from database to directory of files""" repo = repository.Repository(database, context, table=table) LOGGER.info('Querying database %s, table %s ....', database, table) records = repo.session.query(repo.dataset) LOGGER.info('Found %d records\n', records.count()) LOGGER.info('Exporting records\n') dirpath = os.path.abspath(xml_dirpath) exported_files = set() if not os.path.exists(dirpath): LOGGER.info('Directory %s does not exist. Creating...', dirpath) try: os.makedirs(dirpath) except OSError as err: LOGGER.exception('Could not create directory') raise RuntimeError('Could not create %s %s' % (dirpath, err)) from err for record in records.all(): identifier = \ getattr(record, context.md_core_model['mappings']['pycsw:Identifier']) LOGGER.info('Processing %s', identifier) # sanitize identifier identifier = util.secure_filename(identifier) # write to XML document metadata_type = \ getattr(record, context.md_core_model['mappings']['pycsw:MetadataType']) if 'json' in metadata_type: extension = 'json' else: extension = 'xml' filename = os.path.join(dirpath, '%s.%s' % (identifier, extension)) try: LOGGER.info('Writing to file %s', filename) if hasattr(record.xml, 'decode'): str_xml = record.xml.decode('utf-8') else: str_xml = record.xml with open(filename, 'w') as xml: xml.write('\n') xml.write(str_xml) except Exception: # Something went wrong so skip over this file but log an error LOGGER.exception('Error writing %s to disk', filename) # If we wrote a partial file or created an empty file make sure it is removed if os.path.exists(filename): os.remove(filename) continue else: exported_files.add(filename) return tuple(exported_files) def refresh_harvested_records(context, database, table, url): """refresh / harvest all non-local records in repository""" from owslib.csw import CatalogueServiceWeb # get configuration and init repo connection repos = repository.Repository(database, context, table=table) # get all harvested records count, records = repos.query(constraint={'where': "mdsource != 'local'", 'values': []}) if int(count) > 0: LOGGER.info('Refreshing %s harvested records', count) csw = CatalogueServiceWeb(url) for rec in records: source = \ getattr(rec, context.md_core_model['mappings']['pycsw:Source']) schema = \ getattr(rec, context.md_core_model['mappings']['pycsw:Schema']) identifier = \ getattr(rec, context.md_core_model['mappings']['pycsw:Identifier']) LOGGER.info('Harvesting %s (identifier = %s) ...', source, identifier) # TODO: find a smarter way of catching this if schema == 'http://www.isotc211.org/2005/gmd': schema = 'http://www.isotc211.org/schemas/2005/gmd/' try: csw.harvest(source, schema) LOGGER.info(csw.response) except Exception: LOGGER.exception('Could not harvest') else: LOGGER.info('No harvested records') def gen_sitemap(context, database, table, url, output_file): """generate an XML sitemap from all records in repository""" # get configuration and init repo connection repos = repository.Repository(database, context, table=table) # write out sitemap document urlset = etree.Element(util.nspath_eval('sitemap:urlset', context.namespaces), nsmap=context.namespaces) schema_loc = util.nspath_eval('xsi:schemaLocation', context.namespaces) urlset.attrib[schema_loc] = \ '%s http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd' % \ context.namespaces['sitemap'] # get all records count, records = repos.query(constraint={}, maxrecords=99999999) LOGGER.info('Found %s records', count) for rec in records: url_ = etree.SubElement(urlset, util.nspath_eval('sitemap:url', context.namespaces)) uri = '%s?service=CSW&version=2.0.2&request=GetRepositoryItem&id=%s' % \ (url, getattr(rec, context.md_core_model['mappings']['pycsw:Identifier'])) etree.SubElement(url_, util.nspath_eval('sitemap:loc', context.namespaces)).text = uri # write to file LOGGER.info('Writing to %s', output_file) with open(output_file, 'wb') as ofile: ofile.write(etree.tostring(urlset, pretty_print=1, encoding='utf8', xml_declaration=1)) def post_xml(url, xml, timeout=30): """Execute HTTP XML POST request and print response""" LOGGER.info('Executing HTTP POST request %s on server %s', xml, url) from owslib.util import http_post try: with open(xml) as f: return http_post(url=url, request=f.read(), timeout=timeout) except Exception as err: LOGGER.exception('HTTP XML POST error') raise RuntimeError(err) from err def get_sysprof(): """Get versions of dependencies""" none = 'Module not found' try: import sqlalchemy vsqlalchemy = sqlalchemy.__version__ except ImportError: vsqlalchemy = none try: import pyproj vpyproj = pyproj.__version__ except ImportError: vpyproj = none try: import shapely try: vshapely = shapely.__version__ except AttributeError: import shapely.geos vshapely = shapely.geos.geos_capi_version except ImportError: vshapely = none try: import owslib try: vowslib = owslib.__version__ except AttributeError: vowslib = 'Module found, version not specified' except ImportError: vowslib = none return '''pycsw system profile -------------------- Python version: %s os: %s SQLAlchemy: %s Shapely: %s lxml: %s libxml2: %s pyproj: %s OWSLib: %s''' % (sys.version_info, sys.platform, vsqlalchemy, vshapely, etree.__version__, etree.LIBXML_VERSION, vpyproj, vowslib) def validate_xml(xml, xsd): """Validate XML document against XML Schema""" LOGGER.info('Validating %s against schema %s', xml, xsd) schema = etree.XMLSchema(file=xsd) try: tree = etree.parse(xml, PARSER) schema.assertValid(tree) return 'Valid' except Exception as err: LOGGER.exception('Invalid XML') raise RuntimeError('ERROR: %s' % str(err)) from err def delete_records(context, database, table): """Deletes all records from repository""" LOGGER.info('Deleting all records') repo = repository.Repository(database, context, table=table) repo.delete(constraint={'where': '', 'values': []}) def cli_option_verbosity(f): def callback(ctx, param, value): if value is not None: logging.basicConfig(stream=sys.stdout, level=getattr(logging, value)) return True return click.option('--verbosity', '-v', type=click.Choice(['ERROR', 'WARNING', 'INFO', 'DEBUG']), help='Verbosity', callback=callback)(f) CLI_OPTION_CONFIG = click.option('--config', '-c', required=True, type=click.Path(exists=True, resolve_path=True), help='Path to pycsw configuration') CLI_OPTION_YES = click.option('--yes', '-y', is_flag=True, default=False, help='Bypass confirmation') CLI_OPTION_YES_PROMPT = click.option('--yes', '-y', is_flag=True, default=False, prompt='This will delete all records! Continue?', help='Bypass confirmation') def cli_callbacks(f): f = cli_option_verbosity(f) return f @click.group() @click.version_option(version=__version__) def cli(): pass @click.command('setup-repository') @cli_callbacks @click.pass_context @CLI_OPTION_CONFIG def cli_setup_repository(ctx, config, verbosity): """Create repository tables and indexes""" with open(config, encoding='utf8') as fh: cfg = yaml_load(fh) try: repository.setup(cfg['repository']['database'], table=cfg['repository'].get('table')) except Exception as err: msg = f'ERROR: Repository already exists: {err}' raise click.ClickException(msg) from err @click.command('load-records') @cli_callbacks @click.pass_context @CLI_OPTION_CONFIG @click.option('--path', '-p', 'path', required=True, help='File or directory path to metadata records', type=click.Path(exists=True, resolve_path=True, file_okay=True)) @click.option('--recursive', '-r', is_flag=True, default=False, help='Recurse subdirectories') @CLI_OPTION_YES def cli_load_records(ctx, config, path, recursive, yes, verbosity): """Load metadata records from directory or file into repository""" with open(config, encoding='utf8') as fh: cfg = yaml_load(fh) context = pconfig.StaticContext() load_records( context, cfg['repository']['database'], cfg['repository']['table'], path, recursive, yes ) @click.command('delete-records') @cli_callbacks @click.pass_context @CLI_OPTION_CONFIG @CLI_OPTION_YES_PROMPT def cli_delete_records(ctx, config, yes, verbosity): """Delete all records from repository""" with open(config, encoding='utf8') as fh: cfg = yaml_load(fh) context = pconfig.StaticContext() delete_records( context, cfg['repository']['database'], cfg['repository']['table'] ) @click.command('export-records') @cli_callbacks @click.pass_context @CLI_OPTION_CONFIG @click.option('--path', '-p', 'path', required=True, help='Directory path to metadata records', type=click.Path(exists=True, resolve_path=True, writable=True, file_okay=False)) def cli_export_records(ctx, config, path, verbosity): """Dump metadata records from repository into directory""" with open(config, encoding='utf8') as fh: cfg = yaml_load(fh) context = pconfig.StaticContext() export_records( context, cfg['repository']['database'], cfg['repository']['table'], path ) @click.command('rebuild-db-indexes') @cli_callbacks @click.pass_context @CLI_OPTION_CONFIG def cli_rebuild_db_indexes(ctx, config, verbosity): """Rebuild repository database indexes""" with open(config, encoding='utf8') as fh: cfg = yaml_load(fh) context = pconfig.StaticContext() repo = repository.Repository(cfg['repository']['database'], context, table=cfg['repository'].get('table')) repo.rebuild_db_indexes() @click.command('optimize-db') @cli_callbacks @click.pass_context @CLI_OPTION_CONFIG def cli_optimize_db(ctx, config, verbosity): """Optimize repository database""" with open(config, encoding='utf8') as fh: cfg = yaml_load(fh) context = pconfig.StaticContext() repo = repository.Repository(cfg['repository']['database'], context, table=cfg['repository'].get('table')) repo.optimize_db() @click.command('refresh-harvested-records') @cli_callbacks @click.pass_context @CLI_OPTION_CONFIG @click.option('--url', '-u', 'url', help='URL of harvest endpoint') def cli_refresh_harvested_records(ctx, config, verbosity, url): """Refresh / harvest non-local records in repository""" with open(config, encoding='utf8') as fh: cfg = yaml_load(fh) context = pconfig.StaticContext() refresh_harvested_records( context, cfg['repository']['database'], cfg['repository']['table'], url ) @click.command('gen-sitemap') @cli_callbacks @click.pass_context @CLI_OPTION_CONFIG @click.option('--output', '-o', 'output', required=True, help='Filepath to write sitemap', type=click.Path(resolve_path=True, writable=True, dir_okay=False)) def cli_gen_sitemap(ctx, config, output, verbosity): """Generate XML Sitemap""" with open(config, encoding='utf8') as fh: cfg = yaml_load(fh) context = pconfig.StaticContext() gen_sitemap( context, cfg['repository']['database'], cfg['repository']['table'], cfg['server']['url'], output ) @click.command('post-xml') @cli_callbacks @click.pass_context @click.option('--url', '-u', 'url', required=True, help='URL of CSW endpoint') @click.option('--xml', '-x', 'xml', required=True, help='XML file to POST', type=click.Path(resolve_path=True, exists=True, dir_okay=False)) @click.option('--timeout', '-t', 'timeout', default=30, help='Timeout (in seconds) for HTTP requests') def cli_post_xml(ctx, url, xml, timeout, verbosity): """Execute a CSW request via HTTP POST""" click.echo(post_xml(url, xml, timeout)) @click.command('validate-xml') @cli_callbacks @click.pass_context @click.option('--xml', '-x', 'xml', required=True, help='XML document', type=click.Path(resolve_path=True, exists=True, dir_okay=False)) @click.option('--xsd', '-s', 'xsd', required=True, help='XML Schema document', type=click.Path(resolve_path=True, exists=True, dir_okay=False)) def cli_validate_xml(ctx, xml, xsd, verbosity): """Validate an XML document against an XML Schema""" validate_xml(xml, xsd) @click.command('get-sysprof') @click.pass_context def cli_get_sysprof(ctx): """Get versions of dependencies""" click.echo(get_sysprof()) @click.command('migrate-config') @cli_callbacks @click.pass_context @CLI_OPTION_CONFIG def cli_migrate_config(ctx, config, verbosity): """Migrate pycsw ini config to YAML""" dict_ = { 'server': {}, 'logging': {}, 'manager': {}, 'metadata': { 'identification': {}, 'provider': {}, 'contact': {}, 'inspire': {} }, 'profiles': [], 'federatedcatalogues': [], 'repository': {} } cfg = parse_ini_config(config) for name, value in cfg.items('server'): if name == 'loglevel': dict_['logging']['level'] = value elif name == 'logfile': dict_['logging']['logfile'] = value elif name == 'profiles': dict_[name] = value.split(',') elif name == 'federatedcatalogues': dict_[name] = [] for count, fc in enumerate(value.split(',')): dict_[name].append({'id': f'fedcat{count}', 'url': fc}) else: dict_['server'][name] = get_typed_value(value) for name, value in cfg.items('metadata:main'): if name.startswith('identification'): new_key = name.replace('identification_', '') if new_key == 'keywords': dict_['metadata']['identification'][new_key] = value.split(',') elif new_key == 'abstract': dict_['metadata']['identification']['description'] = value else: dict_['metadata']['identification'][new_key] = get_typed_value(value) if name.startswith('provider'): new_key = name.replace('provider_', '') dict_['metadata']['provider'][new_key] = get_typed_value(value) if name.startswith('contact'): new_key = name.replace('contact_', '') dict_['metadata']['contact'][new_key] = get_typed_value(value) for name, value in cfg.items('manager'): if name == 'allowed_ips': dict_['manager'][name] = value.split(',') elif name == 'transactions': dict_['manager'][name] = str2bool(value) else: dict_['manager'][name] = get_typed_value(value) for name, value in cfg.items('repository'): if name == 'facets': dict_['repository'][name] = value.split(',') else: dict_['repository'][name] = get_typed_value(value) for name, value in cfg.items('metadata:inspire'): if name == 'languages_supported': dict_['metadata']['inspire'][name] = value.split(',') elif name == 'enabled': dict_['metadata']['inspire'][name] = str2bool(value) elif name == 'gemet_keywords': dict_['metadata']['inspire'][name] = value.split(',') elif name == 'temp_extent': begin, end = value.split('/') dict_['metadata']['inspire'][name] = { 'begin': begin, 'end': end } else: dict_['metadata']['inspire'][name] = get_typed_value(value) yaml_file = config.replace('.cfg', '.yml') click.echo(f'Writing to {yaml_file}') yaml_dump(dict_, yaml_file) cli.add_command(cli_setup_repository) cli.add_command(cli_load_records) cli.add_command(cli_export_records) cli.add_command(cli_delete_records) cli.add_command(cli_rebuild_db_indexes) cli.add_command(cli_optimize_db) cli.add_command(cli_refresh_harvested_records) cli.add_command(cli_gen_sitemap) cli.add_command(cli_post_xml) cli.add_command(cli_validate_xml) cli.add_command(cli_get_sysprof) cli.add_command(cli_migrate_config) ================================================ FILE: pycsw/core/config.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2016 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from pycsw.core.etree import PARSER from pycsw import __version__ LOGGER = logging.getLogger(__name__) class StaticContext(object): """core configuration""" def __init__(self, prefix='csw30'): """initializer""" LOGGER.debug('Initializing static context') self.version = __version__ self.ogc_schemas_base = 'http://schemas.opengis.net' self.parser = PARSER self.server = None self.languages = { 'en': 'english', 'fr': 'french', 'el': 'greek', } self.response_codes = { 'OK': '200 OK', 'NotFound': '404 Not Found', 'InvalidValue': '400 Invalid property value', 'OperationParsingFailed': '400 Bad Request', 'OperationProcessingFailed': '403 Server Processing Failed', 'OperationNotSupported': '400 Not Implemented', 'MissingParameterValue': '400 Bad Request', 'InvalidParameterValue': '400 Bad Request', 'VersionNegotiationFailed': '400 Bad Request', 'InvalidUpdateSequence': '400 Bad Request', 'OptionNotSupported': '400 Not Implemented', 'NoApplicableCode': '400 Internal Server Error' } self.namespaces = { 'atom': 'http://www.w3.org/2005/Atom', 'csw': 'http://www.opengis.net/cat/csw/2.0.2', 'csw30': 'http://www.opengis.net/cat/csw/3.0', 'dc': 'http://purl.org/dc/elements/1.1/', 'dct': 'http://purl.org/dc/terms/', 'dif': 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/', 'fes20': 'http://www.opengis.net/fes/2.0', 'fgdc': 'http://www.opengis.net/cat/csw/csdgm', 'gm03': 'http://www.interlis.ch/INTERLIS2.3', 'gmd': 'http://www.isotc211.org/2005/gmd', 'gml': 'http://www.opengis.net/gml', 'gml32': 'http://www.opengis.net/gml/3.2', 'mdb': 'http://standards.iso.org/iso/19115/-3/mdb/2.0', 'ogc': 'http://www.opengis.net/ogc', 'os': 'http://a9.com/-/spec/opensearch/1.1/', 'ows': 'http://www.opengis.net/ows', 'ows11': 'http://www.opengis.net/ows/1.1', 'ows20': 'http://www.opengis.net/ows/2.0', 'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'sitemap': 'http://www.sitemaps.org/schemas/sitemap/0.9', 'soapenv': 'http://www.w3.org/2003/05/soap-envelope', 'xlink': 'http://www.w3.org/1999/xlink', 'xs': 'http://www.w3.org/2001/XMLSchema', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance' } self.keep_ns_prefixes = [ 'csw', 'dc', 'dct', 'gmd', 'gml', 'gml32', 'ows', 'xs' ] self.md_core_model = { 'typename': 'pycsw:CoreMetadata', 'outputschema': 'http://pycsw.org/metadata', 'mappings': { 'pycsw:Identifier': 'identifier', # CSW typename (e.g. csw:Record, md:MD_Metadata) 'pycsw:Typename': 'typename', # schema namespace, i.e. http://www.isotc211.org/2005/gmd 'pycsw:Schema': 'schema', # origin of resource, either 'local', or URL to web service 'pycsw:MdSource': 'mdsource', # date of insertion 'pycsw:InsertDate': 'insert_date', # date of insertion # raw XML metadata 'pycsw:XML': 'xml', # raw metadata payload, xml to be migrated to this in the future 'pycsw:Metadata': 'metadata', # raw metadata payload type, xml as default for now 'pycsw:MetadataType': 'metadata_type', # bag of metadata element and attributes ONLY, no XML tags 'pycsw:AnyText': 'anytext', 'pycsw:Language': 'language', 'pycsw:Title': 'title', 'pycsw:Abstract': 'abstract', 'pycsw:Edition': 'edition', 'pycsw:Keywords': 'keywords', 'pycsw:KeywordType': 'keywordstype', 'pycsw:Themes': 'themes', 'pycsw:Format': 'format', 'pycsw:Source': 'source', 'pycsw:Date': 'date', 'pycsw:Modified': 'date_modified', 'pycsw:Type': 'type', # geometry, specified in OGC WKT 'pycsw:BoundingBox': 'wkt_geometry', 'pycsw:VertExtentMin': 'vert_extent_min', 'pycsw:VertExtentMax': 'vert_extent_max', 'pycsw:CRS': 'crs', 'pycsw:AlternateTitle': 'title_alternate', 'pycsw:RevisionDate': 'date_revision', 'pycsw:CreationDate': 'date_creation', 'pycsw:PublicationDate': 'date_publication', 'pycsw:OrganizationName': 'organization', 'pycsw:SecurityConstraints': 'securityconstraints', 'pycsw:ParentIdentifier': 'parentidentifier', 'pycsw:TopicCategory': 'topicategory', 'pycsw:ResourceLanguage': 'resourcelanguage', 'pycsw:GeographicDescriptionCode': 'geodescode', 'pycsw:Denominator': 'denominator', 'pycsw:DistanceValue': 'distancevalue', 'pycsw:DistanceUOM': 'distanceuom', 'pycsw:TempExtent_begin': 'time_begin', 'pycsw:TempExtent_end': 'time_end', 'pycsw:ServiceType': 'servicetype', 'pycsw:ServiceTypeVersion': 'servicetypeversion', 'pycsw:Operation': 'operation', 'pycsw:CouplingType': 'couplingtype', 'pycsw:OperatesOn': 'operateson', 'pycsw:OperatesOnIdentifier': 'operatesonidentifier', 'pycsw:OperatesOnName': 'operatesoname', 'pycsw:Degree': 'degree', 'pycsw:AccessConstraints': 'accessconstraints', 'pycsw:OtherConstraints': 'otherconstraints', 'pycsw:Classification': 'classification', 'pycsw:ConditionApplyingToAccessAndUse': 'conditionapplyingtoaccessanduse', 'pycsw:Lineage': 'lineage', 'pycsw:ResponsiblePartyRole': 'responsiblepartyrole', 'pycsw:SpecificationTitle': 'specificationtitle', 'pycsw:SpecificationDate': 'specificationdate', 'pycsw:SpecificationDateType': 'specificationdatetype', 'pycsw:Creator': 'creator', 'pycsw:Publisher': 'publisher', 'pycsw:Contributor': 'contributor', 'pycsw:Relation': 'relation', 'pycsw:Platform': 'platform', 'pycsw:Instrument': 'instrument', 'pycsw:SensorType': 'sensortype', 'pycsw:CloudCover': 'cloudcover', 'pycsw:Bands': 'bands', 'pycsw:IlluminationElevationAngle': 'illuminationelevationangle', # links: list of dicts with properties: name, description, protocol, url 'pycsw:Links': 'links', # contacts: list of dicts with properties: name, organization, address, postcode, city, region, country, email, phone, fax, onlineresource, position, role 'pycsw:Contacts': 'contacts', } } self.model = None self.models = { 'csw': { 'operations_order': [ 'GetCapabilities', 'DescribeRecord', 'GetDomain', 'GetRecords', 'GetRecordById', 'GetRepositoryItem' ], 'operations': { 'GetCapabilities': { 'methods': { 'get': True, 'post': True, }, 'parameters': { 'sections': { 'values': ['ServiceIdentification', 'ServiceProvider', 'OperationsMetadata', 'Filter_Capabilities'] } } }, 'DescribeRecord': { 'methods': { 'get': True, 'post': True, }, 'parameters': { 'schemaLanguage': { 'values': ['http://www.w3.org/XML/Schema', 'http://www.w3.org/TR/xmlschema-1/', 'http://www.w3.org/2001/XMLSchema'] }, 'typeName': { 'values': ['csw:Record'] }, 'outputFormat': { 'values': ['application/xml', 'application/json'] } } }, 'GetRecords': { 'methods': { 'get': True, 'post': True, }, 'parameters': { 'resultType': { 'values': ['hits', 'results', 'validate'] }, 'typeNames': { 'values': ['csw:Record'] }, 'outputSchema': { 'values': ['http://www.opengis.net/cat/csw/2.0.2'] }, 'outputFormat': { 'values': ['application/xml', 'application/json'] }, 'CONSTRAINTLANGUAGE': { 'values': ['FILTER', 'CQL_TEXT'] }, 'ElementSetName': { 'values': ['brief', 'summary', 'full'] } }, 'constraints': { } }, 'GetRecordById': { 'methods': { 'get': True, 'post': True, }, 'parameters': { 'outputSchema': { 'values': ['http://www.opengis.net/cat/csw/2.0.2'] }, 'outputFormat': { 'values': ['application/xml', 'application/json'] }, 'ElementSetName': { 'values': ['brief', 'summary', 'full'] } } }, 'GetRepositoryItem': { 'methods': { 'get': True, 'post': False, }, 'parameters': { } } }, 'parameters': { 'version': { 'values': ['2.0.2', '3.0.0'] }, 'service': { 'values': ['CSW'] } }, 'constraints': { 'MaxRecordDefault': { 'values': ['10'] }, 'PostEncoding': { 'values': ['XML', 'SOAP'] }, 'XPathQueryables': { 'values': ['allowed'] } }, 'typenames': { 'csw:Record': { 'outputschema': 'http://www.opengis.net/cat/csw/2.0.2', 'queryables': { 'SupportedDublinCoreQueryables': { # map Dublin Core queryables to core metadata model 'dc:title': {'dbcol': self.md_core_model['mappings']['pycsw:Title']}, 'dct:alternative': {'dbcol': self.md_core_model['mappings']['pycsw:AlternateTitle']}, 'dc:creator': {'dbcol': self.md_core_model['mappings']['pycsw:Creator']}, 'dc:subject': {'dbcol': self.md_core_model['mappings']['pycsw:Keywords']}, 'dct:abstract': {'dbcol': self.md_core_model['mappings']['pycsw:Abstract']}, 'dc:publisher': {'dbcol': self.md_core_model['mappings']['pycsw:Publisher']}, 'dc:contributor': {'dbcol': self.md_core_model['mappings']['pycsw:Contributor']}, 'dct:modified': {'dbcol': self.md_core_model['mappings']['pycsw:Modified']}, 'dc:date': {'dbcol': self.md_core_model['mappings']['pycsw:Date']}, 'dc:type': {'dbcol': self.md_core_model['mappings']['pycsw:Type']}, 'dc:format': {'dbcol': self.md_core_model['mappings']['pycsw:Format']}, 'dc:identifier': {'dbcol': self.md_core_model['mappings']['pycsw:Identifier']}, 'dc:source': {'dbcol': self.md_core_model['mappings']['pycsw:Source']}, 'dc:language': {'dbcol': self.md_core_model['mappings']['pycsw:Language']}, 'dc:relation': {'dbcol': self.md_core_model['mappings']['pycsw:Relation']}, 'dc:rights': {'dbcol': self.md_core_model['mappings']['pycsw:AccessConstraints']}, 'dct:spatial': {'dbcol': self.md_core_model['mappings']['pycsw:CRS']}, # bbox and full text map to internal fixed columns 'ows:BoundingBox': {'dbcol': self.md_core_model['mappings']['pycsw:BoundingBox']}, 'csw:AnyText': {'dbcol': self.md_core_model['mappings']['pycsw:AnyText']}, } } } } }, 'csw30': { 'operations_order': [ 'GetCapabilities', 'GetDomain', 'GetRecords', 'GetRecordById', 'GetRepositoryItem' ], 'operations': { 'GetCapabilities': { 'methods': { 'get': True, 'post': True, }, 'parameters': { 'acceptVersions': { 'values': ['2.0.2', '3.0.0'] }, 'acceptFormats': { 'values': ['text/xml', 'application/xml'] }, 'sections': { 'values': ['ServiceIdentification', 'ServiceProvider', 'OperationsMetadata', 'Filter_Capabilities', 'All'] } } }, 'GetRecords': { 'methods': { 'get': True, 'post': True, }, 'parameters': { 'typeNames': { 'values': ['csw:Record', 'csw30:Record'] }, 'outputSchema': { 'values': ['http://www.opengis.net/cat/csw/3.0'] }, 'outputFormat': { 'values': ['application/xml', 'application/json', 'application/atom+xml'] }, 'CONSTRAINTLANGUAGE': { 'values': ['FILTER', 'CQL_TEXT'] }, 'ElementSetName': { 'values': ['brief', 'summary', 'full'] } }, 'constraints': { } }, 'GetRecordById': { 'methods': { 'get': True, 'post': True, }, 'parameters': { 'outputSchema': { 'values': ['http://www.opengis.net/cat/csw/3.0'] }, 'outputFormat': { 'values': ['application/xml', 'application/json', 'application/atom+xml'] }, 'ElementSetName': { 'values': ['brief', 'summary', 'full'] } } }, 'GetRepositoryItem': { 'methods': { 'get': True, 'post': False, }, 'parameters': { } } }, 'parameters': { 'version': { 'values': ['2.0.2', '3.0.0'] }, 'service': { 'values': ['CSW'] } }, 'constraints': { 'MaxRecordDefault': { 'values': ['10'] }, 'PostEncoding': { 'values': ['XML', 'SOAP'] }, 'XPathQueryables': { 'values': ['allowed'] }, 'http://www.opengis.net/spec/csw/3.0/conf/OpenSearch': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Transaction': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions': { 'values': ['http://www.opengis.net/gml/3.2'] }, 'http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables': { 'values': ['TRUE'] }, 'http://www.opengis.net/spec/csw/3.0/conf/CoreSortables': { 'values': ['TRUE'] } }, 'typenames': { 'csw:Record': { 'outputschema': 'http://www.opengis.net/cat/csw/3.0', 'queryables': { 'SupportedDublinCoreQueryables': { # map Dublin Core queryables to core metadata model 'dc:title': {'dbcol': self.md_core_model['mappings']['pycsw:Title']}, 'dct:alternative': {'dbcol': self.md_core_model['mappings']['pycsw:AlternateTitle']}, 'dc:creator': {'dbcol': self.md_core_model['mappings']['pycsw:Creator']}, 'dc:subject': {'dbcol': self.md_core_model['mappings']['pycsw:Keywords']}, 'dct:abstract': {'dbcol': self.md_core_model['mappings']['pycsw:Abstract']}, 'dc:publisher': {'dbcol': self.md_core_model['mappings']['pycsw:Publisher']}, 'dc:contributor': {'dbcol': self.md_core_model['mappings']['pycsw:Contributor']}, 'dct:modified': {'dbcol': self.md_core_model['mappings']['pycsw:Modified']}, 'dc:date': {'dbcol': self.md_core_model['mappings']['pycsw:Date']}, 'dc:type': {'dbcol': self.md_core_model['mappings']['pycsw:Type']}, 'dc:format': {'dbcol': self.md_core_model['mappings']['pycsw:Format']}, 'dc:identifier': {'dbcol': self.md_core_model['mappings']['pycsw:Identifier']}, 'dc:source': {'dbcol': self.md_core_model['mappings']['pycsw:Source']}, 'dc:language': {'dbcol': self.md_core_model['mappings']['pycsw:Language']}, 'dc:relation': {'dbcol': self.md_core_model['mappings']['pycsw:Relation']}, 'dc:rights': {'dbcol': self.md_core_model['mappings']['pycsw:AccessConstraints']}, 'dct:spatial': {'dbcol': self.md_core_model['mappings']['pycsw:CRS']}, # bbox and full text map to internal fixed columns 'ows:BoundingBox': {'dbcol': self.md_core_model['mappings']['pycsw:BoundingBox']}, 'csw:AnyText': {'dbcol': self.md_core_model['mappings']['pycsw:AnyText']}, } } } } } } self.set_model(prefix) def set_model(self, prefix): """sets model given request context""" self.model = self.models[prefix] def gen_domains(self): """Generate parameter domain model""" domain = {} domain['methods'] = {'get': True, 'post': True} domain['parameters'] = {'ParameterName': {'values': []}} for operation in self.model['operations'].keys(): for parameter in self.model['operations'][operation]['parameters']: domain['parameters']['ParameterName']['values'].append('%s.%s' % (operation, parameter)) return domain def refresh_dc(self, mappings): """Refresh Dublin Core mappings""" LOGGER.debug('refreshing Dublin Core mappings with %s', str(mappings)) defaults = { 'dc:title': 'pycsw:Title', 'dct:alternative': 'pycsw:AlternateTitle', 'dc:creator': 'pycsw:Creator', 'dc:subject': 'pycsw:Keywords', 'dct:abstract': 'pycsw:Abstract', 'dc:publisher': 'pycsw:Publisher', 'dc:contributor': 'pycsw:Contributor', 'dct:modified': 'pycsw:Modified', 'dc:date': 'pycsw:Date', 'dc:type': 'pycsw:Type', 'dc:format': 'pycsw:Format', 'dc:identifier': 'pycsw:Identifier', 'dc:source': 'pycsw:Source', 'dc:language': 'pycsw:Language', 'dc:relation': 'pycsw:Relation', 'dc:rights': 'pycsw:AccessConstraints', 'dct:spatial': 'pycsw:CRS', 'ows:BoundingBox': 'pycsw:BoundingBox', 'csw:AnyText': 'pycsw:AnyText', } for k, val in defaults.items(): for model, params in self.models.items(): queryables = params['typenames']['csw:Record']['queryables'] queryables['SupportedDublinCoreQueryables'][k] = { 'dbcol': mappings['mappings'][val] } ================================================ FILE: pycsw/core/etree.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Ricardo Garcia Silva # # Copyright (c) 2015 Tom Kralidis # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Custom etree objects for pycsw Be sure to use the ``PARSER`` object defined in this module whenever it is necessary to parse external XML objects. This parser offers better protection against known XML attacks. """ from lxml import etree PARSER = etree.XMLParser(resolve_entities=False) ================================================ FILE: pycsw/core/formats/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/core/formats/fmt_json.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Ricardo Garcia Silva # # Copyright (c) 2015 Tom Kralidis # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import json import xmltodict def xml2dict(xml_string, namespaces): """Convert an xml document to a dictionary. Parameters ---------- xml_string: str XML representation to convert to a dictionary. namespaces: dict Namespaces used in the ``xml_string`` parameter Returns ------- ordereddict An ordered dictionary with the contents of the xml data """ namespaces_reverse = dict((v, k) for k, v in namespaces.items()) return xmltodict.parse(xml_string, process_namespaces=True, namespaces=namespaces_reverse) def xml2json(xml_string, namespaces, pretty_print=False): """Convert an xml string to JSON""" separators = (',', ': ') if pretty_print: return json.dumps(xml2dict(xml_string, namespaces), indent=4, separators=separators) return json.dumps(xml2dict(xml_string, namespaces), separators=separators) ================================================ FILE: pycsw/core/log.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging import sys LOGGER = logging.getLogger(__name__) def setup_logger(logging_config): """ Setup configuration :param logging_config: logging specific configuration :returns: void (creates logging instance) """ log_format = \ '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s' date_format = '%Y-%m-%dT%H:%M:%SZ' loglevels = { 'CRITICAL': logging.CRITICAL, 'ERROR': logging.ERROR, 'WARNING': logging.WARNING, 'INFO': logging.INFO, 'DEBUG': logging.DEBUG, 'NOTSET': logging.NOTSET, } loglevel = loglevels[logging_config['level']] if 'logfile' in logging_config: logging.basicConfig(level=loglevel, datefmt=date_format, format=log_format, filename=logging_config['logfile']) else: logging.basicConfig(level=loglevel, datefmt=date_format, format=log_format, stream=sys.stdout) LOGGER.debug('Logging initialized') return ================================================ FILE: pycsw/core/metadata.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Ricardo Garcia Silva # Angelos Tzotsos # # Copyright (c) 2025 Tom Kralidis # Copyright (c) 2016 James F. Dickens # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2026 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import json import logging import uuid from urllib.parse import urlparse from geolinks import sniff_link from owslib.util import build_get_url from shapely.wkt import loads from shapely.geometry import MultiPolygon from pycsw.core.etree import etree from pycsw.core import util from pycsw.plugins.outputschemas import atom LOGGER = logging.getLogger(__name__) def parse_record(context, record, repos=None, mtype='http://www.opengis.net/cat/csw/2.0.2', identifier=None, pagesize=10): ''' parse metadata ''' if identifier is None: identifier = uuid.uuid4().urn # parse web services if (mtype == 'http://www.opengis.net/cat/csw/2.0.2' and isinstance(record, str) and record.startswith('http')): LOGGER.info('CSW service detected, fetching via HTTP') # CSW service, not csw:Record try: return _parse_csw(context, repos, record, identifier, pagesize) except Exception as err: # TODO: implement better exception handling if str(err).find('ExceptionReport') != -1: msg = 'CSW harvesting error: %s' % str(err) LOGGER.exception(msg) raise RuntimeError(msg) LOGGER.debug('Not a CSW, attempting to fetch Dublin Core') try: content = util.http_request('GET', record) except Exception as err: raise RuntimeError('HTTP error: %s' % str(err)) return [_parse_dc(context, repos, etree.fromstring(content, context.parser))] elif mtype == 'urn:geoss:waf': # WAF LOGGER.info('WAF detected, fetching via HTTP') return _parse_waf(context, repos, record, identifier) elif mtype == 'http://www.opengis.net/wms': # WMS LOGGER.info('WMS detected, fetching via OWSLib') return _parse_wms(context, repos, record, identifier) elif mtype == 'http://www.opengis.net/wmts/1.0': # WMTS LOGGER.info('WMTS 1.0.0 detected, fetching via OWSLib') return _parse_wmts(context, repos, record, identifier) elif mtype == 'http://www.opengis.net/wps/1.0.0': # WPS LOGGER.info('WPS detected, fetching via OWSLib') return _parse_wps(context, repos, record, identifier) elif mtype == 'http://www.opengis.net/wfs': # WFS 1.1.0 LOGGER.info('WFS detected, fetching via OWSLib') return _parse_wfs(context, repos, record, identifier, '1.1.0') elif mtype == 'http://www.opengis.net/wfs/2.0': # WFS 2.0.0 LOGGER.info('WFS detected, fetching via OWSLib') return _parse_wfs(context, repos, record, identifier, '2.0.0') elif mtype == 'http://www.opengis.net/wcs': # WCS LOGGER.info('WCS detected, fetching via OWSLib') return _parse_wcs(context, repos, record, identifier) elif mtype == 'http://www.opengis.net/sos/1.0': # SOS 1.0.0 LOGGER.info('SOS 1.0.0 detected, fetching via OWSLib') return _parse_sos(context, repos, record, identifier, '1.0.0') elif mtype == 'http://www.opengis.net/sos/2.0': # SOS 2.0.0 LOGGER.info('SOS 2.0.0 detected, fetching via OWSLib') return _parse_sos(context, repos, record, identifier, '2.0.0') elif (mtype == 'http://www.opengis.net/cat/csw/csdgm' and record.startswith('http')): # FGDC LOGGER.info('FGDC detected, fetching via HTTP') record = util.http_request('GET', record) return _parse_metadata(context, repos, record) def _get(context, obj, name): ''' convenience method to get values ''' return getattr(obj, context.md_core_model['mappings'][name]) def _set(context, obj, name, value): ''' convenience method to set values ''' setattr(obj, context.md_core_model['mappings'][name], value) def _parse_metadata(context, repos, record): """parse metadata formats""" if isinstance(record, dict): # JSON LOGGER.debug('Record is JSON based') return [_parse_json_record(context, repos, record)] if isinstance(record, bytes) or isinstance(record, str): exml = etree.fromstring(record, context.parser) else: # already serialized to lxml if hasattr(record, 'getroot'): # standalone document exml = record.getroot() else: # part of a larger document exml = record root = exml.tag LOGGER.info('Serialized metadata, parsing content model') if root == '{%s}MD_Metadata' % context.namespaces['gmd']: # ISO return [_parse_iso(context, repos, exml)] elif root == '{http://www.isotc211.org/2005/gmi}MI_Metadata': # ISO Metadata for Imagery return [_parse_iso(context, repos, exml)] elif root == 'metadata': # FGDC return [_parse_fgdc(context, repos, exml)] elif root == '{%s}TRANSFER' % context.namespaces['gm03']: # GM03 return [_parse_gm03(context, repos, exml)] elif root == '{http://www.geocat.ch/2008/che}CHE_MD_Metadata': # GM03 ISO profile return [_parse_iso(context, repos, exml)] elif root == '{%s}Record' % context.namespaces['csw']: # Dublin Core CSW return [_parse_dc(context, repos, exml)] elif root == '{%s}RDF' % context.namespaces['rdf']: # Dublin Core RDF return [_parse_dc(context, repos, exml)] elif root == '{%s}DIF' % context.namespaces['dif']: # DIF pass # TODO elif root == '{%s}MD_Metadata' % context.namespaces['mdb']: # ISO 19115p3 XML return [_parse_iso(context, repos, exml)] else: raise RuntimeError('Unsupported metadata format') def _parse_csw(context, repos, record, identifier, pagesize=10): from owslib.csw import CatalogueServiceWeb recobjs = [] # records serviceobj = repos.dataset() # if init raises error, this might not be a CSW md = CatalogueServiceWeb(record, timeout=60) LOGGER.info('Setting CSW service metadata') # generate record of service instance _set(context, serviceobj, 'pycsw:Identifier', identifier) _set(context, serviceobj, 'pycsw:Typename', 'csw:Record') _set(context, serviceobj, 'pycsw:Schema', 'http://www.opengis.net/cat/csw/2.0.2') _set(context, serviceobj, 'pycsw:MdSource', record) _set(context, serviceobj, 'pycsw:InsertDate', util.get_today_and_now()) _set( context, serviceobj, 'pycsw:AnyText', util.get_anytext(md._exml) ) _set(context, serviceobj, 'pycsw:Type', 'service') _set(context, serviceobj, 'pycsw:Title', md.identification.title) _set(context, serviceobj, 'pycsw:Abstract', md.identification.abstract) _set(context, serviceobj, 'pycsw:Keywords', ','.join(md.identification.keywords)) _set(context, serviceobj, 'pycsw:Creator', md.provider.contact.name) _set(context, serviceobj, 'pycsw:Publisher', md.provider.name) _set(context, serviceobj, 'pycsw:Contributor', md.provider.contact.name) _set(context, serviceobj, 'pycsw:OrganizationName', md.provider.contact.name) _set(context, serviceobj, 'pycsw:AccessConstraints', md.identification.accessconstraints) _set(context, serviceobj, 'pycsw:OtherConstraints', md.identification.fees) _set(context, serviceobj, 'pycsw:Source', record) _set(context, serviceobj, 'pycsw:Format', md.identification.type) _set(context, serviceobj, 'pycsw:ServiceType', 'OGC:CSW') _set(context, serviceobj, 'pycsw:ServiceTypeVersion', md.identification.version) _set(context, serviceobj, 'pycsw:Operation', ','.join([d.name for d in md.operations])) _set(context, serviceobj, 'pycsw:CouplingType', 'tight') links = [{ 'name': identifier, 'description': 'OGC-CSW Catalogue Service for the Web', 'protocol': 'OGC:CSW', 'url': md.url }] _set(context, serviceobj, 'pycsw:Links', json.dumps(links)) _set(context, serviceobj, 'pycsw:XML', caps2iso(serviceobj, md, context)) _set(context, serviceobj, 'pycsw:MetadataType', 'application/xml') recobjs.append(serviceobj) # get all supported typenames of metadata # so we can harvest the entire CSW # try for ISO, settle for Dublin Core csw_typenames = 'csw:Record' csw_outputschema = 'http://www.opengis.net/cat/csw/2.0.2' grop = md.get_operation_by_name('GetRecords') if all(['gmd:MD_Metadata' in grop.parameters['typeNames']['values'], 'http://www.isotc211.org/2005/gmd' in grop.parameters['outputSchema']['values']]): LOGGER.debug('CSW supports ISO') csw_typenames = 'gmd:MD_Metadata' csw_outputschema = 'http://www.isotc211.org/2005/gmd' # now get all records # get total number of records to loop against try: md.getrecords2(typenames=csw_typenames, resulttype='hits', outputschema=csw_outputschema) matches = md.results['matches'] except Exception: # this is a CSW, but server rejects query LOGGER.debug('CSW query failed') raise RuntimeError(md.response) if pagesize > matches: pagesize = matches LOGGER.info('Harvesting %d CSW records', matches) # loop over all catalogue records incrementally for r in range(1, matches+1, pagesize): try: md.getrecords2(typenames=csw_typenames, startposition=r, maxrecords=pagesize, outputschema=csw_outputschema, esn='full') except Exception as err: # this is a CSW, but server rejects query raise RuntimeError(md.response) for k, v in md.records.items(): # try to parse metadata try: LOGGER.info('Parsing metadata record: %s', v.xml) if csw_typenames == 'gmd:MD_Metadata': recobjs.append(_parse_iso(context, repos, etree.fromstring(v.xml, context.parser))) else: recobjs.append(_parse_dc(context, repos, etree.fromstring(v.xml, context.parser))) except Exception as err: # parsing failed for some reason LOGGER.exception('Metadata parsing failed') return recobjs def _parse_waf(context, repos, record, identifier): recobjs = [] content = util.http_request('GET', record) LOGGER.debug(content) try: parser = etree.HTMLParser() tree = etree.fromstring(content, parser) except Exception as err: raise Exception('Could not parse WAF: %s' % str(err)) up = urlparse(record) links = [] LOGGER.info('collecting links') for link in tree.xpath('//a/@href'): link = link.strip() if not link: continue if link.find('?') != -1: continue if not link.endswith('.xml'): LOGGER.debug('Skipping, not .xml') continue if '/' in link: # path is embedded in link if link[-1] == '/': # directory, skip continue if link[0] == '/': # strip path of WAF URL link = '%s://%s%s' % (up.scheme, up.netloc, link) else: # tack on href to WAF URL link = '%s/%s' % (record, link) LOGGER.debug('URL is: %s', link) links.append(link) LOGGER.debug('%d links found', len(links)) for link in links: LOGGER.info('Processing link %s', link) # fetch and parse linkcontent = util.http_request('GET', link) recobj = _parse_metadata(context, repos, linkcontent)[0] recobj.source = link recobj.mdsource = link recobjs.append(recobj) return recobjs def _parse_wms(context, repos, record, identifier): from owslib.wms import WebMapService recobjs = [] serviceobj = repos.dataset() md = WebMapService(record) try: md = WebMapService(record, version='1.3.0') except Exception as err: LOGGER.info('Looks like WMS 1.3.0 is not supported; trying 1.1.1', err) md = WebMapService(record) # generate record of service instance _set(context, serviceobj, 'pycsw:Identifier', identifier) _set(context, serviceobj, 'pycsw:Typename', 'csw:Record') _set(context, serviceobj, 'pycsw:Schema', 'http://www.opengis.net/wms') _set(context, serviceobj, 'pycsw:MdSource', record) _set(context, serviceobj, 'pycsw:InsertDate', util.get_today_and_now()) _set( context, serviceobj, 'pycsw:AnyText', util.get_anytext(md.getServiceXML()) ) _set(context, serviceobj, 'pycsw:Type', 'service') _set(context, serviceobj, 'pycsw:Title', md.identification.title) _set(context, serviceobj, 'pycsw:Abstract', md.identification.abstract) _set(context, serviceobj, 'pycsw:Keywords', ','.join(md.identification.keywords)) _set(context, serviceobj, 'pycsw:Creator', md.provider.contact.name) _set(context, serviceobj, 'pycsw:Publisher', md.provider.name) _set(context, serviceobj, 'pycsw:Contributor', md.provider.contact.name) _set(context, serviceobj, 'pycsw:OrganizationName', md.provider.contact.name) contacts = [vars(md.provider.contact)] contacts[0]['role'] = 'pointOfContact' _set(context, serviceobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) _set(context, serviceobj, 'pycsw:AccessConstraints', md.identification.accessconstraints) _set(context, serviceobj, 'pycsw:OtherConstraints', md.identification.fees) _set(context, serviceobj, 'pycsw:Source', record) _set(context, serviceobj, 'pycsw:Format', md.identification.type) for c in md.contents: if md.contents[c].parent is None: bbox = md.contents[c].boundingBoxWGS84 tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]) _set(context, serviceobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) break _set(context, serviceobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326') _set(context, serviceobj, 'pycsw:DistanceUOM', 'degrees') _set(context, serviceobj, 'pycsw:ServiceType', 'OGC:WMS') _set(context, serviceobj, 'pycsw:ServiceTypeVersion', md.identification.version) _set(context, serviceobj, 'pycsw:Operation', ','.join([d.name for d in md.operations])) _set(context, serviceobj, 'pycsw:OperatesOn', ','.join(list(md.contents))) _set(context, serviceobj, 'pycsw:CouplingType', 'tight') links = [{ 'name': identifier, 'description': 'OGC-WMS Web Map Service', 'protocol': 'OGC:WMS', 'url': md.url }] _set(context, serviceobj, 'pycsw:Links', json.dumps(links)) _set(context, serviceobj, 'pycsw:XML', caps2iso(serviceobj, md, context)) _set(context, serviceobj, 'pycsw:MetadataType', 'application/xml') recobjs.append(serviceobj) # generate record foreach layer LOGGER.info('Harvesting %d WMS layers', len(md.contents)) for layer in md.contents: recobj = repos.dataset() identifier2 = '%s-%s' % (identifier, md.contents[layer].name) _set(context, recobj, 'pycsw:Identifier', identifier2) _set(context, recobj, 'pycsw:Typename', 'csw:Record') _set(context, recobj, 'pycsw:Schema', 'http://www.opengis.net/wms') _set(context, recobj, 'pycsw:MdSource', record) _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:Type', 'dataset') _set(context, recobj, 'pycsw:ParentIdentifier', identifier) _set(context, recobj, 'pycsw:Title', md.contents[layer].title) _set(context, recobj, 'pycsw:Abstract', md.contents[layer].abstract) _set(context, recobj, 'pycsw:Keywords', ','.join(md.contents[layer].keywords)) _set( context, recobj, 'pycsw:AnyText', util.get_anytext([ md.contents[layer].title, md.contents[layer].abstract, ','.join(md.contents[layer].keywords) ]) ) bbox = md.contents[layer].boundingBoxWGS84 if bbox is not None: tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) _set(context, recobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326') _set(context, recobj, 'pycsw:DistanceUOM', 'degrees') else: bbox = md.contents[layer].boundingBox if bbox: tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) _set(context, recobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:%s' % \ bbox[-1].split(':')[1]) _set(context, recobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) times = md.contents[layer].timepositions if times is not None: # get temporal extent time_begin = time_end = None if len(times) == 1 and len(times[0].split('/')) > 1: time_envelope = times[0].split('/') time_begin = time_envelope[0] time_end = time_envelope[1] elif len(times) > 1: # get first/last time_begin = times[0] time_end = times[-1] if all([time_begin is not None, time_end is not None]): _set(context, recobj, 'pycsw:TempExtent_begin', time_begin) _set(context, recobj, 'pycsw:TempExtent_end', time_end) params = { 'service': 'WMS', 'version': '1.1.1', 'request': 'GetMap', 'layers': md.contents[layer].name, 'format': 'image/png', 'height': '200', 'width': '200', 'srs': 'EPSG:4326', 'bbox': '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]), 'styles': '' } links = [{ 'name': md.contents[layer].name, 'description': 'OGC-Web Map Service', 'protocol': 'OGC:WMS', 'url': md.url }, { 'name': md.contents[layer].name, 'description': 'Web image thumbnail (URL)', 'protocol': 'WWW:LINK-1.0-http--image-thumbnail', 'url': build_get_url(md.url, params) }] _set(context, recobj, 'pycsw:Links', json.dumps(links)) _set(context, recobj, 'pycsw:XML', caps2iso(recobj, md, context)) _set(context, recobj, 'pycsw:MetadataType', 'application/xml') recobjs.append(recobj) return recobjs def _parse_wmts(context, repos, record, identifier): from owslib.wmts import WebMapTileService recobjs = [] serviceobj = repos.dataset() md = WebMapTileService(record) # generate record of service instance _set(context, serviceobj, 'pycsw:Identifier', identifier) _set(context, serviceobj, 'pycsw:Typename', 'csw:Record') _set(context, serviceobj, 'pycsw:Schema', 'http://www.opengis.net/wmts/1.0') _set(context, serviceobj, 'pycsw:MdSource', record) _set(context, serviceobj, 'pycsw:InsertDate', util.get_today_and_now()) _set( context, serviceobj, 'pycsw:AnyText', util.get_anytext(md.getServiceXML()) ) _set(context, serviceobj, 'pycsw:Type', 'service') _set(context, serviceobj, 'pycsw:Title', md.identification.title) _set(context, serviceobj, 'pycsw:Abstract', md.identification.abstract) _set(context, serviceobj, 'pycsw:Keywords', ','.join(md.identification.keywords)) _set(context, serviceobj, 'pycsw:Creator', md.provider.contact.name) _set(context, serviceobj, 'pycsw:Publisher', md.provider.name) _set(context, serviceobj, 'pycsw:Contributor', md.provider.contact.name) _set(context, serviceobj, 'pycsw:OrganizationName', md.provider.contact.name) contacts = [vars(md.provider.contact)] contacts[0]['role'] = 'pointOfContact' _set(context, serviceobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) _set(context, serviceobj, 'pycsw:AccessConstraints', md.identification.accessconstraints) _set(context, serviceobj, 'pycsw:OtherConstraints', md.identification.fees) _set(context, serviceobj, 'pycsw:Source', record) _set(context, serviceobj, 'pycsw:Format', md.identification.type) for c in md.contents: if md.contents[c].parent is None: bbox = md.contents[c].boundingBoxWGS84 tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]) _set(context, serviceobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) break _set(context, serviceobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326') _set(context, serviceobj, 'pycsw:DistanceUOM', 'degrees') _set(context, serviceobj, 'pycsw:ServiceType', 'OGC:WMTS') _set(context, serviceobj, 'pycsw:ServiceTypeVersion', md.identification.version) _set(context, serviceobj, 'pycsw:Operation', ','.join([d.name for d in md.operations])) _set(context, serviceobj, 'pycsw:OperatesOn', ','.join(list(md.contents))) _set(context, serviceobj, 'pycsw:CouplingType', 'tight') links = [{ 'name': identifier, 'description': 'OGC-WMTS Web Map Service', 'protocol': 'OGC:WMTS', 'url': md.url }] _set(context, serviceobj, 'pycsw:Links', json.dumps(links)) _set(context, serviceobj, 'pycsw:XML', caps2iso(serviceobj, md, context)) _set(context, serviceobj, 'pycsw:MetadataType', 'application/xml') recobjs.append(serviceobj) # generate record for each layer LOGGER.debug('Harvesting %d WMTS layers', len(md.contents)) for layer in md.contents: recobj = repos.dataset() keywords = '' identifier2 = '%s-%s' % (identifier, md.contents[layer].name) _set(context, recobj, 'pycsw:Identifier', identifier2) _set(context, recobj, 'pycsw:Typename', 'csw:Record') _set(context, recobj, 'pycsw:Schema', 'http://www.opengis.net/wmts/1.0') _set(context, recobj, 'pycsw:MdSource', record) _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:Type', 'dataset') _set(context, recobj, 'pycsw:ParentIdentifier', identifier) if md.contents[layer].title: _set(context, recobj, 'pycsw:Title', md.contents[layer].title) else: _set(context, recobj, 'pycsw:Title', "") if md.contents[layer].abstract: _set(context, recobj, 'pycsw:Abstract', md.contents[layer].abstract) else: _set(context, recobj, 'pycsw:Abstract', "") if hasattr(md.contents[layer], 'keywords'): # safeguard against older OWSLib installs keywords = ','.join(md.contents[layer].keywords) _set(context, recobj, 'pycsw:Keywords', keywords) _set( context, recobj, 'pycsw:AnyText', util.get_anytext([ md.contents[layer].title, md.contents[layer].abstract, ','.join(keywords) ]) ) bbox = md.contents[layer].boundingBoxWGS84 if bbox is not None: tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) _set(context, recobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326') _set(context, recobj, 'pycsw:DistanceUOM', 'degrees') else: bbox = md.contents[layer].boundingBox if bbox: tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) _set(context, recobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:%s' % \ bbox[-1].split(':')[1]) _set(context, recobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) params = { 'service': 'WMTS', 'version': '1.0.0', 'request': 'GetTile', 'layer': md.contents[layer].name, } links = [{ 'name': md.contents[layer].name, 'description': 'OGC-Web Map Tile Service', 'protocol': 'OGC:WMTS', 'url': md.url }, { 'name': md.contents[layer].name, 'description': 'Web image thumbnail (URL)', 'protocol': 'WWW:LINK-1.0-http--image-thumbnai', 'url': build_get_url(md.url, params) }] _set(context, recobj, 'pycsw:Links', json.dumps(links)) _set(context, recobj, 'pycsw:XML', caps2iso(recobj, md, context)) _set(context, recobj, 'pycsw:MetadataType', 'application/xml') recobjs.append(recobj) return recobjs def _parse_wfs(context, repos, record, identifier, version): import requests from owslib.wfs import WebFeatureService bboxs = [] recobjs = [] serviceobj = repos.dataset() try: md = WebFeatureService(record, version) except requests.exceptions.HTTPError as err: raise except Exception as err: if version == '1.1.0': md = WebFeatureService(record, '1.0.0') # generate record of service instance _set(context, serviceobj, 'pycsw:Identifier', identifier) _set(context, serviceobj, 'pycsw:Typename', 'csw:Record') _set(context, serviceobj, 'pycsw:Schema', 'http://www.opengis.net/wfs') _set(context, serviceobj, 'pycsw:MdSource', record) _set(context, serviceobj, 'pycsw:InsertDate', util.get_today_and_now()) _set( context, serviceobj, 'pycsw:AnyText', util.get_anytext(etree.tostring(md._capabilities)) ) _set(context, serviceobj, 'pycsw:Type', 'service') _set(context, serviceobj, 'pycsw:Title', md.identification.title) _set(context, serviceobj, 'pycsw:Abstract', md.identification.abstract) _set(context, serviceobj, 'pycsw:Keywords', ','.join(md.identification.keywords)) _set(context, serviceobj, 'pycsw:Creator', md.provider.contact.name) _set(context, serviceobj, 'pycsw:Publisher', md.provider.name) _set(context, serviceobj, 'pycsw:Contributor', md.provider.contact.name) _set(context, serviceobj, 'pycsw:OrganizationName', md.provider.contact.name) contacts = [vars(md.provider.contact)] contacts[0]['role'] = 'pointOfContact' _set(context, serviceobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) _set(context, serviceobj, 'pycsw:AccessConstraints', md.identification.accessconstraints) _set(context, serviceobj, 'pycsw:OtherConstraints', md.identification.fees) _set(context, serviceobj, 'pycsw:Source', record) _set(context, serviceobj, 'pycsw:Format', md.identification.type) _set(context, serviceobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326') _set(context, serviceobj, 'pycsw:DistanceUOM', 'degrees') _set(context, serviceobj, 'pycsw:ServiceType', 'OGC:WFS') _set(context, serviceobj, 'pycsw:ServiceTypeVersion', md.identification.version) _set(context, serviceobj, 'pycsw:Operation', ','.join([d.name for d in md.operations])) _set(context, serviceobj, 'pycsw:OperatesOn', ','.join(list(md.contents))) _set(context, serviceobj, 'pycsw:CouplingType', 'tight') links = [{ 'name': identifier, 'description': 'OGC-WFS Web Feature Service', 'protocol': 'OGC:WFS', 'url': md.url }] _set(context, serviceobj, 'pycsw:Links', json.dumps(links)) # generate record foreach featuretype LOGGER.info('Harvesting %d WFS featuretypes', len(md.contents)) for featuretype in md.contents: recobj = repos.dataset() identifier2 = '%s-%s' % (identifier, md.contents[featuretype].id) _set(context, recobj, 'pycsw:Identifier', identifier2) _set(context, recobj, 'pycsw:Typename', 'csw:Record') _set(context, recobj, 'pycsw:Schema', 'http://www.opengis.net/wfs') _set(context, recobj, 'pycsw:MdSource', record) _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:Type', 'dataset') _set(context, recobj, 'pycsw:ParentIdentifier', identifier) _set(context, recobj, 'pycsw:Title', md.contents[featuretype].title) _set(context, recobj, 'pycsw:Abstract', md.contents[featuretype].abstract) _set(context, recobj, 'pycsw:Keywords', ','.join(md.contents[featuretype].keywords)) _set( context, recobj, 'pycsw:AnyText', util.get_anytext([ md.contents[featuretype].title, md.contents[featuretype].abstract, ','.join(md.contents[featuretype].keywords) ]) ) bbox = md.contents[featuretype].boundingBoxWGS84 if bbox is not None: tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]) wkt_polygon = util.bbox2wktpolygon(tmp) _set(context, recobj, 'pycsw:BoundingBox', wkt_polygon) _set(context, recobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326') _set(context, recobj, 'pycsw:DistanceUOM', 'degrees') bboxs.append(wkt_polygon) params = { 'service': 'WFS', 'version': '1.1.0', 'request': 'GetFeature', 'typename': md.contents[featuretype].id, } links = [{ 'name': md.contents[featuretype].id, 'description': 'OGC-Web Feature Service', 'protocol': 'OGC:WFS', 'url': md.url }, { 'name': md.contents[featuretype].id, 'description': 'File for download', 'protocol': 'WWW:DOWNLOAD-1.0-http--download', 'url': build_get_url(md.url, params) }] _set(context, recobj, 'pycsw:Links', json.dumps(links)) _set(context, recobj, 'pycsw:XML', caps2iso(recobj, md, context)) _set(context, recobj, 'pycsw:MetadataType', 'application/xml') _set(context, recobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) recobjs.append(recobj) # Derive a bbox based on aggregated featuretype bbox values bbox_agg = bbox_from_polygons(bboxs) if bbox_agg is not None: _set(context, serviceobj, 'pycsw:BoundingBox', bbox_agg) _set(context, serviceobj, 'pycsw:XML', caps2iso(serviceobj, md, context)) recobjs.insert(0, serviceobj) return recobjs def _parse_wcs(context, repos, record, identifier): from owslib.wcs import WebCoverageService bboxs = [] recobjs = [] serviceobj = repos.dataset() md = WebCoverageService(record, '1.0.0') # generate record of service instance _set(context, serviceobj, 'pycsw:Identifier', identifier) _set(context, serviceobj, 'pycsw:Typename', 'csw:Record') _set(context, serviceobj, 'pycsw:Schema', 'http://www.opengis.net/wcs') _set(context, serviceobj, 'pycsw:MdSource', record) _set(context, serviceobj, 'pycsw:InsertDate', util.get_today_and_now()) _set( context, serviceobj, 'pycsw:AnyText', util.get_anytext(etree.tostring(md._capabilities)) ) _set(context, serviceobj, 'pycsw:Type', 'service') _set(context, serviceobj, 'pycsw:Title', md.identification.title) _set(context, serviceobj, 'pycsw:Abstract', md.identification.abstract) _set(context, serviceobj, 'pycsw:Keywords', ','.join(md.identification.keywords)) _set(context, serviceobj, 'pycsw:Creator', md.provider.contact.name) _set(context, serviceobj, 'pycsw:Publisher', md.provider.name) _set(context, serviceobj, 'pycsw:Contributor', md.provider.contact.name) _set(context, serviceobj, 'pycsw:OrganizationName', md.provider.contact.name) contacts = [vars(md.provider.contact)] contacts[0]['role'] = 'pointOfContact' _set(context, serviceobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) _set(context, serviceobj, 'pycsw:AccessConstraints', md.identification.accessConstraints) _set(context, serviceobj, 'pycsw:OtherConstraints', md.identification.fees) _set(context, serviceobj, 'pycsw:Source', record) _set(context, serviceobj, 'pycsw:Format', md.identification.type) _set(context, serviceobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326') _set(context, serviceobj, 'pycsw:DistanceUOM', 'degrees') _set(context, serviceobj, 'pycsw:ServiceType', 'OGC:WCS') _set(context, serviceobj, 'pycsw:ServiceTypeVersion', md.identification.version) _set(context, serviceobj, 'pycsw:Operation', ','.join([d.name for d in md.operations])) _set(context, serviceobj, 'pycsw:OperatesOn', ','.join(list(md.contents))) _set(context, serviceobj, 'pycsw:CouplingType', 'tight') links = [{ 'name': identifier, 'description': 'OGC-WCS Web Coverage Service', 'protocol': 'OGC:WCS', 'url': md.url }] _set(context, serviceobj, 'pycsw:Links', json.dumps(links)) # generate record foreach coverage LOGGER.info('Harvesting %d WCS coverages ', len(md.contents)) for coverage in md.contents: recobj = repos.dataset() identifier2 = '%s-%s' % (identifier, md.contents[coverage].id) _set(context, recobj, 'pycsw:Identifier', identifier2) _set(context, recobj, 'pycsw:Typename', 'csw:Record') _set(context, recobj, 'pycsw:Schema', 'http://www.opengis.net/wcs') _set(context, recobj, 'pycsw:MdSource', record) _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:Type', 'dataset') _set(context, recobj, 'pycsw:ParentIdentifier', identifier) _set(context, recobj, 'pycsw:Title', md.contents[coverage].title) _set(context, recobj, 'pycsw:Abstract', md.contents[coverage].abstract) _set(context, recobj, 'pycsw:Keywords', ','.join(md.contents[coverage].keywords)) _set( context, recobj, 'pycsw:AnyText', util.get_anytext([ md.contents[coverage].title, md.contents[coverage].abstract, ','.join(md.contents[coverage].keywords) ]) ) bbox = md.contents[coverage].boundingBoxWGS84 if bbox is not None: tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]) wkt_polygon = util.bbox2wktpolygon(tmp) _set(context, recobj, 'pycsw:BoundingBox', wkt_polygon) _set(context, recobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326') _set(context, recobj, 'pycsw:DistanceUOM', 'degrees') bboxs.append(wkt_polygon) links = [{ 'name': md.contents[coverage].id, 'description': 'OGC-Web Coverage Service', 'protocol': 'OGC:WCS', 'url': md.url }] _set(context, recobj, 'pycsw:Links', json.dumps(links)) _set(context, recobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) _set(context, recobj, 'pycsw:XML', caps2iso(recobj, md, context)) recobjs.append(recobj) # Derive a bbox based on aggregated coverage bbox values bbox_agg = bbox_from_polygons(bboxs) if bbox_agg is not None: _set(context, serviceobj, 'pycsw:BoundingBox', bbox_agg) _set(context, serviceobj, 'pycsw:XML', caps2iso(serviceobj, md, context)) recobjs.insert(0, serviceobj) return recobjs def _parse_wps(context, repos, record, identifier): from owslib.wps import WebProcessingService recobjs = [] serviceobj = repos.dataset() md = WebProcessingService(record) # generate record of service instance _set(context, serviceobj, 'pycsw:Identifier', identifier) _set(context, serviceobj, 'pycsw:Typename', 'csw:Record') _set(context, serviceobj, 'pycsw:Schema', 'http://www.opengis.net/wps/1.0.0') _set(context, serviceobj, 'pycsw:MdSource', record) _set(context, serviceobj, 'pycsw:InsertDate', util.get_today_and_now()) _set( context, serviceobj, 'pycsw:AnyText', util.get_anytext(md._capabilities) ) _set(context, serviceobj, 'pycsw:Type', 'service') _set(context, serviceobj, 'pycsw:Title', md.identification.title) _set(context, serviceobj, 'pycsw:Abstract', md.identification.abstract) _set(context, serviceobj, 'pycsw:Keywords', ','.join(md.identification.keywords)) _set(context, serviceobj, 'pycsw:Creator', md.provider.contact.name) _set(context, serviceobj, 'pycsw:Publisher', md.provider.name) _set(context, serviceobj, 'pycsw:Contributor', md.provider.contact.name) _set(context, serviceobj, 'pycsw:OrganizationName', md.provider.contact.name) contacts = [vars(md.provider.contact)] contacts[0]['role'] = 'pointOfContact' _set(context, serviceobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) _set(context, serviceobj, 'pycsw:AccessConstraints', md.identification.accessconstraints) _set(context, serviceobj, 'pycsw:OtherConstraints', md.identification.fees) _set(context, serviceobj, 'pycsw:Source', record) _set(context, serviceobj, 'pycsw:Format', md.identification.type) _set(context, serviceobj, 'pycsw:ServiceType', 'OGC:WPS') _set(context, serviceobj, 'pycsw:ServiceTypeVersion', md.identification.version) _set(context, serviceobj, 'pycsw:Operation', ','.join([d.name for d in md.operations])) _set(context, serviceobj, 'pycsw:OperatesOn', ','.join([o.identifier for o in md.processes])) _set(context, serviceobj, 'pycsw:CouplingType', 'loose') links = [{ 'name': identifier, 'description': 'OGC-WPS Web Processing Service', 'protocol': 'OGC:WPS', 'url': md.url }, { 'name': identifier, 'description': 'OGC-WPS Capabilities service (ver 1.0.0)', 'protocol': 'OGC:WPS-1.1.0-http-get-capabilities', 'url': build_get_url(md.url, {'service': 'WPS', 'version': '1.0.0', 'request': 'GetCapabilities'}) }] _set(context, serviceobj, 'pycsw:Links', json.dumps(links)) _set(context, serviceobj, 'pycsw:XML', caps2iso(serviceobj, md, context)) _set(context, serviceobj, 'pycsw:MetadataType', 'application/xml') recobjs.append(serviceobj) # generate record foreach process LOGGER.info('Harvesting %d WPS processes', len(md.processes)) for process in md.processes: recobj = repos.dataset() identifier2 = '%s-%s' % (identifier, process.identifier) _set(context, recobj, 'pycsw:Identifier', identifier2) _set(context, recobj, 'pycsw:Typename', 'csw:Record') _set(context, recobj, 'pycsw:Schema', 'http://www.opengis.net/wps/1.0.0') _set(context, recobj, 'pycsw:MdSource', record) _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:Type', 'software') _set(context, recobj, 'pycsw:ParentIdentifier', identifier) _set(context, recobj, 'pycsw:Title', process.title) _set(context, recobj, 'pycsw:Abstract', process.abstract) _set( context, recobj, 'pycsw:AnyText', util.get_anytext([process.title, process.abstract]) ) params = { 'service': 'WPS', 'version': '1.0.0', 'request': 'DescribeProcess', 'identifier': process.identifier } links.append({ 'name': identifier, 'description': 'OGC-WPS DescribeProcess service (ver 1.0.0)', 'protocol': 'OGC:WPS-1.0.0-http-describe-process', 'url': build_get_url(md.url, {'service': 'WPS', 'version': '1.0.0', 'request': 'DescribeProcess', 'identifier': process.identifier}) }) _set(context, recobj, 'pycsw:Links', json.dumps(links)) _set(context, recobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) _set(context, recobj, 'pycsw:XML', caps2iso(recobj, md, context)) _set(context, recobj, 'pycsw:MetadataType', 'application/xml') recobjs.append(recobj) return recobjs def _parse_sos(context, repos, record, identifier, version): from owslib.sos import SensorObservationService bboxs = [] recobjs = [] serviceobj = repos.dataset() if version == '1.0.0': schema = 'http://www.opengis.net/sos/1.0' else: schema = 'http://www.opengis.net/sos/2.0' md = SensorObservationService(record, version=version) # generate record of service instance _set(context, serviceobj, 'pycsw:Identifier', identifier) _set(context, serviceobj, 'pycsw:Typename', 'csw:Record') _set(context, serviceobj, 'pycsw:Schema', schema) _set(context, serviceobj, 'pycsw:MdSource', record) _set(context, serviceobj, 'pycsw:InsertDate', util.get_today_and_now()) _set( context, serviceobj, 'pycsw:AnyText', util.get_anytext(etree.tostring(md._capabilities)) ) _set(context, serviceobj, 'pycsw:Type', 'service') _set(context, serviceobj, 'pycsw:Title', md.identification.title) _set(context, serviceobj, 'pycsw:Abstract', md.identification.abstract) _set(context, serviceobj, 'pycsw:Keywords', ','.join(md.identification.keywords)) _set(context, serviceobj, 'pycsw:Creator', md.provider.contact.name) _set(context, serviceobj, 'pycsw:Publisher', md.provider.name) _set(context, serviceobj, 'pycsw:Contributor', md.provider.contact.name) _set(context, serviceobj, 'pycsw:OrganizationName', md.provider.contact.name) contacts = [vars(md.provider.contact)] contacts[0]['role'] = 'pointOfContact' _set(context, serviceobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) _set(context, serviceobj, 'pycsw:AccessConstraints', md.identification.accessconstraints) _set(context, serviceobj, 'pycsw:OtherConstraints', md.identification.fees) _set(context, serviceobj, 'pycsw:Source', record) _set(context, serviceobj, 'pycsw:Format', md.identification.type) _set(context, serviceobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326') _set(context, serviceobj, 'pycsw:DistanceUOM', 'degrees') _set(context, serviceobj, 'pycsw:ServiceType', 'OGC:SOS') _set(context, serviceobj, 'pycsw:ServiceTypeVersion', md.identification.version) _set(context, serviceobj, 'pycsw:Operation', ','.join([d.name for d in md.operations])) _set(context, serviceobj, 'pycsw:OperatesOn', ','.join(list(md.contents))) _set(context, serviceobj, 'pycsw:CouplingType', 'tight') links = [{ 'name': identifier, 'description': 'OGC-SOS Sensor Observation Service', 'protocol': 'OGC:SOS', 'url': md.url }] _set(context, serviceobj, 'pycsw:Links', json.dumps(links)) # generate record foreach offering LOGGER.info('Harvesting %d SOS ObservationOffering\'s ', len(md.contents)) for offering in md.contents: recobj = repos.dataset() identifier2 = '%s-%s' % (identifier, md.contents[offering].id) _set(context, recobj, 'pycsw:Identifier', identifier2) _set(context, recobj, 'pycsw:Typename', 'csw:Record') _set(context, recobj, 'pycsw:Schema', schema) _set(context, recobj, 'pycsw:MdSource', record) _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:Type', 'dataset') _set(context, recobj, 'pycsw:ParentIdentifier', identifier) _set(context, recobj, 'pycsw:Title', md.contents[offering].description) _set(context, recobj, 'pycsw:Abstract', md.contents[offering].description) begin = md.contents[offering].begin_position end = md.contents[offering].end_position _set(context, recobj, 'pycsw:TempExtent_begin', util.datetime2iso8601(begin) if begin is not None else None) _set(context, recobj, 'pycsw:TempExtent_end', util.datetime2iso8601(end) if end is not None else None) #For observed_properties that have mmi url or urn, we simply want the observation name. observed_properties = [] for obs in md.contents[offering].observed_properties: #Observation is stored as urn representation: urn:ogc:def:phenomenon:mmisw.org:cf:sea_water_salinity if obs.lower().startswith(('urn:', 'x-urn')): observed_properties.append(obs.rsplit(':', 1)[-1]) #Observation is stored as uri representation: http://mmisw.org/ont/cf/parameter/sea_floor_depth_below_sea_surface elif obs.lower().startswith(('http://', 'https://')): observed_properties.append(obs.rsplit('/', 1)[-1]) else: observed_properties.append(obs) #Build anytext from description and the observed_properties. anytext = [] anytext.append(md.contents[offering].description) anytext.extend(observed_properties) _set(context, recobj, 'pycsw:AnyText', util.get_anytext(anytext)) _set(context, recobj, 'pycsw:Keywords', ','.join(observed_properties)) bbox = md.contents[offering].bbox if bbox is not None: tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3]) wkt_polygon = util.bbox2wktpolygon(tmp) _set(context, recobj, 'pycsw:BoundingBox', wkt_polygon) _set(context, recobj, 'pycsw:CRS', md.contents[offering].bbox_srs.id) _set(context, recobj, 'pycsw:DistanceUOM', 'degrees') bboxs.append(wkt_polygon) _set(context, recobj, 'pycsw:Contacts', json.dumps(contacts,default=lambda o: o.__dict__)) _set(context, recobj, 'pycsw:XML', caps2iso(recobj, md, context)) _set(context, recobj, 'pycsw:MetadataType', 'application/xml') recobjs.append(recobj) # Derive a bbox based on aggregated featuretype bbox values bbox_agg = bbox_from_polygons(bboxs) if bbox_agg is not None: _set(context, serviceobj, 'pycsw:BoundingBox', bbox_agg) _set(context, serviceobj, 'pycsw:XML', caps2iso(serviceobj, md, context)) recobjs.insert(0, serviceobj) return recobjs def _parse_fgdc(context, repos, exml): from owslib.fgdc import Metadata recobj = repos.dataset() links = [] md = Metadata(exml) if md.idinfo.datasetid is not None: # we need an identifier _set(context, recobj, 'pycsw:Identifier', md.idinfo.datasetid) else: # generate one ourselves _set(context, recobj, 'pycsw:Identifier', uuid.uuid1().urn) _set(context, recobj, 'pycsw:Typename', 'fgdc:metadata') _set(context, recobj, 'pycsw:Schema', context.namespaces['fgdc']) _set(context, recobj, 'pycsw:MdSource', 'local') _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:XML', md.xml) _set(context, recobj, 'pycsw:MetadataType', 'application/xml') _set(context, recobj, 'pycsw:AnyText', util.get_anytext(exml)) _set(context, recobj, 'pycsw:Language', 'en-US') if hasattr(md.idinfo, 'descript'): _set(context, recobj, 'pycsw:Abstract', md.idinfo.descript.abstract) if hasattr(md.idinfo, 'keywords'): if md.idinfo.keywords.theme: _set(context, recobj, 'pycsw:Keywords', \ ','.join(md.idinfo.keywords.theme[0]['themekey'])) if hasattr(md.idinfo.timeperd, 'timeinfo'): if hasattr(md.idinfo.timeperd.timeinfo, 'rngdates'): _set(context, recobj, 'pycsw:TempExtent_begin', md.idinfo.timeperd.timeinfo.rngdates.begdate) _set(context, recobj, 'pycsw:TempExtent_end', md.idinfo.timeperd.timeinfo.rngdates.enddate) if hasattr(md.idinfo, 'origin'): _set(context, recobj, 'pycsw:Creator', md.idinfo.origin) _set(context, recobj, 'pycsw:Publisher', md.idinfo.origin) _set(context, recobj, 'pycsw:Contributor', md.idinfo.origin) contacts = [] if hasattr(md.idinfo, 'ptcontac'): _set(context, recobj, 'pycsw:OrganizationName', md.idinfo.ptcontac.cntorg) contacts.append(fgdccontact2iso(md.idinfo.ptcontac, 'pointOfContact')) if hasattr(md.metainfo, 'metc'): contacts.append(fgdccontact2iso(md.metainfo.metc, 'pointOfContact')) if hasattr(md.distinfo, 'distrib'): contacts.append(fgdccontact2iso(md.distinfo.distrib, 'distributor')) if len(contacts) > 0: _set(context, recobj, 'pycsw:Contacts', json.dumps(contacts)) _set(context, recobj, 'pycsw:AccessConstraints', md.idinfo.accconst) _set(context, recobj, 'pycsw:OtherConstraints', md.idinfo.useconst) _set(context, recobj, 'pycsw:Date', md.metainfo.metd) if hasattr(md.idinfo, 'spdom') and hasattr(md.idinfo.spdom, 'bbox'): bbox = md.idinfo.spdom.bbox else: bbox = None if hasattr(md.idinfo, 'citation'): if hasattr(md.idinfo.citation, 'citeinfo'): _set(context, recobj, 'pycsw:Type', md.idinfo.citation.citeinfo['geoform']) _set(context, recobj, 'pycsw:Title', md.idinfo.citation.citeinfo['title']) _set(context, recobj, 'pycsw:PublicationDate', md.idinfo.citation.citeinfo['pubdate']) _set(context, recobj, 'pycsw:Format', md.idinfo.citation.citeinfo['geoform']) if md.idinfo.citation.citeinfo['onlink']: for link in md.idinfo.citation.citeinfo['onlink']: links.append({ 'name': None, 'description': None, 'protocol': None, 'url': link }) if hasattr(md, 'distinfo') and hasattr(md.distinfo, 'stdorder'): for link in md.distinfo.stdorder['digform']: tmp = ',%s,,%s' % (link['name'], link['url']) links.append({ 'name': None, 'description': link['name'], 'protocol': None, 'url': link['url'] }) if len(links) > 0: _set(context, recobj, 'pycsw:Links', json.dumps(links)) if bbox is not None: try: tmp = '%s,%s,%s,%s' % (bbox.minx, bbox.miny, bbox.maxx, bbox.maxy) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) except Exception: LOGGER.debug('Coordinates are corrupt') _set(context, recobj, 'pycsw:BoundingBox', None) else: _set(context, recobj, 'pycsw:BoundingBox', None) return recobj def _parse_gm03(context, repos, exml): def get_value_by_language(pt_group, language, pt_type='text'): for ptg in pt_group: if ptg.language == language: if pt_type == 'url': val = ptg.plain_url else: # 'text' val = ptg.plain_text return val from owslib.gm03 import GM03 recobj = repos.dataset() links = [] md = GM03(exml) if hasattr(md.data, 'core'): data = md.data.core elif hasattr(md.data, 'comprehensive'): data = md.data.comprehensive language = data.metadata.language _set(context, recobj, 'pycsw:Identifier', data.metadata.file_identifier) _set(context, recobj, 'pycsw:Typename', 'gm03:TRANSFER') _set(context, recobj, 'pycsw:Schema', context.namespaces['gm03']) _set(context, recobj, 'pycsw:MdSource', 'local') _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:XML', md.xml) _set(context, recobj, 'pycsw:MetadataType', 'application/xml') _set(context, recobj, 'pycsw:AnyText', util.get_anytext(exml)) _set(context, recobj, 'pycsw:Language', data.metadata.language) _set(context, recobj, 'pycsw:Type', data.metadata.hierarchy_level[0]) _set(context, recobj, 'pycsw:Date', data.metadata.date_stamp) for dt in data.date: if dt.date_type == 'modified': _set(context, recobj, 'pycsw:Modified', dt.date) elif dt.date_type == 'creation': _set(context, recobj, 'pycsw:CreationDate', dt.date) elif dt.date_type == 'publication': _set(context, recobj, 'pycsw:PublicationDate', dt.date) elif dt.date_type == 'revision': _set(context, recobj, 'pycsw:RevisionDate', dt.date) if hasattr(data, 'metadata_point_of_contact'): _set(context, recobj, 'pycsw:ResponsiblePartyRole', data.metadata_point_of_contact.role) _set(context, recobj, 'pycsw:Source', data.metadata.dataset_uri) _set(context, recobj, 'pycsw:CRS','urn:ogc:def:crs:EPSG:6.11:4326') if hasattr(data, 'citation'): _set(context, recobj, 'pycsw:Title', get_value_by_language(data.citation.title.pt_group, language)) if hasattr(data, 'data_identification'): _set(context, recobj, 'pycsw:Abstract', get_value_by_language(data.data_identification.abstract.pt_group, language)) if hasattr(data.data_identification, 'topic_category'): _set(context, recobj, 'pycsw:TopicCategory', data.data_identification.topic_category) _set(context, recobj, 'pycsw:ResourceLanguage', data.data_identification.language) if hasattr(data, 'format'): _set(context, recobj, 'pycsw:Format', data.format.name) # bbox if hasattr(data, 'geographic_bounding_box'): try: tmp = '%s,%s,%s,%s' % (data.geographic_bounding_box.west_bound_longitude, data.geographic_bounding_box.south_bound_latitude, data.geographic_bounding_box.east_bound_longitude, data.geographic_bounding_box.north_bound_latitude) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) except Exception: LOGGER.debug('Coordinates are corrupt') _set(context, recobj, 'pycsw:BoundingBox', None) else: _set(context, recobj, 'pycsw:BoundingBox', None) # temporal extent if hasattr(data, 'temporal_extent'): if data.temporal_extent.extent['begin'] is not None and data.temporal_extent.extent['end'] is not None: _set(context, recobj, 'pycsw:TempExtent_begin', data.temporal_extent.extent['begin']) _set(context, recobj, 'pycsw:TempExtent_end', data.temporal_extent.extent['end']) # online linkages name = description = protocol = '' if hasattr(data, 'online_resource'): if hasattr(data.online_resource, 'name'): name = get_value_by_language(data.online_resource.name.pt_group, language) if hasattr(data.online_resource, 'description'): description = get_value_by_language(data.online_resource.description.pt_group, language) linkage = get_value_by_language(data.online_resource.linkage.pt_group, language, 'url') links.append({ 'name': name, 'description': description, 'protocol': protocol, 'url': linkage }) if len(links) > 0: _set(context, recobj, 'pycsw:Links', json.dumps(links)) keywords = [] for kw in data.keywords: keywords.append(get_value_by_language(kw.keyword.pt_group, language)) _set(context, recobj, 'pycsw:Keywords', ','.join(keywords)) # contacts return recobj def _parse_iso(context, repos, exml): """ Parses ISO 19139, ISO 19115p3 """ from owslib.iso import MD_ImageDescription, MD_Metadata, SV_ServiceIdentification from owslib.iso_che import CHE_MD_Metadata recobj = repos.dataset() bbox = None links = [] mdmeta_ns = 'gmd' if exml.tag == '{http://www.geocat.ch/2008/che}CHE_MD_Metadata': md = CHE_MD_Metadata(exml) elif exml.tag == '{http://standards.iso.org/iso/19115/-3/mdb/2.0}MD_Metadata': from owslib.iso3 import MD_Metadata md = MD_Metadata(exml) mdmeta_ns = 'mdb' else: md = MD_Metadata(exml) md_identification = md.identification[0] _set(context, recobj, 'pycsw:Identifier', md.identifier) _set(context, recobj, 'pycsw:Typename', f'{mdmeta_ns}:MD_Metadata') _set(context, recobj, 'pycsw:Schema', context.namespaces['gmd']) _set(context, recobj, 'pycsw:MdSource', 'local') _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:XML', md.xml) _set(context, recobj, 'pycsw:MetadataType', 'application/xml') _set(context, recobj, 'pycsw:AnyText', util.get_anytext(exml)) _set(context, recobj, 'pycsw:Language', md.language or md.languagecode) _set(context, recobj, 'pycsw:Type', md.hierarchy) _set(context, recobj, 'pycsw:ParentIdentifier', md.parentidentifier) _set(context, recobj, 'pycsw:Date', md.datestamp) _set(context, recobj, 'pycsw:Modified', md.datestamp) _set(context, recobj, 'pycsw:Source', md.dataseturi) if md.referencesystem is not None and md.referencesystem.code is not None: try: code_ = 'urn:ogc:def:crs:EPSG::%d' % int(md.referencesystem.code) except ValueError: code_ = md.referencesystem.code _set(context, recobj, 'pycsw:CRS', code_) if md_identification: _set(context, recobj, 'pycsw:Title', md_identification.title) _set(context, recobj, 'pycsw:Edition', md_identification.edition) _set(context, recobj, 'pycsw:AlternateTitle', md_identification.alternatetitle) _set(context, recobj, 'pycsw:Abstract', md_identification.abstract) _set(context, recobj, 'pycsw:Relation', md_identification.aggregationinfo) if hasattr(md_identification, 'temporalextent_start'): _set(context, recobj, 'pycsw:TempExtent_begin', md_identification.temporalextent_start) if hasattr(md_identification, 'temporalextent_end'): _set(context, recobj, 'pycsw:TempExtent_end', md_identification.temporalextent_end) if len(md_identification.topiccategory) > 0: _set(context, recobj, 'pycsw:TopicCategory', md_identification.topiccategory[0]) if len(md_identification.resourcelanguage) > 0: _set(context, recobj, 'pycsw:ResourceLanguage', md_identification.resourcelanguage[0]) elif len(md_identification.resourcelanguagecode) > 0: _set(context, recobj, 'pycsw:ResourceLanguage', md_identification.resourcelanguagecode[0]) # Geographic bounding box if hasattr(md_identification, 'bbox'): bbox = md_identification.bbox else: bbox = None # Vertical extent of a bounding box if hasattr(md_identification, 'extent'): if hasattr(md_identification.extent, 'vertExtMin') and \ md_identification.extent.vertExtMin is not None: _set(context, recobj, 'pycsw:VertExtentMin', md_identification.extent.vertExtMin) if hasattr(md_identification.extent, 'vertExtMax') and \ md_identification.extent.vertExtMax is not None: _set(context, recobj, 'pycsw:VertExtentMax', md_identification.extent.vertExtMax) if (hasattr(md_identification, 'keywords') and len(md_identification.keywords) > 0): all_keywords = [item for sublist in md_identification.keywords for item in sublist.keywords if item is not None] _set(context, recobj, 'pycsw:Keywords', ','.join([ k.name for k in all_keywords if hasattr(k,'name') and k.name not in [None,'']])) _set(context, recobj, 'pycsw:KeywordType', md_identification.keywords[0].type) _set(context, recobj, 'pycsw:Themes', json.dumps([t for t in md_identification.keywords if t.thesaurus is not None], default=lambda o: o.__dict__)) # Creator if (hasattr(md_identification, 'creator') and len(md_identification.creator) > 0): all_orgs = set([item.organization for item in md_identification.creator if hasattr(item, 'organization') and item.organization is not None]) _set(context, recobj, 'pycsw:Creator', ';'.join(all_orgs)) # Publisher if (hasattr(md_identification, 'publisher') and len(md_identification.publisher) > 0): all_orgs = set([item.organization for item in md_identification.publisher if hasattr(item, 'organization') and item.organization is not None]) _set(context, recobj, 'pycsw:Publisher', ';'.join(all_orgs)) # Contributor if (hasattr(md_identification, 'contributor') and len(md_identification.contributor) > 0): all_orgs = set([item.organization for item in md_identification.contributor if hasattr(item, 'organization') and item.organization is not None]) _set(context, recobj, 'pycsw:Contributor', ';'.join(all_orgs)) if (hasattr(md_identification, 'contact') and len(md_identification.contact) > 0): all_orgs = set([item.organization for item in md_identification.contact if hasattr(item, 'organization') and item.organization is not None]) _set(context, recobj, 'pycsw:OrganizationName', ';'.join(all_orgs)) _set(context, recobj, 'pycsw:Contacts', json.dumps(md_identification.contact, default=lambda o: o.__dict__)) if len(md_identification.securityconstraints) > 0: _set(context, recobj, 'pycsw:SecurityConstraints', md_identification.securityconstraints[0]) if len(md_identification.accessconstraints) > 0: _set(context, recobj, 'pycsw:AccessConstraints', md_identification.accessconstraints[0]) if len(md_identification.otherconstraints) > 0: _set(context, recobj, 'pycsw:OtherConstraints', md_identification.otherconstraints[0]) if hasattr(md_identification, 'date'): for datenode in md_identification.date: if datenode.type == 'revision': _set(context, recobj, 'pycsw:RevisionDate', datenode.date) elif datenode.type == 'creation': _set(context, recobj, 'pycsw:CreationDate', datenode.date) elif datenode.type == 'publication': _set(context, recobj, 'pycsw:PublicationDate', datenode.date) if hasattr(md_identification, 'extent') and hasattr(md_identification.extent, 'description_code'): _set(context, recobj, 'pycsw:GeographicDescriptionCode', md_identification.extent.description_code) if len(md_identification.denominators) > 0: _set(context, recobj, 'pycsw:Denominator', md_identification.denominators[0]) if len(md_identification.distance) > 0: _set(context, recobj, 'pycsw:DistanceValue', float(md_identification.distance[0])) if len(md_identification.uom) > 0: _set(context, recobj, 'pycsw:DistanceUOM', md_identification.uom[0]) if len(md_identification.classification) > 0: _set(context, recobj, 'pycsw:Classification', md_identification.classification[0]) if len(md_identification.uselimitation) > 0: _set(context, recobj, 'pycsw:ConditionApplyingToAccessAndUse', md_identification.uselimitation[0]) service_types = [] from owslib.iso import SV_ServiceIdentification for smd in md.identification: if isinstance(smd, SV_ServiceIdentification): service_types.append(smd.type) _set(context, recobj, 'pycsw:ServiceTypeVersion', smd.version) _set(context, recobj, 'pycsw:CouplingType', smd.couplingtype) _set(context, recobj, 'pycsw:ServiceType', ','.join(service_types)) if hasattr(md_identification, 'dataquality'): _set(context, recobj, 'pycsw:Degree', md.dataquality.conformancedegree) _set(context, recobj, 'pycsw:Lineage', md.dataquality.lineage) _set(context, recobj, 'pycsw:SpecificationTitle', md.dataquality.specificationtitle) if hasattr(md.dataquality, 'specificationdate'): _set(context, recobj, 'pycsw:specificationDate', md.dataquality.specificationdate[0].date) _set(context, recobj, 'pycsw:SpecificationDateType', md.dataquality.specificationdate[0].datetype) if hasattr(md, 'contact') and len(md.contact) > 0: _set(context, recobj, 'pycsw:ResponsiblePartyRole', md.contact[0].role) if hasattr(md, 'contentinfo') and len(md.contentinfo) > 0: for ci in md.contentinfo: if isinstance(ci, MD_ImageDescription): _set(context, recobj, 'pycsw:CloudCover', float(ci.cloud_cover)) _set(context, recobj, 'pycsw:IlluminationElevationAngle', ci.illumination_elevation_angle) keywords = _get(context, recobj, 'pycsw:Keywords') if ci.processing_level is not None: pl_keyword = 'eo:processingLevel:' + ci.processing_level if keywords is None: keywords = pl_keyword else: keywords += ',' + pl_keyword _set(context, recobj, 'pycsw:Keywords', keywords) bands = [] for band in ci.bands: band_info = { 'id': band.id, 'units': band.units, 'min': band.min, 'max': band.max } bands.append(band_info) if len(bands) > 0: _set(context, recobj, 'pycsw:Bands', json.dumps(bands)) if hasattr(md, 'acquisition') and md.acquisition is not None: platform = md.acquisition.platforms[0] _set(context, recobj, 'pycsw:Platform', platform.identifier) if platform.instruments: instrument = platform.instruments[0] _set(context, recobj, 'pycsw:Instrument', instrument.identifier) _set(context, recobj, 'pycsw:SensorType', instrument.type) all_formats = [] if hasattr(md.distribution, 'format') and md.distribution.format is not None: all_formats.append(md.distribution.format) LOGGER.info('Scanning for links') if hasattr(md, 'distribution'): dist_links = [] if hasattr(md.distribution, 'online'): LOGGER.debug(f'Scanning for {mdmeta_ns}:transferOptions element(s)') dist_links.extend(md.distribution.online) if hasattr(md.distribution, 'distributor'): LOGGER.debug(f'Scanning for {mdmeta_ns}:distributorTransferOptions element(s)') for dist_member in md.distribution.distributor: dist_links.extend(dist_member.online) for link in dist_links: if link.url is not None and link.protocol is None: # take a best guess link.protocol = sniff_link(link.url) if (link.protocol is not None and link.protocol not in all_formats): all_formats.append(link.protocol) links.append({ 'name': link.name, 'description': link.description, 'protocol': link.protocol, 'url': link.url, 'function': link.function }) _set(context, recobj, 'pycsw:Format', ','.join(all_formats)) try: LOGGER.debug('Scanning for srv:SV_ServiceIdentification links') for sident in md.identification: if hasattr(sident, 'operations'): for sops in sident.operations: for scpt in sops['connectpoint']: LOGGER.debug('adding srv link %s', scpt.url) linkobj = { 'name': scpt.name, 'description': scpt.description, 'protocol': scpt.protocol, 'url': scpt.url } links.append(linkobj) except Exception: # srv: identification does not exist LOGGER.exception('no srv:SV_ServiceIdentification links found') if hasattr(md_identification, 'graphicoverview'): for thumb in md_identification.graphicoverview: links.append({ 'name': 'preview', 'description': 'Web image thumbnail (URL)', 'protocol': 'WWW:LINK-1.0-http--image-thumbnail', 'url': thumb }) if len(links) > 0: _set(context, recobj, 'pycsw:Links', json.dumps(links)) if bbox is not None: try: tmp = '%s,%s,%s,%s' % (bbox.minx, bbox.miny, bbox.maxx, bbox.maxy) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) except Exception: LOGGER.debug('Coordinates are corrupt') _set(context, recobj, 'pycsw:BoundingBox', None) else: _set(context, recobj, 'pycsw:BoundingBox', None) return recobj def _parse_dc(context, repos, exml): from owslib.csw import CswRecord recobj = repos.dataset() links = [] md = CswRecord(exml) if md.bbox is None: bbox = None else: bbox = md.bbox _set(context, recobj, 'pycsw:Identifier', md.identifier) _set(context, recobj, 'pycsw:Typename', 'csw:Record') _set(context, recobj, 'pycsw:Schema', context.namespaces['csw']) _set(context, recobj, 'pycsw:MdSource', 'local') _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:XML', md.xml) _set(context, recobj, 'pycsw:MetadataType', 'application/xml') _set(context, recobj, 'pycsw:AnyText', util.get_anytext(exml)) _set(context, recobj, 'pycsw:Language', md.language) _set(context, recobj, 'pycsw:Type', md.type) _set(context, recobj, 'pycsw:Title', md.title) _set(context, recobj, 'pycsw:AlternateTitle', md.alternative) _set(context, recobj, 'pycsw:Abstract', md.abstract) if md.subjects is not None and len(md.subjects) > 0 and None not in md.subjects: _set(context, recobj, 'pycsw:Keywords', ','.join(md.subjects)) _set(context, recobj, 'pycsw:ParentIdentifier', md.ispartof) _set(context, recobj, 'pycsw:Relation', md.relation) _set(context, recobj, 'pycsw:TempExtent_begin', md.temporal) _set(context, recobj, 'pycsw:TempExtent_end', md.temporal) _set(context, recobj, 'pycsw:ResourceLanguage', md.language) _set(context, recobj, 'pycsw:Creator', md.creator) _set(context, recobj, 'pycsw:Publisher', md.publisher) _set(context, recobj, 'pycsw:Contributor', md.contributor) _set(context, recobj, 'pycsw:OrganizationName', md.rightsholder) if md.rights is not None and len(md.rights) > 0 and None not in md.rights: _set(context, recobj, 'pycsw:ConditionApplyingToAccessAndUse', ','.join(md.rights)) _set(context, recobj, 'pycsw:AccessConstraints', md.accessrights) _set(context, recobj, 'pycsw:OtherConstraints', md.license) _set(context, recobj, 'pycsw:Date', md.date) _set(context, recobj, 'pycsw:CreationDate', md.created) _set(context, recobj, 'pycsw:PublicationDate', md.issued) _set(context, recobj, 'pycsw:Modified', md.modified) _set(context, recobj, 'pycsw:Format', md.format) _set(context, recobj, 'pycsw:Source', md.source) for ref in md.references: links.append({ 'name': None, 'description': None, 'protocol': ref['scheme'], 'url': ref['url'], }) for uri in md.uris: links.append({ 'name': uri['name'], 'description': uri['description'], 'protocol': uri['protocol'], 'url': uri['url'], }) if len(links) > 0: _set(context, recobj, 'pycsw:Links', json.dumps(links)) if bbox is not None: try: tmp = '%s,%s,%s,%s' % (bbox.minx, bbox.miny, bbox.maxx, bbox.maxy) _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp)) except Exception: LOGGER.debug('Coordinates are corrupt') _set(context, recobj, 'pycsw:BoundingBox', None) else: _set(context, recobj, 'pycsw:BoundingBox', None) return recobj def _parse_json_record(context, repos, record): """Parse JSON record""" recobj = None if 'conformsTo' in record: LOGGER.debug('Parsing OGC API - Records record model') recobj = _parse_oarec_record(context, repos, record) elif 'stac_version' in record: LOGGER.debug('Parsing STAC resource') recobj = _parse_stac_resource(context, repos, record) if recobj is None: raise RuntimeError('Unsupported JSON metadata format') atom_xml = atom.write_record(recobj, 'full', context) _set(context, recobj, 'pycsw:XML', etree.tostring(atom_xml)) return recobj def _parse_oarec_record(context, repos, record): """Parse OARec record""" conformance = 'http://www.opengis.net/spec/ogcapi-records-1/1.0/req/record-core' recobj = repos.dataset() keywords = [] links = [] _set(context, recobj, 'pycsw:Identifier', record['id']) _set(context, recobj, 'pycsw:Typename', 'csw:Record') _set(context, recobj, 'pycsw:Schema', conformance) _set(context, recobj, 'pycsw:MdSource', 'local') _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:XML', '') # FIXME: transform into XML? or not, to validate _set(context, recobj, 'pycsw:Metadata', json.dumps(record)) _set(context, recobj, 'pycsw:MetadataType', 'application/geo+json') _set(context, recobj, 'pycsw:AnyText', ' '.join([str(t) for t in util.get_anytext_from_obj(record)])) language = record['properties'].get('language') if language is not None and isinstance(language, dict): _set(context, recobj, 'pycsw:Language', language.get('code')) _set(context, recobj, 'pycsw:Type', record['properties']['type']) _set(context, recobj, 'pycsw:Title', record['properties']['title']) _set(context, recobj, 'pycsw:Abstract', record['properties'].get('description')) if 'keywords' in record['properties']: keywords = record['properties']['keywords'] _set(context, recobj, 'pycsw:Keywords', ','.join(keywords)) if 'themes' in record['properties']: _set(context, recobj, 'pycsw:Themes', json.dumps(record['properties']['themes'])) if 'links' in record: for link in record['links']: new_link = { 'url': link.get('href') } if link.get('title') is not None: new_link['name'] = link.get('title') new_link['description'] = link.get('title') if link.get('description') is not None: new_link['description'] = link.get('description') if link.get('type') is not None: new_link['protocol'] = link.get('type') if link.get('rel') is not None: new_link['function'] = link.get('rel') links.append(new_link) if links: _set(context, recobj, 'pycsw:Links', json.dumps(links)) if record.get('geometry') is not None: _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(util.geojson_geometry2bbox(record['geometry']))) if 'temporal' in record['properties'].get('extent', []): _set(context, recobj, 'pycsw:TempExtent_begin', record['properties']['extent']['temporal']['interval'][0]) _set(context, recobj, 'pycsw:TempExtent_end', record['properties']['extent']['temporal']['interval'][1]) return recobj def _parse_stac_resource(context, repos, record): """Parse STAC resource""" recobj = repos.dataset() keywords = [] links = [] bbox_wkt = None stac_type = record.get('type', 'Feature') if stac_type == 'Feature': LOGGER.debug('Parsing STAC Item') conformance = 'https://github.com/radiantearth/stac-spec/tree/master/item-spec/item-spec.md' typename = 'stac:Item' metadata_type = 'application/geo+json' stype = 'item' title = record['properties'].get('title') abstract = record['properties'].get('description') _set(context, recobj, 'pycsw:CreationDate', record['properties'].get('created')) _set(context, recobj, 'pycsw:Modified', record['properties'].get('updated')) _set(context, recobj, 'pycsw:Platform', record['properties'].get('platform')) _set(context, recobj, 'pycsw:OtherConstraints', record['properties'].get('license')) instruments = record['properties'].get('instruments') if instruments is not None: _set(context, recobj, 'pycsw:Instrument', ','.join(instruments)) if record['properties'].get('gsd') is not None: _set(context, recobj, 'pycsw:DistanceValue', float(record['properties']['gsd'])) _set(context, recobj, 'pycsw:DistanceUOM', 'm') if record.get('geometry') is not None: bbox_wkt = util.bbox2wktpolygon(util.geojson_geometry2bbox(record['geometry'])) elif stac_type == 'Collection': LOGGER.debug('Parsing STAC Collection') conformance = 'https://github.com/radiantearth/stac-spec/tree/master/collection-spec/collection-spec.md' typename = 'stac:Collection' metadata_type = 'application/json' stype = 'collection' title = record.get('title') abstract = record.get('description') _set(context, recobj, 'pycsw:CreationDate', record.get('created')) _set(context, recobj, 'pycsw:Modified', record.get('updated')) _set(context, recobj, 'pycsw:Platform', record.get('platform')) _set(context, recobj, 'pycsw:OtherConstraints', record.get('license')) instruments = record.get('instruments') if instruments is not None: _set(context, recobj, 'pycsw:Instrument', ','.join(instruments)) if record.get('gsd') is not None: _set(context, recobj, 'pycsw:DistanceValue', float(record['gsd'])) _set(context, recobj, 'pycsw:DistanceUOM', 'm') if 'extent' in record and 'spatial' in record['extent']: bbox_csv = ','.join(str(t) for t in record['extent']['spatial']['bbox'][0]) bbox_wkt = util.bbox2wktpolygon(bbox_csv) if 'extent' in record and 'temporal' in record['extent'] and 'interval' in record['extent']['temporal']: _set(context, recobj, 'pycsw:TempExtent_begin', record['extent']['temporal']['interval'][0][0]) _set(context, recobj, 'pycsw:TempExtent_end', record['extent']['temporal']['interval'][0][1]) elif stac_type == 'Catalog': LOGGER.debug('Parsing STAC Catalog') conformance = 'https://github.com/radiantearth/stac-spec/tree/master/catalog-spec/catalog-spec.md' typename = 'stac:Catalog' metadata_type = 'application/json' stype = 'catalog' title = record.get('title') abstract = record.get('description') _set(context, recobj, 'pycsw:CreationDate', record.get('created')) _set(context, recobj, 'pycsw:Modified', record.get('updated')) _set(context, recobj, 'pycsw:Platform', record.get('platform')) _set(context, recobj, 'pycsw:OtherConstraints', record.get('license')) instruments = record.get('instruments') if instruments is not None: _set(context, recobj, 'pycsw:Instrument', ','.join(instruments)) _set(context, recobj, 'pycsw:Identifier', record['id']) _set(context, recobj, 'pycsw:Typename', typename) _set(context, recobj, 'pycsw:Schema', conformance) _set(context, recobj, 'pycsw:MdSource', 'local') _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now()) _set(context, recobj, 'pycsw:XML', '') # FIXME: transform into XML? or not, to validate _set(context, recobj, 'pycsw:Metadata', json.dumps(record)) _set(context, recobj, 'pycsw:MetadataType', metadata_type) _set(context, recobj, 'pycsw:AnyText', ' '.join([str(t) for t in util.get_anytext_from_obj(record)])) _set(context, recobj, 'pycsw:Type', stype) _set(context, recobj, 'pycsw:Title', title) _set(context, recobj, 'pycsw:Abstract', abstract) _set(context, recobj, 'pycsw:BoundingBox', bbox_wkt) if 'links' in record: for link in record['links']: new_link = { 'url': link.get('href') } if link.get('title') is not None: new_link['name'] = link.get('title') new_link['description'] = link.get('title') if link.get('description') is not None: new_link['description'] = link.get('description') if link.get('type') is not None: new_link['protocol'] = link.get('type') if link.get('rel') is not None: new_link['function'] = link.get('rel') links.append(new_link) if 'assets' in record: for key, link in record['assets'].items(): new_link = { 'url': link.get('href') } if link.get('title') is not None: new_link['name'] = key new_link['description'] = link.get('title') if link.get('type') is not None: new_link['protocol'] = link.get('type') if link.get('rel') is not None: new_link['function'] = link.get('rel') else: new_link['function'] = 'enclosure' links.append(new_link) if links: _set(context, recobj, 'pycsw:Links', json.dumps(links)) if stac_type == 'Feature': if 'keywords' in record['properties']: keywords = record['properties']['keywords'] _set(context, recobj, 'pycsw:Keywords', ','.join(keywords)) if 'start_datetime' in record['properties']: _set(context, recobj, 'pycsw:TempExtent_begin', record['properties']['start_datetime']) if 'end_datetime' in record['properties']: _set(context, recobj, 'pycsw:TempExtent_end', record['properties']['end_datetime']) if 'datetime' in record['properties']: _set(context, recobj, 'pycsw:Date', record['properties']['datetime']) if 'start_datetime' not in record['properties'] and 'end_datetime' not in record['properties']: _set(context, recobj, 'pycsw:TempExtent_begin', record['properties']['datetime']) _set(context, recobj, 'pycsw:TempExtent_end', record['properties']['datetime']) if 'eo:cloud_cover' in record['properties']: _set(context, recobj, 'pycsw:CloudCover', float(record['properties']['eo:cloud_cover'])) if 'processing:lineage' in record['properties']: _set(context, recobj, 'pycsw:Lineage', record['properties']['processing:lineage']) if 'collection' in record: _set(context, recobj, 'pycsw:ParentIdentifier', record['collection']) _set(context, recobj, 'pycsw:IlluminationElevationAngle', record['properties'].get('view:off_nadir')) if stac_type in ['Collection', 'Catalog']: if 'keywords' in record: keywords = record['keywords'] _set(context, recobj, 'pycsw:Keywords', ','.join(keywords)) if 'start_datetime' in record: _set(context, recobj, 'pycsw:TempExtent_begin', record['start_datetime']) if 'end_datetime' in record: _set(context, recobj, 'pycsw:TempExtent_end', record['end_datetime']) if 'datetime' in record: _set(context, recobj, 'pycsw:Date', record['datetime']) if 'start_datetime' not in record and 'end_datetime' not in record: _set(context, recobj, 'pycsw:TempExtent_begin', record['datetime']) _set(context, recobj, 'pycsw:TempExtent_end', record['datetime']) return recobj def fgdccontact2iso(cnt, role='pointOfContact'): """Creates a iso format contact (owslib style) from fgdc format""" return { 'name': cnt.cntper, 'organization': cnt.cntorg, 'position': cnt.cntpos, 'phone': cnt.voice, 'address': cnt.address, 'city': cnt.city, 'region': cnt.state, 'postcode': cnt.postal, 'country': cnt.country, 'email': cnt.email, 'role': role } def caps2iso(record, caps, context): """Creates ISO metadata from Capabilities XML""" from pycsw.plugins.profiles.apiso.apiso import APISO apiso_obj = APISO(context.model, context.namespaces, context) apiso_obj.ogc_schemas_base = 'http://schemas.opengis.net' apiso_obj.url = context.url queryables = dict(apiso_obj.repository['queryables']['SupportedISOQueryables'].items()) iso_xml = apiso_obj.write_record(record, 'full', 'http://www.isotc211.org/2005/gmd', queryables, caps) return etree.tostring(iso_xml) def bbox_from_polygons(bboxs): """Derive an aggregated bbox from n polygons Parameters ---------- bboxs: list A sequence of strings containing Well-Known Text representations of polygons Returns ------- str Well-Known Text representation of the aggregated bounding box for all the input polygons """ try: multi_pol = MultiPolygon( [loads(bbox) for bbox in bboxs] ) bstr = ",".join([f"{b:.2f}" for b in multi_pol.bounds]) return util.bbox2wktpolygon(bstr) except Exception as err: raise RuntimeError('Cannot aggregate polygons: %s' % str(err)) from err ================================================ FILE: pycsw/core/pygeofilter_evaluate.py ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2021 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from shapely import box from shapely.geometry import shape from sqlalchemy import text from pygeofilter import ast from pygeofilter.values import Envelope from pygeofilter.backends.evaluator import handle from pygeofilter.backends.sqlalchemy import filters from pygeofilter.backends.sqlalchemy.evaluate import SQLAlchemyFilterEvaluator from pycsw.core.util import bbox2wktpolygon LOGGER = logging.getLogger(__name__) class PycswFilterEvaluator(SQLAlchemyFilterEvaluator): def __init__(self, field_mapping=None, dbtype='sqlite', undefined_as_null=None): super().__init__(field_mapping, undefined_as_null=undefined_as_null) self._pycsw_dbtype = dbtype @handle(ast.GeometryIntersects) def intersects(self, node, lhs, rhs): LOGGER.debug('Overriding INTERSECT filter handling') geometry = self.field_mapping['bbox'].key try: crs = node.crs except AttributeError: crs = 4326 if isinstance(node.rhs, Envelope): wkt = box(node.rhs.x1, node.rhs.x2, node.rhs.y1, node.rhs.y2, ccw=False).wkt else: wkt = shape(node.rhs.geometry).wkt if self._pycsw_dbtype == 'postgresql+postgis+native': return text(f"ST_Intersects({geometry}, 'SRID={crs};{wkt}')") else: return text(f"query_spatial({geometry}, '{wkt}', 'intersects', 'false') = 'true'") # noqa @handle(ast.BBox) def bbox(self, node, lhs): LOGGER.debug('Overriding BBOX filter handling') geometry = self.field_mapping['bbox'].key crs = node.crs or 4326 bbox_string = f'{node.minx},{node.miny},{node.maxx},{node.maxy}' wkt = bbox2wktpolygon(bbox_string) if self._pycsw_dbtype == 'postgresql+postgis+native': return text(f"ST_Intersects({geometry}, 'SRID={crs};{wkt}')") else: return text(f"query_spatial({geometry}, '{wkt}', 'bbox', 'false') = 'true'") # noqa @handle(ast.Equal) def equal(self, node, lhs, rhs): list_props = [ 'dataset.keywords', 'dataset.instrument' ] if str(lhs.prop) in list_props: LOGGER.debug(f'Overriding {lhs.prop} "=" with "ilike"') node.pattern = f'%{rhs}%' node.nocase = False node.not_ = False return self.ilike(node, lhs) return filters.runop(lhs, rhs, '=') @handle(ast.Like) def ilike(self, node, lhs): LOGGER.debug('Overriding ILIKE filter handling') LOGGER.debug(f'Term: {node.pattern}') if (str(lhs.prop) == 'dataset.anytext' and self._pycsw_dbtype.startswith('postgres')): if '%' not in node.pattern: LOGGER.debug('Kicking into PostgreSQL FTS mode') return text(f"plainto_tsquery('english', '{node.pattern}') @@ anytext_tsvector") # noqa LOGGER.debug('Default ILIKE behaviour') return filters.like( lhs, node.pattern, not node.nocase, node.not_ ) def to_filter(ast, dbtype, field_mapping=None): return PycswFilterEvaluator(field_mapping, dbtype).evaluate(ast) ================================================ FILE: pycsw/core/repository.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # Ricardo Garcia Silva # # Copyright (c) 2024 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import inspect import logging import os from time import sleep from shapely.wkt import loads from shapely.errors import ShapelyError from sqlalchemy import create_engine, func, __version__, select from sqlalchemy.exc import OperationalError from sqlalchemy.sql import text from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import create_session from pycsw.core import util from pycsw.core.etree import etree from pycsw.core.etree import PARSER LOGGER = logging.getLogger(__name__) class Repository(object): _engines = {} @classmethod def create_engine(clazz, url): ''' SQL Alchemy engines are thread-safe and simple wrappers for connection pools https://groups.google.com/forum/#!topic/sqlalchemy/t8i3RSKZGb0 To reduce startup time we can cache the engine as a class variable in the repository object and do database initialization once Engines are memoized by url ''' if url not in clazz._engines: LOGGER.info('creating new engine: %s', util.sanitize_db_connect(url)) engine = create_engine('%s' % url, echo=False, pool_pre_ping=True) # load SQLite query bindings # This can be directly bound via events # for sqlite < 0.7, we need to to this on a per-connection basis if engine.name in ['sqlite', 'sqlite3'] and __version__ >= '0.7': from sqlalchemy import event @event.listens_for(engine, "connect") def connect(dbapi_connection, connection_rec): create_custom_sql_functions(dbapi_connection) clazz._engines[url] = engine return clazz._engines[url] ''' Class to interact with underlying repository ''' def __init__(self, database, context, app_root=None, table='records', repo_filter=None, stable_sort = False): ''' Initialize repository ''' self.context = context self.filter = repo_filter self.stable_sort = stable_sort self.fts = False self.database = database self.table = table # Don't use relative paths, this is hack to get around # most wsgi restriction... if (app_root and self.database.startswith('sqlite:///') and not self.database.startswith('sqlite:////')): self.database = self.database.replace('sqlite:///', 'sqlite:///%s%s' % (app_root, os.sep)) self.engine = Repository.create_engine('%s' % self.database) base = declarative_base(bind=self.engine) LOGGER.info('binding ORM to existing database') self.postgis_geometry_column = None schema_name, table_name = table.rpartition(".")[::2] default_table_args = { "autoload": True, "schema": schema_name or None } column_constraints = context.md_core_model.get("column_constraints") # Note: according to the sqlalchemy docs available here: # # https://docs.sqlalchemy.org/en/14/orm/declarative_tables.html#declarative-table-configuration # # the __table_args__ attribute can either be a tuple or a dict if column_constraints is not None: table_args = tuple((*column_constraints, default_table_args)) else: table_args = default_table_args self.dataset = type( 'dataset', (base,), { "__tablename__": table_name, "__table_args__": table_args } ) self.dbtype = self.engine.name self.session = create_session(self.engine) self.func = func temp_dbtype = None self.query_mappings = { 'identifier': self.dataset.identifier, 'type': self.dataset.type, 'typename': self.dataset.typename, 'parentidentifier': self.dataset.parentidentifier, 'collections': self.dataset.parentidentifier, 'updated': self.dataset.insert_date, 'title': self.dataset.title, 'description': self.dataset.abstract, 'keywords': self.dataset.keywords, 'edition': self.dataset.edition, 'anytext': self.dataset.anytext, 'bbox': self.dataset.wkt_geometry, 'date': self.dataset.date, 'date_creation': self.dataset.date_creation, 'date_modified': self.dataset.date_modified, 'datetime': self.dataset.date, 'time_begin': self.dataset.time_begin, 'time_end': self.dataset.time_end, 'platform': self.dataset.platform, 'cloudcover': self.dataset.cloudcover, 'instrument': self.dataset.instrument, 'sensortype': self.dataset.sensortype, 'off_nadir': self.dataset.illuminationelevationangle, 'distancevalue': self.dataset.distancevalue, 'otherconstraints': self.dataset.otherconstraints } if self.dbtype == 'postgresql': # check if PostgreSQL is enabled with PostGIS 1.x try: self.session.execute(select([func.postgis_version()])) temp_dbtype = 'postgresql+postgis+wkt' LOGGER.debug('PostgreSQL+PostGIS1+WKT detected') except Exception: LOGGER.exception('PostgreSQL+PostGIS1+WKT detection failed') # check if PostgreSQL is enabled with PostGIS 2.x try: self.session.execute('select(postgis_version())') temp_dbtype = 'postgresql+postgis+wkt' LOGGER.debug('PostgreSQL+PostGIS2+WKT detected') except Exception: LOGGER.exception('PostgreSQL+PostGIS2+WKT detection failed') # check if a native PostGIS geometry column exists try: result = self.session.execute( "select f_geometry_column " "from geometry_columns " "where f_table_name = '%s' " "and f_geometry_column != 'wkt_geometry' " "limit 1;" % table_name ) row = result.fetchone() self.postgis_geometry_column = str(row['f_geometry_column']) temp_dbtype = 'postgresql+postgis+native' LOGGER.debug('PostgreSQL+PostGIS+Native detected') except Exception: LOGGER.exception('PostgreSQL+PostGIS+Native not picked up: %s', table_name) # check if a native PostgreSQL FTS GIN index exists result = self.session.execute("select relname from pg_class where relname='fts_gin_idx'").scalar() self.fts = bool(result) LOGGER.debug('PostgreSQL FTS enabled: %r', self.fts) if temp_dbtype is not None: LOGGER.debug('%s support detected', temp_dbtype) self.dbtype = temp_dbtype if self.dbtype == 'postgresql+postgis+native': LOGGER.debug('Adjusting to PostGIS geometry column (wkb_geometry)') self.query_mappings['bbox'] = self.dataset.wkb_geometry self.query_mappings['geometry'] = self.dataset.wkb_geometry if self.dbtype in ['sqlite', 'sqlite3']: # load SQLite query bindings # <= 0.6 behaviour if not __version__ >= '0.7': self.connection = self.engine.raw_connection() create_custom_sql_functions(self.connection) LOGGER.info('setting repository queryables') # generate core queryables db and obj bindings self.queryables = {} for tname in self.context.model['typenames']: for qname in self.context.model['typenames'][tname]['queryables']: self.queryables[qname] = {} for qkey, qvalue in \ self.context.model['typenames'][tname]['queryables'][qname].items(): self.queryables[qname][qkey] = qvalue # flatten all queryables # TODO smarter way of doing this self.queryables['_all'] = {} for qbl in self.queryables: if qbl != '_all': self.queryables['_all'].update(self.queryables[qbl]) self.queryables['_all'].update(self.context.md_core_model['mappings']) def ping(self, max_tries=10, wait_seconds=10): LOGGER.debug(f"Waiting for {util.sanitize_db_connect(self.database)}...") if self.database.startswith('sqlite'): sql = 'SELECT sqlite_version();' else: sql = 'SELECT version();' engine = create_engine(self.database) current_try = 0 while current_try < max_tries: try: engine.execute(sql) LOGGER.debug("Database is already up!") break except OperationalError as err: LOGGER.debug(f"Database not responding yet {err}") current_try += 1 sleep(wait_seconds) else: raise RuntimeError( f"Database not responding at {util.sanitize_db_connect(self.database)} after {max_tries} tries. ") def rebuild_db_indexes(self): """Rebuild database indexes""" LOGGER.info('Rebuilding database %s, table %s', util.sanitize_db_connect(self.database), self.table) connection = self.engine.connect() connection.autocommit = True connection.execute('REINDEX %s' % self.table) connection.close() LOGGER.info('Done') def optimize_db(self): """Optimize database""" from sqlalchemy.exc import ArgumentError, OperationalError LOGGER.info('Optimizing database %s', util.sanitize_db_connect(self.database)) connection = self.engine.connect() try: # PostgreSQL connection.execution_options(isolation_level="AUTOCOMMIT") connection.execute('VACUUM ANALYZE') except (ArgumentError, OperationalError): # SQLite connection.autocommit = True connection.execute('VACUUM') connection.execute('ANALYZE') finally: connection.close() LOGGER.info('Done') def _create_values(self, values): value_dict = {} for num, value in enumerate(values): value_dict['pvalue%d' % num] = value return value_dict def describe(self): ''' Derive table columns and types ''' type_mappings = { 'TEXT': 'string', 'VARCHAR': 'string', 'FLOAT': 'number' } properties = { 'geometry': { '$ref': 'https://geojson.org/schema/Polygon.json', 'x-ogc-role': 'primary-geometry' } } for i in self.dataset.__table__.columns: if i.name in ['anytext', 'metadata', 'metadata_type', 'xml']: continue properties[i.name] = { 'title': i.name } if i.name == 'identifier': properties[i.name]['x-ogc-role'] = 'id' try: properties[i.name]['type'] = type_mappings[str(i.type)] except Exception as err: LOGGER.debug(f'Cannot determine type: {err}') return properties def query_ids(self, ids): ''' Query by list of identifiers ''' column = getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:Identifier']) query = self.session.query(self.dataset).filter(column.in_(ids)) return self._get_repo_filter(query).all() def query_collections(self, filters=None, limit=10): ''' Query for parent collections ''' column = getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:ParentIdentifier']) collections = self.session.query(column).distinct() results = self._get_repo_filter(collections).all() ids = [res[0] for res in results if res[0] is not None] column = getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:Identifier']) query = self.session.query(self.dataset).filter(column.in_(ids)) collection_typenames = [ 'stac:Collection' ] column = getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:Typename']) query2 = self.session.query(self.dataset).filter(column.in_(collection_typenames)) if filters is not None: LOGGER.debug('Querying repository with additional filters') return list(set(self._get_repo_filter(query).filter(filters).limit(limit).all()) | set(self._get_repo_filter(query2).filter(filters).limit(limit).all())) return list(set(self._get_repo_filter(query).limit(limit).all()) | set(self._get_repo_filter(query2).limit(limit).all())) def query_domain(self, domain, typenames, domainquerytype='list', count=False): ''' Query by property domain values ''' domain_value = getattr(self.dataset, domain) if domainquerytype == 'range': LOGGER.info('Generating property name range values') query = self.session.query(func.min(domain_value), func.max(domain_value)) else: if count: LOGGER.info('Generating property name frequency counts') query = self.session.query(getattr(self.dataset, domain), func.count(domain_value)).group_by(domain_value) else: query = self.session.query(domain_value).distinct() return self._get_repo_filter(query).all() def query_insert(self, direction='max'): ''' Query to get latest (default) or earliest update to repository ''' column = getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:InsertDate']) if direction == 'min': return self._get_repo_filter(self.session.query(func.min(column))).first()[0] # else default max return self._get_repo_filter(self.session.query(func.max(column))).first()[0] def query_source(self, source): ''' Query by source ''' column = getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:Source']) query = self.session.query(self.dataset).filter(column == source) return self._get_repo_filter(query).all() def query(self, constraint, sortby=None, typenames=None, maxrecords=10, startposition=0): ''' Query records from underlying repository ''' # run the raw query and get total if 'where' in constraint: # GetRecords with constraint LOGGER.debug('constraint detected') query = self.session.query(self.dataset).filter( text(constraint['where'])).params(self._create_values(constraint['values'])) else: # GetRecords sans constraint LOGGER.debug('No constraint detected') query = self.session.query(self.dataset) total = self._get_repo_filter(query).count() if util.ranking_pass: # apply spatial ranking # TODO: Check here for dbtype so to extract wkt from postgis native to wkt LOGGER.debug('spatial ranking detected') LOGGER.debug('Target WKT: %s', getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:BoundingBox'])) LOGGER.debug('Query WKT: %s', util.ranking_query_geometry) query = query.order_by(func.get_spatial_overlay_rank(getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:BoundingBox']), util.ranking_query_geometry).desc()) # trying to make this wsgi safe util.ranking_pass = False util.ranking_query_geometry = '' if sortby is not None: # apply sorting LOGGER.debug('sorting detected') # TODO: Check here for dbtype so to extract wkt from postgis native to wkt sortby_column = getattr(self.dataset, sortby['propertyname']) if sortby['order'] == 'DESC': # descending sort if 'spatial' in sortby and sortby['spatial']: # spatial sort query = query.order_by(func.get_geometry_area(sortby_column).desc()) else: # aspatial sort query = query.order_by(sortby_column.desc()) else: # ascending sort if 'spatial' in sortby and sortby['spatial']: # spatial sort query = query.order_by(func.get_geometry_area(sortby_column)) else: # aspatial sort query = query.order_by(sortby_column) if self.stable_sort: identifier = self.context.md_core_model['mappings']['pycsw:Identifier'] query = query.order_by(identifier) # always apply limit and offset return [str(total), self._get_repo_filter(query).limit( maxrecords).offset(startposition).all()] def insert(self, record, source, insert_date): ''' Insert a record into the repository ''' if isinstance(record.xml, bytes): LOGGER.debug('Decoding bytes to unicode') record.xml = record.xml.decode() try: self.session.begin() self.session.add(record) self.session.commit() except Exception as err: LOGGER.exception(err) self.session.rollback() raise def update(self, record=None, recprops=None, constraint=None): ''' Update a record in the repository based on identifier ''' if record is not None: identifier = getattr(record, self.context.md_core_model['mappings']['pycsw:Identifier']) if isinstance(record.xml, bytes): LOGGER.debug('Decoding bytes to unicode') record.xml = record.xml.decode() if recprops is None and constraint is None: # full update LOGGER.debug('full update') update_dict = dict([(getattr(self.dataset, key), getattr(record, key)) for key in record.__dict__.keys() if key != '_sa_instance_state']) try: self.session.begin() self._get_repo_filter(self.session.query(self.dataset)).filter_by( identifier=identifier).update(update_dict, synchronize_session='fetch') self.session.commit() except Exception as err: self.session.rollback() msg = 'Cannot commit to repository' LOGGER.exception(msg) raise RuntimeError(msg) from err else: # update based on record properties LOGGER.debug('property based update') try: rows = rows2 = 0 self.session.begin() for rpu in recprops: # update queryable column and XML document via XPath if 'xpath' not in rpu['rp']: self.session.rollback() raise RuntimeError('XPath not found for property %s' % rpu['rp']['name']) if 'dbcol' not in rpu['rp']: self.session.rollback() raise RuntimeError('property not found for XPath %s' % rpu['rp']['name']) rows += self._get_repo_filter(self.session.query(self.dataset)).filter( text(constraint['where'])).params(self._create_values(constraint['values'])).update({ getattr(self.dataset, rpu['rp']['dbcol']): rpu['value'], 'xml': func.update_xpath(str(self.context.namespaces), getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:XML']), str(rpu)), }, synchronize_session='fetch') # then update anytext tokens rows2 += self._get_repo_filter(self.session.query(self.dataset)).filter( text(constraint['where'])).params(self._create_values(constraint['values'])).update({ 'anytext': func.get_anytext(getattr( self.dataset, self.context.md_core_model['mappings']['pycsw:XML'])) }, synchronize_session='fetch') self.session.commit() LOGGER.debug('Updated %d records', rows) return rows except Exception as err: self.session.rollback() msg = 'Cannot commit to repository' LOGGER.exception(msg) raise RuntimeError(msg) from err def delete(self, constraint): ''' Delete a record from the repository ''' LOGGER.debug('Deleting record with constraint: %s', constraint) try: self.session.begin() rows = self._get_repo_filter(self.session.query(self.dataset)).filter( text(constraint['where'])).params(self._create_values(constraint['values'])) parentids = [] for row in rows: # get ids parentids.append(getattr(row, self.context.md_core_model['mappings']['pycsw:Identifier'])) rows = rows.delete(synchronize_session='fetch') if rows > 0: LOGGER.debug('Deleting all child records') # delete any child records which had this record as a parent rows += self._get_repo_filter(self.session.query(self.dataset)).filter( getattr(self.dataset, self.context.md_core_model['mappings']['pycsw:ParentIdentifier']).in_(parentids)).delete( synchronize_session='fetch') self.session.commit() LOGGER.debug('Deleted %d records', rows) except Exception as err: self.session.rollback() msg = 'Cannot commit to repository' LOGGER.exception(msg) raise RuntimeError(msg) from err return rows def exists(self): if self.database.startswith('sqlite:'): db_path = self.database.rpartition(":///")[-1] if not os.path.isfile(db_path): try: os.makedirs(os.path.dirname(db_path)) except OSError as exc: if exc.args[0] == 17: # directory already exists pass def _get_repo_filter(self, query): ''' Apply repository wide side filter / mask query ''' if self.filter is not None: return query.filter(text(self.filter)) return query def create_custom_sql_functions(connection): """Register custom functions on the database connection.""" inspect_function = inspect.getfullargspec for function_object in [ query_spatial, update_xpath, util.get_anytext, get_geometry_area, get_spatial_overlay_rank ]: argspec = inspect_function(function_object) connection.create_function( function_object.__name__, len(argspec.args), function_object ) def query_spatial(bbox_data_wkt, bbox_input_wkt, predicate, distance): """Perform spatial query Parameters ---------- bbox_data_wkt: str Well-Known Text representation of the data being queried bbox_input_wkt: str Well-Known Text representation of the input being queried predicate: str Spatial predicate to use in query distance: int or float or str Distance parameter for when using either of ``beyond`` or ``dwithin`` predicates. Returns ------- str Either ``true`` or ``false`` depending on the result of the spatial query Raises ------ RuntimeError If an invalid predicate is used """ try: bbox1 = loads(bbox_data_wkt.split(';')[-1]) bbox2 = loads(bbox_input_wkt) if predicate == 'bbox': result = bbox1.intersects(bbox2) elif predicate == 'beyond': result = bbox1.distance(bbox2) > float(distance) elif predicate == 'contains': result = bbox1.contains(bbox2) elif predicate == 'crosses': result = bbox1.crosses(bbox2) elif predicate == 'disjoint': result = bbox1.disjoint(bbox2) elif predicate == 'dwithin': result = bbox1.distance(bbox2) <= float(distance) elif predicate == 'equals': result = bbox1.equals(bbox2) elif predicate == 'intersects': result = bbox1.intersects(bbox2) elif predicate == 'overlaps': result = bbox1.intersects(bbox2) and not bbox1.touches(bbox2) elif predicate == 'touches': result = bbox1.touches(bbox2) elif predicate == 'within': result = bbox1.within(bbox2) else: raise RuntimeError( 'Invalid spatial query predicate: %s' % predicate) except (AttributeError, ValueError, ShapelyError, TypeError): result = False return "true" if result else "false" def update_xpath(nsmap, xml, recprop): """Update XML document XPath values""" if isinstance(xml, bytes) or isinstance(xml, str): # serialize to lxml xml = etree.fromstring(xml, PARSER) recprop = eval(recprop) nsmap = eval(nsmap) try: nodes = xml.xpath(recprop['rp']['xpath'], namespaces=nsmap) if len(nodes) > 0: # matches for node1 in nodes: if node1.text != recprop['value']: # values differ, update node1.text = recprop['value'] except Exception as err: LOGGER.warning('update_xpath error', exc_info=True) raise RuntimeError('ERROR: %s' % str(err)) from err return etree.tostring(xml) def get_geometry_area(geometry): """Derive area of a given geometry""" try: if geometry is not None: return str(loads(geometry).area) return '0' except Exception: return '0' def get_spatial_overlay_rank(target_geometry, query_geometry): """Derive spatial overlay rank for geospatial search as per Lanfear (2006) http://pubs.usgs.gov/of/2006/1279/2006-1279.pdf""" # TODO: Add those parameters to config file kt = 1.0 kq = 1.0 if target_geometry is not None and query_geometry is not None: try: q_geom = loads(query_geometry) t_geom = loads(target_geometry) Q = q_geom.area T = t_geom.area if any(item == 0.0 for item in [Q, T]): LOGGER.warning('Geometry has no area') return '0' X = t_geom.intersection(q_geom).area if kt == 1.0 and kq == 1.0: LOGGER.debug('Spatial Rank: %s', str((X/Q)*(X/T))) return str((X/Q)*(X/T)) else: LOGGER.debug('Spatial Rank: %s', str(((X/Q)**kq)*((X/T)**kt))) return str(((X/Q)**kq)*((X/T)**kt)) except Exception: LOGGER.warning('Cannot derive spatial overlay ranking', exc_info=True) return '0' return '0' def setup(database, table, create_sfsql_tables=True, postgis_geometry_column='wkb_geometry', extra_columns=[], language='english'): """Setup database tables and indexes""" from sqlalchemy import Column, create_engine, Integer, MetaData, \ Table, Text, Unicode from sqlalchemy.types import Float from sqlalchemy.orm import create_session LOGGER.info('Creating database %s', util.sanitize_db_connect(database)) if database.startswith('sqlite:///'): _, filepath = database.split('sqlite:///') dirname = os.path.dirname(filepath) if not os.path.exists(dirname): LOGGER.debug('SQLite directory %s does not exist' % dirname) try: db_path = database.rpartition(":///")[-1] os.makedirs(os.path.dirname(db_path)) except OSError as exc: if exc.args[0] == 17: # directory already exists LOGGER.debug('Directory already exists') dbase = create_engine(database) schema_name, table_name = table.rpartition(".")[::2] mdata = MetaData(dbase, schema=schema_name or None) create_postgis_geometry = False # If PostGIS 2.x detected, do not create sfsql tables. if dbase.name == 'postgresql': try: dbsession = create_session(dbase) for row in dbsession.execute('select(postgis_lib_version())'): postgis_lib_version = row[0] create_sfsql_tables = False create_postgis_geometry = True LOGGER.info('PostGIS %s detected: Skipping SFSQL tables creation', postgis_lib_version) except Exception: pass if create_sfsql_tables: LOGGER.info('Creating table spatial_ref_sys') srs = Table( 'spatial_ref_sys', mdata, Column('srid', Integer, nullable=False, primary_key=True), Column('auth_name', Text), Column('auth_srid', Integer), Column('srtext', Text) ) srs.create() i = srs.insert() i.execute(srid=4326, auth_name='EPSG', auth_srid=4326, srtext='GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]') LOGGER.info('Creating table geometry_columns') geom = Table( 'geometry_columns', mdata, Column('f_table_catalog', Text, nullable=False), Column('f_table_schema', Text, nullable=False), Column('f_table_name', Text, nullable=False), Column('f_geometry_column', Text, nullable=False), Column('geometry_type', Integer), Column('coord_dimension', Integer), Column('srid', Integer, nullable=False), Column('geometry_format', Text, nullable=False), ) geom.create() i = geom.insert() i.execute(f_table_catalog='public', f_table_schema='public', f_table_name=table_name, f_geometry_column='wkt_geometry', geometry_type=3, coord_dimension=2, srid=4326, geometry_format='WKT') # abstract metadata information model LOGGER.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', Unicode, nullable=False), Column('anytext', Text, nullable=False), Column('metadata', Unicode), Column('metadata_type', Text, default='application/xml', 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, index=True), Column('edition', Text, index=True), Column('keywords', Text, index=True), Column('keywordstype', Text, index=True), Column('themes', 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, index=True), Column('accessconstraints', Text, index=True), Column('otherconstraints', Text, index=True), # 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', Text, index=True), Column('distancevalue', Float, index=True), Column('distanceuom', Text, index=True), Column('wkt_geometry', Text), Column('vert_extent_min', Float, index=True), Column('vert_extent_max', Float, index=True), # 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), # inspire 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), # eo Column('platform', Text, index=True), Column('instrument', Text, index=True), Column('sensortype', Text, index=True), Column('cloudcover', Float, index=True), # bands: JSON list of dicts with properties: name, units, min, max Column('bands', Text, index=True), # STAC: view:off_nadir Column('illuminationelevationangle', Text, index=True), # distribution # links: JSON list of dicts with properties: name, description, protocol, url Column('links', Text, index=False), # contacts: JSON list of dicts with owslib contact properties, name, organization, email, role, etc. Column('contacts', Text, index=True), ) # add extra columns that may have been passed via extra_columns # extra_columns is a list of sqlalchemy.Column objects if extra_columns: LOGGER.info('Extra column definitions detected') for extra_column in extra_columns: LOGGER.info('Adding extra column: %s', extra_column) records.append_column(extra_column) records.create() conn = dbase.connect() if dbase.name == 'postgresql': LOGGER.info('Creating PostgreSQL Free Text Search (FTS) GIN index') tsvector_fts = "alter table %s add column anytext_tsvector tsvector" % table_name conn.execute(tsvector_fts) index_fts = "create index fts_gin_idx on %s using gin(anytext_tsvector)" % table_name conn.execute(index_fts) # This needs to run if records exist "UPDATE records SET anytext_tsvector = to_tsvector('english', anytext)" trigger_fts = "create trigger ftsupdate before insert or update on %s for each row execute procedure tsvector_update_trigger('anytext_tsvector', 'pg_catalog.%s', 'anytext')" % (table_name, language) conn.execute(trigger_fts) if dbase.name == 'postgresql' and create_postgis_geometry: # create native geometry column within db LOGGER.info('Creating native PostGIS geometry column') if postgis_lib_version < '2': create_column_sql = "SELECT AddGeometryColumn('%s', '%s', 4326, 'POLYGON', 2)" % (table_name, postgis_geometry_column) else: create_column_sql = "ALTER TABLE %s ADD COLUMN %s geometry(Geometry,4326);" % (table_name, postgis_geometry_column) create_insert_update_trigger_sql = ''' DROP TRIGGER IF EXISTS %(table)s_update_geometry ON %(table)s; DROP FUNCTION IF EXISTS %(table)s_update_geometry(); CREATE FUNCTION %(table)s_update_geometry() RETURNS trigger AS $%(table)s_update_geometry$ BEGIN IF NEW.wkt_geometry IS NULL THEN RETURN NEW; END IF; NEW.%(geometry)s := ST_GeomFromText(NEW.wkt_geometry,4326); RETURN NEW; END; $%(table)s_update_geometry$ LANGUAGE plpgsql; CREATE TRIGGER %(table)s_update_geometry BEFORE INSERT OR UPDATE ON %(table)s FOR EACH ROW EXECUTE PROCEDURE %(table)s_update_geometry(); ''' % {'table': table_name, 'geometry': postgis_geometry_column} create_spatial_index_sql = 'CREATE INDEX %(geometry)s_idx ON %(table)s USING GIST (%(geometry)s);' \ % {'table': table_name, 'geometry': postgis_geometry_column} conn.execute(create_column_sql) conn.execute(create_insert_update_trigger_sql) conn.execute(create_spatial_index_sql) ================================================ FILE: pycsw/core/schemas/catalog.xml ================================================ ================================================ FILE: pycsw/core/schemas/ogc/OGC-SOFTWARE-NOTICE.txt ================================================ OGC Software Notice This OGC work (including software, documents, or other related items) is being provided by the copyright holders under the following license. By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions: Permission to use, copy, and modify this software and its documentation, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications, that you make: The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed or derivative code: "Copyright © [$date-of-document] Open Geospatial Consortium, Inc. All Rights Reserved. http://www.opengeospatial.org/ogc/legal (Hypertext is preferred, but a textual representation is permitted.) Notice of any changes or modifications to the OGC files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.) THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders. ================================================ FILE: pycsw/core/schemas/ogc/README.txt ================================================ These schemas are shipped with pycsw to support realtime XML validation. The schemas have been downloaded from the official OGC schema repository at http://schemas.opengis.net/ Note that only schemas required for pycsw are included. As well, xs:import and xs:include statements with references to absolute URLs have been modified to refer to relative URLs for performance. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/README.txt ================================================ # 2015-02-13 The unofficial CSW 3.0 schema can be tested from here. http://test.schemas.opengis.net/csw/3.0/ I did make one change to the examples/Capabilities.xml Thanks, kevin #################################################################### --- csw3_0_0-beta-20150123-pv/csw/3.0/examples/Capabilities.xml +++ csw3_0_0-beta-20150123-pv-s1/csw/3.0/examples/Capabilities.xml @@ -15,7 +15,7 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 - http://www.opengis.net/csw/3.0/cswAll.xsd + http://schemas.opengis.net/csw/3.0/cswAll.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd http://www.w3.org/1999/xlink ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/_wrapper.xsd ================================================ ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/cswAll.xsd ================================================ cswAll.xsd 2012-06-04 This XML Schema Document includes and imports, directly or indirectly, all the XML Schemas defined by the Catalogue Service Specification. CSW is an OGC Standard. Copyright (c) 2012 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights see: http://www.opengeospatial.org/legal/. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/cswCommon.xsd ================================================ http://schemas.opengis.net/csw/3.0/cswCommons.xsd This schema defines commen elements used in the CSW schemas. Base type for all request messages except GetCapabilities. The attributes identify the relevant service type and version. This is a general acknowledgement response message for all requests that may be processed in an asynchronous manner. EchoedRequest - Echoes the submitted request message RequestId - identifier for polling purposes (if no response handler is available, or the URL scheme is unsupported) Includes a copy of the request message body. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/cswGetCapabilities.xsd ================================================ http://schemas.opengis.net/csw/3.0/cswGetCapabilities.xsd This schema defines the request and response messages for the CSW 3.0 GetCapabilities operation. Request for a description of service capabilities. See OGC 06-121r9 for more information. OGC service type identifier (CSW). This type extends ows:CapabilitiesBaseType defined in OGC 06-121r9 to include information about supported OGC filter components. A profile may extend this type to describe additional capabilities. If sections parameter not specified, then Filter_Capabilities is mandatory. On full getCapabilities request, then all capabilities should be present. Document this in the specification, use annotation on minOccurs to make this point. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/cswGetDomain.xsd ================================================ http://schemas.opengis.net/csw/3.0/cswGetDomain.xsd This schema defines the request and response messages for the CSW 3.0 GetDomain operation. Returns the set of supported possible values for the specified data component. Returns the set of available values for the specified data component. This is typically a subset of the list of possible values. Returns the actual values for some property. In general this is a subset of the value domain (that is, set of permissible values), although in some cases these may be the same. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/cswGetRecordById.xsd ================================================ http://schemas.opengis.net/csw/3.0/cswGetRecordsById.xsd This schema defines the request messages for the CSW 3.0 GetRecordById operation. Convenience operation to retrieve default record representations by identifier. Id - object identifier (a URI) that provides a reference to a catalogue item (or a result set if the catalogue supports persistent result sets). ElementSetName - one of "brief, "summary", or "full" ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/cswGetRecords.xsd ================================================ http://schemas.opengis.net/csw/3.0/cswGetRecords.xsd This schema defines the request and response messages for the CSW 3.0 GetRecords operation. The principal means of searching the catalogue. The matching catalogue entries may be included with the response. The client may assign a requestId (absolute URI). A distributed search is performed if the DistributedSearch element is present and the catalogue is a member of a federation. Profiles may allow alternative query expressions. requestId becomes mandatory in the case of a distributed search. Must be a unique Id (i.e. a UUID). Various attributes that specify basic retrieval options: outputFormat - the media type of the response message outputSchema - the preferred schema for records in the result set startPosition - requests a slice of the result set, starting at this position maxRecords - the maximum number of records to return. No records are returned if maxRecords=0. Governs the behaviour of a distributed search. hopCount - the maximum number of message hops before the search is terminated. Each catalogue node decrements this value when the request is received, and must not forward the request if hopCount=0. To restrict the number of catalogues of a federation which should be searched upon an optional list of those catalogues can be provided within the federatedCatatalogues parameter. An Id which uniquely identifies the requestor. Id which uniquely identifies a complete client initiated distributed search sequence/session. Defines how long (sec) the distributedSearchId should be valid, meaning how long a server involved in distributed search should minimally store information related to the distributedSearchId. For every catalogue in this list an optional timeout definition (in msec) can be provided. Specifies a query to execute against instances of one or more object types. A set of ElementName elements may be included to specify an adhoc view of the csw30:Record instances in the result set. Otherwise, use ElementSetName to specify a predefined view. The Constraint element contains a query filter expressed in a supported query language. A sorting criterion that specifies a property to sort by may be included. typeNames - a list of object types to query. The exact syntax is defined in an application profile. If querying against the common record properties, only a single type may be specified (Record). A search constraint that adheres to one of the following syntaxes: Filter - OGC filter expression CqlText - OGC CQL predicate Query language version Named subsets of catalogue object properties; these views are mapped to a specific information model and are defined in an application profile. The response message for a GetRecords request. Some or all of the matching records may be included as children of the SearchResults element. The RequestId is only included if the client specified it. This element provides information about the status of the search request. status - status of the search timestamp - the date and time when the result set was modified (ISO 8601 format: YYYY-MM-DDThh:mm:ss[+|-]hh:mm). status of the items included in the resultset: complete (all items found are included), subset (subset of items found are included, but no further items in the requested range startPosition/maxRecords are available), processing (subset of items found are included, but server further processing to get the outstanding items in the requested range startPosition/maxRecords), none (no items are included). Includes representations of result set members if maxRecords > 0. The items must conform to one of the csw30:Record views or a profile-specific representation. resultSetId - id of the result set (a URI). elementSet - The element set that has been returned (e.g., "brief", "summary", "full") recordSchema - schema reference for included records(URI) numberOfRecordsMatched - number of records matched by the query numberOfRecordsReturned - number of records returned to client nextRecord - position of next record in the result set (0 if no records remain). expires - the time instant when the result set expires and is discarded (ISO8601 format) elapsedTime - runtime information of the search within the federated catalogue The URL-prefix of the getCapabilities HTTP-GET operation of the catalogue. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/cswHarvest.xsd ================================================ http://schemas.opengis.net/csw/3.0/cswHarvest.xsd This schema defines the request and response messages for the Harvest operation. Requests that the catalogue attempt to harvest a resource from some network location identified by the source URL. Source - a URL from which the resource is retrieved ResourceType - normally a URI that specifies the type of the resource being harvested ResourceFormat - a media type indicating the format of the resource being harvested. The default is "application/xml". ResponseHandler - a reference to some endpoint to which the response shall be forwarded when the harvest operation has been completed HarvestInterval - an interval expressed using the ISO 8601 syntax; it specifies the interval between harvest attempts (e.g., P6M indicates an interval of six months). The content of the response varies depending on the presence of the ResponseHandler element. If present, then the catalogue should verify the request and respond immediately with an csw30:Acknowledgement element in the response. The catalogue must then attempt to harvest the resource at some later time and send the response message to the location specified by the value of the ResponseHandler element using the indicated protocol (e.g. ftp, mailto, http). If the ResponseHandler element is absent, then the catalogue must attempt to harvest the resource immediately and include a TransactionResponse element in the response. In any case, if the harvest attempt is successful the response shall include summary representations of the newly created catalogue item(s). ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/cswTransaction.xsd ================================================ http://schemas.opengis.net/csw/3.0/cswTransaction.xsd This schema defines the request and response messages for the Transaction operation. Users may insert, update, or delete catalogue entries. If the verboseResponse attribute has the value "true", then one or more csw30:InsertResult elements must be included in the response. Submits one or more records to the catalogue. The representation is defined by the application profile. The handle attribute may be included to specify a local identifier for the action (it must be unique within the context of the transaction). Update statements may replace an entire record or only update part of a record: 1) To replace an existing record, include a new instance of the record; 2) To update selected properties of an existing record, include a set of RecordProperty elements. The scope of the update statement is determined by the Constraint element. The 'handle' is a local identifier for the action. Deletes one or more catalogue items that satisfy some set of conditions. The RecordProperty element is used to specify the new value of a record property in an update statement. The Name element contains the name of a property to be updated. The name may be a path expression. The Value element contains the replacement value for the named property. The response for a transaction request that was successfully completed. If the transaction failed for any reason, a service exception report indicating a TransactionFailure is returned instead. Reports the total number of catalogue items modified by a transaction request (i.e, inserted, updated, deleted). If the client did not specify a requestId, the server may assign one (a URI value). Returns a "brief" view of any newly created catalogue records. The handle attribute may reference a particular statement in the corresponding transaction request. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/cswUnHarvest.xsd ================================================ http://schemas.opengis.net/csw/3.0/cswUnHarvest.xsd This schema defines the request and response messages for the UnHarvest operation. Requests that the CSW unharvest a resource from the catalogue. The resource to unharvest is identified by its source URL (which must match exactly) and its resource type. Source - URL of the resourse to unharvest (must match exactly; including case) ResourceType - normally a URI that specifies the type of the resource being unharvested. ResponseHandler - a reference to some endpoint to which the response shall be forwarded when the unharvest operation has been completed The response to an UnHarvest request is simply a list of csw30:Source elements echoing what has been unharvested. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/rec-dcmes.xsd ================================================ This schema declares XML elements for the 15 Dublin Core elements in the "http://purl.org/dc/elements/1.1/" namespace. This is the default type for all of the DC elements. It defines a complexType SimpleLiteral which permits mixed content but disallows child elements by use of minOcccurs/maxOccurs. However, this complexType does permit the derivation of other types which would permit child elements. The scheme attribute may be used as a qualifier to reference an encoding scheme that describes the value domain for a given property. A name given to the resource. Typically, Title will be a name by which the resource is formally known. An entity primarily responsible for making the content of the resource. Examples of Creator include a person, an organization, or a service. Typically, the name of a Creator should be used to indicate the entity. A topic of the content of the resource. Typically, Subject will be expressed as keywords, key phrases, or classification codes that describe a topic of the resource. Recommended best practice is to select a value from a controlled vocabulary or formal classification scheme. An account of the content of the resource. Examples of Description include, but are not limited to, an abstract, table of contents, reference to a graphical representation of content, or free-text account of the content. An entity responsible for making the resource available. Examples of Publisher include a person, an organization, or a service. Typically, the name of a Publisher should be used to indicate the entity. An entity responsible for making contributions to the content of the resource. Examples of Contributor include a person, an organization, or a service. Typically, the name of a Contributor should be used to indicate the entity. A date of an event in the lifecycle of the resource. Typically, Date will be associated with the creation or availability of the resource. Recommended best practice for encoding the date value is defined in a profile of ISO 8601 and includes (among others) dates of the form YYYY-MM-DD. The nature or genre of the content of the resource. Type includes terms describing general categories, functions, genres, or aggregation levels for content. Recommended best practice is to select a value from a controlled vocabulary (for example, the DCMI Type Vocabulary). To describe the physical or digital manifestation of the resource, use the Format element. The physical or digital manifestation of the resource. Typically, Format will include the media-type or dimensions of the resource. Format may be used to identify the software, hardware, or other equipment needed to display or operate the resource. Examples of dimensions include size and duration. Recommended best practice is to select a value from a controlled vocabulary (for example, the list of Internet Media Types defining computer media formats). An unambiguous reference to the resource within a given context. Recommended best practice is to identify the resource by means of a string or number conforming to a formal identification system. Formal identification systems include but are not limited to the Uniform Resource Identifier (URI) (including the Uniform Resource Locator (URL)), the Digital Object Identifier (DOI), and the International Standard Book Number (ISBN). A Reference to a resource from which the present resource is derived. The present resource may be derived from the Source resource in whole or in part. Recommended best practice is to identify the referenced resource by means of a string or number conforming to a formal identification system. A language of the intellectual content of the resource. Recommended best practice is to use RFC 3066, which, in conjunction with ISO 639, defines two- and three-letter primary language tags with optional subtags. Examples include "en" or "eng" for English, "akk" for Akkadian, and "en-GB" for English used in the United Kingdom. A reference to a related resource. Recommended best practice is to identify the referenced resource by means of a string or number conforming to a formal identification system. The extent or scope of the content of the resource. Typically, Coverage will include spatial location (a place name or geographic coordinates), temporal period (a period label, date, or date range), or jurisdiction (such as a named administrative entity). Recommended best practice is to select a value from a controlled vocabulary (for example, the Thesaurus of Geographic Names [TGN]) and to use, where appropriate, named places or time periods in preference to numeric identifiers such as sets of coordinates or date ranges. Information about rights held in and over the resource. Typically, Rights will contain a rights management statement for the resource, or reference a service providing such information. Rights information often encompasses Intellectual Property Rights (IPR), Copyright, and various Property Rights. If the Rights element is absent, no assumptions may be made about any rights held in or over the resource. This group is included as a convenience for schema authors who need to refer to all the elements in the "http://purl.org/dc/elements/1.1/" namespace. This type definition is included as a convenience for schema authors who need a container element for all of the DC elements. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/rec-dcterms.xsd ================================================ This schema declares additional DCMI elements and element refinements in the "http://purl.org/dc/terms/" namespace. This group is included as a convenience for schema authors who need to refer to the complete set of DCMI metadata terms. ================================================ FILE: pycsw/core/schemas/ogc/cat/csw/3.0/record.xsd ================================================ http://schemas.opengis.net/csw/3.0/record.xsd This schema defines the basic record types that must be supported by all CSW implementations. These correspond to full, summary, and brief views based on DCMI metadata terms. This type encapsulates all of the standard DCMI metadata terms, including the Dublin Core refinements; these terms may be mapped to the profile-specific information model. A type for specifying the temporal extent of the data item that a metadata record describes. Omitting begin/end implies infinity in that direction. The attribute "inclusive" can be used indicate whether the boundary value in included in extent or not. This type defines a brief representation of the common record format. It extends AbstractRecordType to include only the dc:identifier and dc:type properties. This type defines a summary representation of the common record format. It extends AbstractRecordType to include the core properties. This type extends DCMIRecordType to add ows:BoundingBox; it may be used to specify a spatial envelope for the catalogued resource. ================================================ FILE: pycsw/core/schemas/ogc/csw/2.0.2/CSW-discovery.xsd ================================================ http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd This schema defines the request and response messages for the CSW-Discovery operations specified in clause 10 of OGC-07-066. CSW is an OGC Standard. Copyright (c) 2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Base type for all request messages except GetCapabilities. The attributes identify the relevant service type and version. Request for a description of service capabilities. See OGC 05-008 for more information. This type extends ows:CapabilitiesBaseType defined in OGC-05-008 to include information about supported OGC filter components. A profile may extend this type to describe additional capabilities. This request allows a user to discover elements of the information model supported by the catalogue. If no TypeName elements are included, then all of the schemas for the information model must be returned. schemaLanguage - preferred schema language (W3C XML Schema by default) outputFormat - preferred output format (application/xml by default) The response contains a list of matching schema components in the requested schema language. A schema component includes a schema fragment (type definition) or an entire schema from some target namespace; the schema language is identified by URI. If the component is a schema fragment its parent MUST be referenced (parentSchema). The principal means of searching the catalogue. The matching catalogue entries may be included with the response. The client may assign a requestId (absolute URI). A distributed search is performed if the DistributedSearch element is present and the catalogue is a member of a federation. Profiles may allow alternative query expressions. Various attributes that specify basic retrieval options: outputFormat - the media type of the response message outputSchema - the preferred schema for records in the result set startPosition - requests a slice of the result set, starting at this position maxRecords - the maximum number of records to return. No records are returned if maxRecords=0. Include results in the response. Provide a result set summary, but no results. Validate the request and return an Acknowledgement message if it is valid. Continue processing the request asynchronously. Governs the behaviour of a distributed search. hopCount - the maximum number of message hops before the search is terminated. Each catalogue node decrements this value when the request is received, and must not forward the request if hopCount=0. Specifies a query to execute against instances of one or more object types. A set of ElementName elements may be included to specify an adhoc view of the csw:Record instances in the result set. Otherwise, use ElementSetName to specify a predefined view. The Constraint element contains a query filter expressed in a supported query language. A sorting criterion that specifies a property to sort by may be included. typeNames - a list of object types to query. The exact syntax is defined in an application profile. If querying against the common record properties, only a single type may be specified (Record). A search constraint that adheres to one of the following syntaxes: Filter - OGC filter expression CqlText - OGC CQL predicate Query language version Named subsets of catalogue object properties; these views are mapped to a specific information model and are defined in an application profile. The response message for a GetRecords request. Some or all of the matching records may be included as children of the SearchResults element. The RequestId is only included if the client specified it. This element provides information about the status of the search request. status - status of the search timestamp - the date and time when the result set was modified (ISO 8601 format: YYYY-MM-DDThh:mm:ss[+|-]hh:mm). Includes representations of result set members if maxRecords > 0. The items must conform to one of the csw:Record views or a profile-specific representation. resultSetId - id of the result set (a URI). elementSet - The element set that has been returned (i.e., "brief", "summary", "full") recordSchema - schema reference for included records(URI) numberOfRecordsMatched - number of records matched by the query numberOfRecordsReturned - number of records returned to client nextRecord - position of next record in the result set (0 if no records remain). expires - the time instant when the result set expires and is discarded (ISO 8601 format) Convenience operation to retrieve default record representations by identifier. Id - object identifier (a URI) that provides a reference to a catalogue item (or a result set if the catalogue supports persistent result sets). ElementSetName - one of "brief, "summary", or "full" Returns a representation of the matching entry. If there is no matching record, the response message must be empty. Requests the actual values of some specified request parameter or other data element. Returns the actual values for some property. In general this is a subset of the value domain (that is, set of permissible values), although in some cases these may be the same. This is a general acknowledgement response message for all requests that may be processed in an asynchronous manner. EchoedRequest - Echoes the submitted request message RequestId - identifier for polling purposes (if no response handler is available, or the URL scheme is unsupported) Includes a copy of the request message body. ================================================ FILE: pycsw/core/schemas/ogc/csw/2.0.2/CSW-publication.xsd ================================================ http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd This schema defines the request and response messages for the CSW-Publication operations specified in clause 10 of OGC-07-066. CSW is an OGC Standard. Copyright (c) 2004, 2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Users may insert, update, or delete catalogue entries. If the verboseResponse attribute has the value "true", then one or more csw:InsertResult elements must be included in the response. Submits one or more records to the catalogue. The representation is defined by the application profile. The handle attribute may be included to specify a local identifier for the action (it must be unique within the context of the transaction). Update statements may replace an entire record or only update part of a record: 1) To replace an existing record, include a new instance of the record; 2) To update selected properties of an existing record, include a set of RecordProperty elements. The scope of the update statement is determined by the Constraint element. The 'handle' is a local identifier for the action. Deletes one or more catalogue items that satisfy some set of conditions. The RecordProperty element is used to specify the new value of a record property in an update statement. The Name element contains the name of a property to be updated. The name may be a path expression. The Value element contains the replacement value for the named property. The response for a transaction request that was successfully completed. If the transaction failed for any reason, a service exception report indicating a TransactionFailure is returned instead. Reports the total number of catalogue items modified by a transaction request (i.e, inserted, updated, deleted). If the client did not specify a requestId, the server may assign one (a URI value). Returns a "brief" view of any newly created catalogue records. The handle attribute may reference a particular statement in the corresponding transaction request. Requests that the catalogue attempt to harvest a resource from some network location identified by the source URL. Source - a URL from which the resource is retrieved ResourceType - normally a URI that specifies the type of the resource (DCMES v1.1) being harvested if it is known. ResourceFormat - a media type indicating the format of the resource being harvested. The default is "application/xml". ResponseHandler - a reference to some endpoint to which the response shall be forwarded when the harvest operation has been completed HarvestInterval - an interval expressed using the ISO 8601 syntax; it specifies the interval between harvest attempts (e.g., P6M indicates an interval of six months). The content of the response varies depending on the presence of the ResponseHandler element. If present, then the catalogue should verify the request and respond immediately with an csw:Acknowledgement element in the response. The catalogue must then attempt to harvest the resource at some later time and send the response message to the location specified by the value of the ResponseHandler element using the indicated protocol (e.g. ftp, mailto, http). If the ResponseHandler element is absent, then the catalogue must attempt to harvest the resource immediately and include a TransactionResponse element in the response. In any case, if the harvest attempt is successful the response shall include summary representations of the newly created catalogue item(s). ================================================ FILE: pycsw/core/schemas/ogc/csw/2.0.2/rec-dcmes.xsd ================================================ This schema declares XML elements for the 15 Dublin Core elements in the "http://purl.org/dc/elements/1.1/" namespace. This is the default type for all of the DC elements. It defines a complexType SimpleLiteral which permits mixed content but disallows child elements by use of minOcccurs/maxOccurs. However, this complexType does permit the derivation of other types which would permit child elements. The scheme attribute may be used as a qualifier to reference an encoding scheme that describes the value domain for a given property. A name given to the resource. Typically, Title will be a name by which the resource is formally known. An entity primarily responsible for making the content of the resource. Examples of Creator include a person, an organization, or a service. Typically, the name of a Creator should be used to indicate the entity. A topic of the content of the resource. Typically, Subject will be expressed as keywords, key phrases, or classification codes that describe a topic of the resource. Recommended best practice is to select a value from a controlled vocabulary or formal classification scheme. An account of the content of the resource. Examples of Description include, but are not limited to, an abstract, table of contents, reference to a graphical representation of content, or free-text account of the content. An entity responsible for making the resource available. Examples of Publisher include a person, an organization, or a service. Typically, the name of a Publisher should be used to indicate the entity. An entity responsible for making contributions to the content of the resource. Examples of Contributor include a person, an organization, or a service. Typically, the name of a Contributor should be used to indicate the entity. A date of an event in the lifecycle of the resource. Typically, Date will be associated with the creation or availability of the resource. Recommended best practice for encoding the date value is defined in a profile of ISO 8601 and includes (among others) dates of the form YYYY-MM-DD. The nature or genre of the content of the resource. Type includes terms describing general categories, functions, genres, or aggregation levels for content. Recommended best practice is to select a value from a controlled vocabulary (for example, the DCMI Type Vocabulary). To describe the physical or digital manifestation of the resource, use the Format element. The physical or digital manifestation of the resource. Typically, Format will include the media-type or dimensions of the resource. Format may be used to identify the software, hardware, or other equipment needed to display or operate the resource. Examples of dimensions include size and duration. Recommended best practice is to select a value from a controlled vocabulary (for example, the list of Internet Media Types defining computer media formats). An unambiguous reference to the resource within a given context. Recommended best practice is to identify the resource by means of a string or number conforming to a formal identification system. Formal identification systems include but are not limited to the Uniform Resource Identifier (URI) (including the Uniform Resource Locator (URL)), the Digital Object Identifier (DOI), and the International Standard Book Number (ISBN). A Reference to a resource from which the present resource is derived. The present resource may be derived from the Source resource in whole or in part. Recommended best practice is to identify the referenced resource by means of a string or number conforming to a formal identification system. A language of the intellectual content of the resource. Recommended best practice is to use RFC 3066, which, in conjunction with ISO 639, defines two- and three-letter primary language tags with optional subtags. Examples include "en" or "eng" for English, "akk" for Akkadian, and "en-GB" for English used in the United Kingdom. A reference to a related resource. Recommended best practice is to identify the referenced resource by means of a string or number conforming to a formal identification system. The extent or scope of the content of the resource. Typically, Coverage will include spatial location (a place name or geographic coordinates), temporal period (a period label, date, or date range), or jurisdiction (such as a named administrative entity). Recommended best practice is to select a value from a controlled vocabulary (for example, the Thesaurus of Geographic Names [TGN]) and to use, where appropriate, named places or time periods in preference to numeric identifiers such as sets of coordinates or date ranges. Information about rights held in and over the resource. Typically, Rights will contain a rights management statement for the resource, or reference a service providing such information. Rights information often encompasses Intellectual Property Rights (IPR), Copyright, and various Property Rights. If the Rights element is absent, no assumptions may be made about any rights held in or over the resource. This group is included as a convenience for schema authors who need to refer to all the elements in the "http://purl.org/dc/elements/1.1/" namespace. This type definition is included as a convenience for schema authors who need a container element for all of the DC elements. ================================================ FILE: pycsw/core/schemas/ogc/csw/2.0.2/rec-dcterms.xsd ================================================ This schema declares additional DCMI elements and element refinements in the "http://purl.org/dc/terms/" namespace. This group is included as a convenience for schema authors who need to refer to the complete set of DCMI metadata terms. ================================================ FILE: pycsw/core/schemas/ogc/csw/2.0.2/record.xsd ================================================ http://schemas.opengis.net/csw/2.0.2/record.xsd This schema defines the basic record types that must be supported by all CSW implementations. These correspond to full, summary, and brief views based on DCMI metadata terms. CSW is an OGC Standard. Copyright (c) 2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This type encapsulates all of the standard DCMI metadata terms, including the Dublin Core refinements; these terms may be mapped to the profile-specific information model. This type defines a brief representation of the common record format. It extends AbstractRecordType to include only the dc:identifier and dc:type properties. This type defines a summary representation of the common record format. It extends AbstractRecordType to include the core properties. This type extends DCMIRecordType to add ows:BoundingBox; it may be used to specify a spatial envelope for the catalogued resource. ================================================ FILE: pycsw/core/schemas/ogc/filter/1.1.0/expr.xsd ================================================ ================================================ FILE: pycsw/core/schemas/ogc/filter/1.1.0/filter.xsd ================================================ This XML Schema defines OGC query filter capabilities documents. filter is an OGC Standard. Copyright (c) 2002,2003,2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit: http://www.opengeospatial.org/legal/ . Updated: 2011-02-04 ================================================ FILE: pycsw/core/schemas/ogc/filter/1.1.0/filterCapabilities.xsd ================================================ This XML Schema defines OGC query filter capabilities documents. filter is an OGC Standard. Copyright (c) 2002,2003,2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Updated: 2010-01-22 ================================================ FILE: pycsw/core/schemas/ogc/filter/1.1.0/sort.xsd ================================================ ================================================ FILE: pycsw/core/schemas/ogc/filter/2.0/_wrapper.xsd ================================================ ================================================ FILE: pycsw/core/schemas/ogc/filter/2.0/expr.xsd ================================================ Filter Encoding is an OGC Standard. Copyright (c) 2010, 2014 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/filter/2.0/filter.xsd ================================================ Filter Encoding is an OGC Standard. Copyright (c) 2010, 2014 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/filter/2.0/filterAll.xsd ================================================ This XML Schema document includes and imports, directly or indirectly, all the XML Schema defined by the Filter Encoding Standard. Filter Encoding is an OGC Standard. Copyright (c) 2010, 2014 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/filter/2.0/filterCapabilities.xsd ================================================ This XML Schema defines OGC query filter capabilities documents. Filter Encoding is an OGC Standard. Copyright (c) 2010, 2014 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/filter/2.0/query.xsd ================================================ Filter Encoding is an OGC Standard. Copyright (c) 2010, 2014 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/filter/2.0/sort.xsd ================================================ Filter Encoding is an OGC Standard. Copyright (c) 2010, 2014 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/basicTypes.xsd ================================================ basicTypes.xsd Generic simpleContent components for use in GML GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Some common reasons for a null value: innapplicable - the object does not have a value missing - The correct value is not readily available to the sender of this data. Furthermore, a correct value may not exist. template - the value will be available later unknown - The correct value is not known to, and not computable by, the sender of this data. However, a correct value probably exists. withheld - the value is not divulged other:reason - as indicated by "reason" string Specific communities may agree to assign more strict semantics when these terms are used in a particular context. Utility type for null elements. The value may be selected from one of the enumerated tokens, or may be a URI in which case this should identify a resource which describes the reason for the null. Utility type used in various places - e.g. to indicate the direction of topological objects; "+" for forwards, or "-" for backwards. Union of the XML Schema boolean type and the GML Nulltype. An element which uses this type may have content which is either a boolean {0,1,true,false} or a value from Nulltype XML List based on the union type defined above. An element declared with this type contains a space-separated list of boolean values {0,1,true,false} with null values interspersed as needed XML List based on XML Schema boolean type. An element of this type contains a space-separated list of boolean values {0,1,true,false} Union of the XML Schema string type and the GML Nulltype. An element which uses this type may have content which is either a string or a value from Nulltype. Note that a "string" may contain whitespace. Union of the XML Schema Name type and the GML Nulltype. An element which uses this type may have content which is either a Name or a value from Nulltype. Note that a "Name" may not contain whitespace. XML List based on the union type defined above. An element declared with this type contains a space-separated list of Name values with null values interspersed as needed XML List based on XML Schema Name type. An element of this type contains a space-separated list of Name values Union of the XML Schema double type and the GML Nulltype. An element which uses this type may have content which is either a double or a value from Nulltype XML List based on the union type defined above. An element declared with this type contains a space-separated list of double values with null values interspersed as needed XML List based on XML Schema double type. An element of this type contains a space-separated list of double values Union of the XML Schema integer type and the GML Nulltype. An element which uses this type may have content which is either an integer or a value from Nulltype XML List based on the union type defined above. An element declared with this type contains a space-separated list of integer values with null values interspersed as needed XML List based on XML Schema integer type. An element of this type contains a space-separated list of integer values Name or code with an (optional) authority. Text token. If the codeSpace attribute is present, then its value should identify a dictionary, thesaurus or authority for the term, such as the organisation who assigned the value, or the dictionary from which it is taken. A text string with an optional codeSpace attribute. List of values on a uniform nominal scale. List of text tokens. In a list context a token should not include any spaces, so xsd:Name is used instead of xsd:string. If a codeSpace attribute is present, then its value is a reference to a Reference System for the value, a dictionary or code list. List of values on a uniform nominal scale. List of text tokens. In a list context a token should not include any spaces, so xsd:Name is used instead of xsd:string. A member of the list may be a typed null. If a codeSpace attribute is present, then its value is a reference to a Reference System for the value, a dictionary or code list. Number with a scale. The value of uom (Units Of Measure) attribute is a reference to a Reference System for the amount, either a ratio or position scale. List of numbers with a uniform scale. The value of uom (Units Of Measure) attribute is a reference to a Reference System for the amount, either a ratio or position scale. List of numbers with a uniform scale. A member of the list may be a typed null. The value of uom (Units Of Measure) attribute is a reference to a Reference System for the amount, either a ratio or position scale. Tables or arrays of tuples. May be used for text-encoding of values from a table. Actually just a string, but allows the user to indicate which characters are used as separators. The value of the 'cs' attribute is the separator for coordinate values, and the value of the 'ts' attribute gives the tuple separator (a single space by default); the default values may be changed to reflect local usage. Defaults to CSV within a tuple, space between tuples. However, any string content will be schema-valid. A set of values, representing a list of token with the lexical value space of NCName. The tokens are seperated by whitespace. A set of values, representing a list of token with the lexical value space of QName. The tokens are seperated by whitespace. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateOperations.xsd ================================================ How to encode coordinate operation definitions. Builds on referenceSystems.xsd to encode the data needed to define coordinate operations, including Transformations, Conversions, and other specific subtypes of operations. This schema encodes the Coordinate Operation (CC_) package of the extended UML Model for OGC Abstract Specification Topic 2: Spatial Referencing by Coordinates. That UML model is adapted from ISO 19111 - Spatial referencing by coordinates, as described in Annex C of Topic 2. Caution: The CRS package in GML 3.1 and GML 3.1.1 is preliminary, and is expected to undergo some modifications that are not backward compatible during the development of GML 3.2 (ISO 19136). The GML 3.2 package will implement the model described in the revised version of ISO 19111. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Basic encoding for coordinate operation objects, simplifying and restricting the DefinitionType as needed. The name by which this coordinate operation is identified. A mathematical operation on coordinates that transforms or converts coordinates to another coordinate reference system. Many but not all coordinate operations (from CRS A to CRS B) also uniquely define the inverse operation (from CRS B to CRS A). In some cases, the operation method algorithm for the inverse operation is the same as for the forward algorithm, but the signs of some operation parameter values must be reversed. In other cases, different algorithms are required for the forward and inverse operations, but the same operation parameter values are used. If (some) entirely different parameter values are needed, a different coordinate operation shall be defined. Set of alternative identifications of this coordinate operation. The first coordinateOperationID, if any, is normally the primary identification code, and any others are aliases. Comments on or information about this coordinate operation, including source information. Unordered set of estimates of the impact of this coordinate operation on point position accuracy. Gives position error estimates for target coordinates of this coordinate operation, assuming no errors in source coordinates. An identification of a coordinate operation. Version of the coordinate transformation (i.e., instantiation due to the stochastic nature of the parameters). Mandatory when describing a transformation, and should not be supplied for a conversion. Association to the source CRS (coordinate reference system) of this coordinate operation. Association to the target CRS (coordinate reference system) of this coordinate operation. For constraints on multiplicity of "sourceCRS" and "targetCRS", see UML model of Coordinate Operation package in OGC Abstract Specification topic 2. Association to a coordinate operation, either referencing or containing the definition of that coordinate operation. An ordered sequence of two or more single coordinate operations. The sequence of operations is constrained by the requirement that the source coordinate reference system of step (n+1) must be the same as the target coordinate reference system of step (n). The source coordinate reference system of the first step and the target coordinate reference system of the last step are the source and target coordinate reference system associated with the concatenated operation. Instead of a forward operation, an inverse operation may be used for one or more of the operation steps mentioned above, if the inverse operation is uniquely defined by the forward operation. Ordered sequence of associations to the two or more single operations used by this concatenated operation. Association to a single operation. Association to a concatenated operation, either referencing or containing the definition of that concatenated operation. A single (not concatenated) coordinate operation. Association to a single operation, either referencing or containing the definition of that single operation. A pass-through operation specifies that a subset of a coordinate tuple is subject to a specific coordinate operation. Ordered sequence of positive integers defining the positions in a coordinate tuple of the coordinates affected by this pass-through operation. A positive integer defining a position in a coordinate tuple. Association to the operation applied to the specified ordinates. Association to a pass through operation, either referencing or containing the definition of that pass through operation. A parameterized mathematical operation on coordinates that transforms or converts coordinates to another coordinate reference system. This coordinate operation uses an operation method, usually with associated parameter values. However, operation methods and parameter values are directly associated with concrete subtypes, not with this abstract type. This abstract complexType shall not be directly used, extended, or restricted in a compliant Application Schema. Association to an abstract operation, either referencing or containing the definition of that operation. An abstract operation on coordinates that does not include any change of datum. The best-known example of a coordinate conversion is a map projection. The parameters describing coordinate conversions are defined rather than empirically derived. Note that some conversions have no parameters. This abstract complexType is expected to be extended for well-known operation methods with many Conversion instances, in Application Schemas that define operation-method-specialized element names and contents. This conversion uses an operation method, usually with associated parameter values. However, operation methods and parameter values are directly associated with concrete subtypes, not with this abstract type. All concrete types derived from this type shall extend this type to include a "usesMethod" element that references the "OperationMethod" element. Similarly, all concrete types derived from this type shall extend this type to include zero or more elements each named "uses...Value" that each use the type of an element substitutable for the "_generalParameterValue" element. Association to a general conversion, either referencing or containing the definition of that conversion. A concrete operation on coordinates that does not include any change of Datum. The best-known example of a coordinate conversion is a map projection. The parameters describing coordinate conversions are defined rather than empirically derived. Note that some conversions have no parameters. This concrete complexType can be used with all operation methods, without using an Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one Conversion instance. Unordered list of composition associations to the set of parameter values used by this conversion operation. Association to the operation method used by this coordinate operation. Composition association to a parameter value used by this coordinate operation. Association to a concrete general-purpose conversion, either referencing or containing the definition of that conversion. An abstract operation on coordinates that usually includes a change of Datum. The parameters of a coordinate transformation are empirically derived from data containing the coordinates of a series of points in both coordinate reference systems. This computational process is usually "over-determined", allowing derivation of error (or accuracy) estimates for the transformation. Also, the stochastic nature of the parameters may result in multiple (different) versions of the same coordinate transformation. This abstract complexType is expected to be extended for well-known operation methods with many Transformation instances, in Application Schemas that define operation-method-specialized value element names and contents. This transformation uses an operation method with associated parameter values. However, operation methods and parameter values are directly associated with concrete subtypes, not with this abstract type. All concrete types derived from this type shall extend this type to include a "usesMethod" element that references one "OperationMethod" element. Similarly, all concrete types derived from this type shall extend this type to include one or more elements each named "uses...Value" that each use the type of an element substitutable for the "_generalParameterValue" element. Association to a general transformation, either referencing or containing the definition of that transformation. A concrete operation on coordinates that usually includes a change of datum. The parameters of a coordinate transformation are empirically derived from data containing the coordinates of a series of points in both coordinate reference systems. This computational process is usually "over-determined", allowing derivation of error (or accuracy) estimates for the transformation. Also, the stochastic nature of the parameters may result in multiple (different) versions of the same coordinate transformation. This concrete complexType can be used for all operation methods, without using an Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one Transformation instance. Unordered set of composition associations to the set of parameter values used by this transformation operation. Association to a transformation, either referencing or containing the definition of that transformation. Abstract parameter value or group of parameter values. This abstract complexType is expected to be extended and restricted for well-known operation methods with many instances, in Application Schemas that define operation-method-specialized element names and contents. Specific parameter value elements are directly contained in concrete subtypes, not in this abstract type. All concrete types derived from this type shall extend this type to include one "...Value" element with an appropriate type, which should be one of the element types allowed in the ParameterValueType. In addition, all derived concrete types shall extend this type to include a "valueOfParameter" element that references one element substitutable for the "OperationParameter" element. A parameter value, ordered sequence of values, or reference to a file of parameter values. This concrete complexType can be used for operation methods without using an Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one instance. This complexType can be used, extended, or restricted for well-known operation methods, especially for methods with many instances. Numeric value of an operation parameter, with its associated unit of measure. Value of an angle operation parameter, in either degree-minute-second format or single value format. String value of an operation parameter. A string value does not have an associated unit of measure. Positive integer value of an operation parameter, usually used for a count. An integer value does not have an associated unit of measure. Boolean value of an operation parameter. A Boolean value does not have an associated unit of measure. Ordered sequence of two or more numeric values of an operation parameter list, where each value has the same associated unit of measure. An element of this type contains a space-separated sequence of double values. Ordered sequence of two or more integer values of an operation parameter list, usually used for counts. These integer values do not have an associated unit of measure. An element of this type contains a space-separated sequence of integer values. Reference to a file or a part of a file containing one or more parameter values, each numeric value with its associated unit of measure. When referencing a part of a file, that file must contain multiple identified parts, such as an XML encoded document. Furthermore, the referenced file or part of a file can reference another part of the same or different files, as allowed in XML documents. Association to the operation parameter that this is a value of. A group of related parameter values. The same group can be repeated more than once in a Conversion, Transformation, or higher level parameterValueGroup, if those instances contain different values of one or more parameterValues which suitably distinquish among those groups. This concrete complexType can be used for operation methods without using an Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one instance. This complexType can be used, extended, or restricted for well-known operation methods, especially for methods with many instances. Unordered set of composition associations to the parameter values and groups of values included in this group. A composition association to a parameter value or group of values included in this group. Association to the operation parameter group for which this element provides parameter values. Basic encoding for operation method objects, simplifying and restricting the DefinitionType as needed. The name by which this operation method is identified. Definition of an algorithm used to perform a coordinate operation. Most operation methods use a number of operation parameters, although some coordinate conversions use none. Each coordinate operation using the method assigns values to these parameters. Set of alternative identifications of this operation method. The first methodID, if any, is normally the primary identification code, and any others are aliases. Comments on or information about this operation method, including source information. Unordered list of associations to the set of operation parameters and parameter groups used by this operation method. An identification of an operation method. Formula(s) used by this operation method. The value may be a reference to a publication. Note that the operation method may not be analytic, in which case this element references or contains the procedure, not an analytic formula. Number of dimensions in the source CRS of this operation method. Number of dimensions in the target CRS of this operation method. Association to an operation parameter or parameter group used by this operation method. Association to a concrete general-purpose operation method, either referencing or containing the definition of that method. Abstract definition of a parameter or group of parameters used by an operation method. The minimum number of times that values for this parameter group or parameter are required. If this attribute is omitted, the minimum number is one. Association to an operation parameter or group, either referencing or containing the definition of that parameter or group. Basic encoding for operation parameter objects, simplifying and restricting the DefinitionType as needed. The name by which this operation parameter is identified. The definition of a parameter used by an operation method. Most parameter values are numeric, but other types of parameter values are possible. This complexType is expected to be used or extended for all operation methods, without defining operation-method-specialized element names. Set of alternative identifications of this operation parameter. The first parameterID, if any, is normally the primary identification code, and any others are aliases. Comments on or information about this operation parameter, including source information. An identification of an operation parameter. Association to an operation parameter, either referencing or containing the definition of that parameter. Basic encoding for operation parameter group objects, simplifying and restricting the DefinitionType as needed. The name by which this operation parameter group is identified. The definition of a group of parameters used by an operation method. This complexType is expected to be used or extended for all applicable operation methods, without defining operation-method-specialized element names. Set of alternative identifications of this operation parameter group. The first groupID, if any, is normally the primary identification code, and any others are aliases. Comments on or information about this operation parameter group, including source information. Unordered list of associations to the set of operation parameters that are members of this group. An identification of an operation parameter group. The maximum number of times that values for this parameter group can be included. If this attribute is omitted, the maximum number is one. Association to an operation parameter that is a member of a group. Association to an operation parameter, either referencing or containing the definition of that parameter. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateReferenceSystems.xsd ================================================ How to encode coordinate reference system definitions. Builds on referenceSystems.xsd to encode the data needed to define coordinate reference systems, including the specific subtypes of coordinate reference systems. This schema encodes the Coordinate Reference System (SC_) package of the extended UML Model for OGC Abstract Specification Topic 2: Spatial Referencing by Coordinates, with the exception of the abstract "SC_CRS" class. The "SC_CRS" class is encoded in referenceSystems.xsd, to eliminate the (circular) references from coordinateOperations.xsd to coordinateReferenceSystems.xsd. That UML model is adapted from ISO 19111 - Spatial referencing by coordinates, as described in Annex C of Topic 2. Caution: The CRS package in GML 3.1 and GML 3.1.1 is preliminary, and is expected to undergo some modifications that are not backward compatible during the development of GML 3.2 (ISO 19136). The GML 3.2 package will implement the model described in the revised version of ISO 19111. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . A coordinate reference system consists of an ordered sequence of coordinate system axes that are related to the earth through a datum. A coordinate reference system is defined by one datum and by one coordinate system. Most coordinate reference system do not move relative to the earth, except for engineering coordinate reference systems defined on moving platforms such as cars, ships, aircraft, and spacecraft. For further information, see OGC Abstract Specification Topic 2. Coordinate reference systems are commonly divided into sub-types. The common classification criterion for sub-typing of coordinate reference systems is the way in which they deal with earth curvature. This has a direct effect on the portion of the earth's surface that can be covered by that type of CRS with an acceptable degree of error. The exception to the rule is the subtype "Temporal" which has been added by analogy. Association to a coordinate reference system, either referencing or containing the definition of that reference system. A coordinate reference system describing the position of points through two or more independent coordinate reference systems. Ordered sequence of associations to all the component coordinate reference systems included in this compound coordinate reference system. An association to a component coordinate reference system included in this compound coordinate reference system. Association to a compound coordinate reference system, either referencing or containing the definition of that reference system. A coordinate reference system based on an ellipsoidal approximation of the geoid; this provides an accurate representation of the geometry of geographic features for a large portion of the earth's surface. Association to the ellipsoidal coordinate system used by this CRS. Association to the geodetic datum used by this CRS. Association to a geographic coordinate reference system, either referencing or containing the definition of that reference system. A 1D coordinate reference system used for recording heights or depths. Vertical CRSs make use of the direction of gravity to define the concept of height or depth, but the relationship with gravity may not be straightforward. By implication, ellipsoidal heights (h) cannot be captured in a vertical coordinate reference system. Ellipsoidal heights cannot exist independently, but only as an inseparable part of a 3D coordinate tuple defined in a geographic 3D coordinate reference system. Association to the vertical coordinate system used by this CRS. Association to the vertical datum used by this CRS. Association to a vertical coordinate reference system, either referencing or containing the definition of that reference system. A 3D coordinate reference system with the origin at the approximate centre of mass of the earth. A geocentric CRS deals with the earth's curvature by taking a 3D spatial view, which obviates the need to model the earth's curvature. Association to the Cartesian coordinate system used by this CRS. Association to the spherical coordinate system used by this CRS. Association to a geocentric coordinate reference system, either referencing or containing the definition of that reference system. A coordinate reference system that is defined by its coordinate conversion from another coordinate reference system (not by a datum). This abstract complexType shall not be used, extended, or restricted, in an Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. Association to the coordinate reference system used by this derived CRS. Association to the coordinate conversion used to define this derived CRS. A 2D coordinate reference system used to approximate the shape of the earth on a planar surface, but in such a way that the distortion that is inherent to the approximation is carefully controlled and known. Distortion correction is commonly applied to calculated bearings and distances to produce values that are a close match to actual field values. Association to a projected coordinate reference system, either referencing or containing the definition of that reference system. A coordinate reference system that is defined by its coordinate conversion from another coordinate reference system but is not a projected coordinate reference system. This category includes coordinate reference systems derived from a projected coordinate reference system. Type of a derived coordinate reference system. Reference to a source of information specifying the values and meanings of all the allowed string values for this DerivedCRSTypeType. Association to the coordinate system used by this CRS. Association to a non-projected derived coordinate reference system, either referencing or containing the definition of that reference system. A contextually local coordinate reference system; which can be divided into two broad categories: - earth-fixed systems applied to engineering activities on or near the surface of the earth; - CRSs on moving platforms such as road vehicles, vessels, aircraft, or spacecraft. For further information, see OGC Abstract Specification Topic 2. Association to the engineering datum used by this CRS. Association to an engineering coordinate reference system, either referencing or containing the definition of that reference system. An engineering coordinate reference system applied to locations in images. Image coordinate reference systems are treated as a separate sub-type because a separate user community exists for images with its own terms of reference. Association to the oblique Cartesian coordinate system used by this CRS. Association to the image datum used by this CRS. Association to an image coordinate reference system, either referencing or containing the definition of that reference system. A 1D coordinate reference system used for the recording of time. Association to the temporal coordinate system used by this CRS. Association to the temporal datum used by this CRS. Association to a temporal coordinate reference system, either referencing or containing the definition of that reference system. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateSystems.xsd ================================================ How to encode coordinate system definitions. Builds on referenceSystems.xsd to encode the data needed to define coordinate systems, including the specific subtypes of coordinate systems. This schema encodes the Coordinate System (CS_) package of the extended UML Model for OGC Abstract Specification Topic 2: Spatial Referencing by Coordinates. That UML model is adapted from ISO 19111 - Spatial referencing by coordinates, as described in Annex C of Topic 2. Caution: The CRS package in GML 3.1 and GML 3.1.1 is preliminary, and is expected to undergo some modifications that are not backward compatible during the development of GML 3.2 (ISO 19136). The GML 3.2 package will implement the model described in the revised version of ISO 19111. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Basic encoding for coordinate system axis objects, simplifying and restricting the DefinitionType as needed. The name by which this coordinate system axis is identified. Definition of a coordinate system axis. Set of alternative identifications of this coordinate system axis. The first axisID, if any, is normally the primary identification code, and any others are aliases. Comments on or information about this coordinate system axis, including data source information. An identification of a coordinate system axis. The abbreviation used for this coordinate system axis. This abbreviation can be used to identify the ordinates in a coordinate tuple. Examples are X and Y. The codeSpace attribute can reference a source of more information on a set of standardized abbreviations, or on this abbreviation. Direction of this coordinate system axis (or in the case of Cartesian projected coordinates, the direction of this coordinate system axis at the origin). Examples: north or south, east or west, up or down. Within any set of coordinate system axes, only one of each pair of terms can be used. For earth-fixed CRSs, this direction is often approximate and intended to provide a human interpretable meaning to the axis. When a geodetic datum is used, the precise directions of the axes may therefore vary slightly from this approximate direction. Note that an EngineeringCRS can include specific descriptions of the directions of its coordinate system axes. For example, the path of a linear CRS axis can be referenced in another document, such as referencing a GML feature that references or includes a curve geometry. The codeSpace attribute can reference a source of more information on a set of standardized directions, or on this direction. Identifier of the unit of measure used for this coordinate system axis. The value of this coordinate in a coordinate tuple shall be recorded using this unit of measure, whenever those coordinates use a coordinate reference system that uses a coordinate system that uses this axis. Association to a coordinate system axis, either referencing or containing the definition of that axis. Basic encoding for coordinate system objects, simplifying and restricting the DefinitionType as needed. The name by which this coordinate system is identified. A coordinate system (CS) is the set of coordinate system axes that spans a given coordinate space. A CS is derived from a set of (mathematical) rules for specifying how coordinates in a given space are to be assigned to points. The coordinate values in a coordinate tuple shall be recorded in the order in which the coordinate system axes associations are recorded, whenever those coordinates use a coordinate reference system that uses this coordinate system. This abstract complexType shall not be used, extended, or restricted, in an Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. Set of alternative identifications of this coordinate system. The first csID, if any, is normally the primary identification code, and any others are aliases. Comments on or information about this coordinate system, including data source information. Ordered sequence of associations to the coordinate system axes included in this coordinate system. An identification of a coordinate system. Association to a coordinate system axis. Association to a coordinate system, either referencing or containing the definition of that coordinate system. A two- or three-dimensional coordinate system in which position is specified by geodetic latitude, geodetic longitude, and (in the three-dimensional case) ellipsoidal height. An EllipsoidalCS shall have two or three usesAxis associations. Association to an ellipsoidal coordinate system, either referencing or containing the definition of that coordinate system. A 1-, 2-, or 3-dimensional coordinate system. Gives the position of points relative to orthogonal straight axes in the 2- and 3-dimensional cases. In the 1-dimensional case, it contains a single straight coordinate axis. In the multi-dimensional case, all axes shall have the same length unit of measure. A CartesianCS shall have one, two, or three usesAxis associations. Association to a Cartesian coordinate system, either referencing or containing the definition of that coordinate system. A one-dimensional coordinate system used to record the heights (or depths) of points. Such a coordinate system is usually dependent on the Earth's gravity field, perhaps loosely as when atmospheric pressure is the basis for the vertical coordinate system axis. A VerticalCS shall have one usesAxis association. Association to a vertical coordinate system, either referencing or containing the definition of that coordinate system. A one-dimensional coordinate system containing a single time axis, used to describe the temporal position of a point in the specified time units from a specified time origin. A TemporalCS shall have one usesAxis association. Association to a temporal coordinate system, either referencing or containing the definition of that coordinate system. A one-dimensional coordinate system that consists of the points that lie on the single axis described. The associated ordinate is the distance from the specified origin to the point along the axis. Example: usage of the line feature representing a road to describe points on or along that road. A LinearCS shall have one usesAxis association. Association to a linear coordinate system, either referencing or containing the definition of that coordinate system. A two- or three-dimensional coordinate system that consists of any combination of coordinate axes not covered by any other coordinate system type. An example is a multilinear coordinate system which contains one coordinate axis that may have any 1-D shape which has no intersections with itself. This non-straight axis is supplemented by one or two straight axes to complete a 2 or 3 dimensional coordinate system. The non-straight axis is typically incrementally straight or curved. A UserDefinedCS shall have two or three usesAxis associations. Association to a user-defined coordinate system, either referencing or containing the definition of that coordinate system. A three-dimensional coordinate system with one distance measured from the origin and two angular coordinates. Not to be confused with an ellipsoidal coordinate system based on an ellipsoid "degenerated" into a sphere. A SphericalCS shall have three usesAxis associations. Association to a spherical coordinate system, either referencing or containing the definition of that coordinate system. A two-dimensional coordinate system in which position is specified by the distance from the origin and the angle between the line from the origin to a point and a reference direction. A PolarCS shall have two usesAxis associations. Association to a polar coordinate system, either referencing or containing the definition of that coordinate system. A three-dimensional coordinate system consisting of a polar coordinate system extended by a straight coordinate axis perpendicular to the plane spanned by the polar coordinate system. A CylindricalCS shall have three usesAxis associations. Association to a cylindrical coordinate system, either referencing or containing the definition of that coordinate system. A two- or three-dimensional coordinate system with straight axes that are not necessarily orthogonal. An ObliqueCartesianCS shall have two or three usesAxis associations. Association to an oblique-Cartesian coordinate system, either referencing or containing the definition of that coordinate system. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/coverage.xsd ================================================ coverage.xsd GML Coverage schema. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Abstract element which acts as the head of a substitution group for coverages. Note that a coverage is a GML feature. A continuous coverage as defined in ISO 19123 is a coverage that can return different values for the same feature attribute at different direct positions within a single spatiotemporal object in its spatiotemporal domain A discrete coverage consists of a domain set, range set and optionally a coverage function. The domain set consists of either geometry or temporal objects, finite in number. The range set is comprised of a finite number of attribute values each of which is associated to every direct position within any single spatiotemporal object in the domain. In other words, the range values are constant on each spatiotemporal object in the domain. This coverage function maps each element from the coverage domain to an element in its range. This definition conforms to ISO 19123. The spatiotemporal domain of a coverage. Typically * a geometry collection, * an implicit geometry (e.g. a grid), * an explicit or implicit collection of time instances or periods, or N.B. Temporal geometric complexes and temporal grids are not yet implemented in GML. each member _Value holds a tuple or "row" from the equivalent table each list holds the complete set of one scalar component from the values - i.e. a "column" from the equivalent table Its tuple list holds the values as space-separated tuples each of which contains comma-separated components, and the tuple structure is specified using the rangeParameters property. a reference to an external source for the data, together with a description of how that external source is structured The function or rule which defines the map from members of the domainSet to the range. More functions will be added to this list List of codes that identifies the file structure model for records stored in files. Metadata about the rangeSet. Definition of record structure. This is required if the rangeSet is encoded in a DataBlock. We use a gml:_Value with empty values as a map of the composite value structure. Description of a rule for associating members from the domainSet with members of the rangeSet. Defines how values in the domain are mapped to the range set. The start point and the sequencing rule are specified here. If absent, the implied value is "Linear". Index position of the first grid post, which must lie somwhere in the GridEnvelope. If absent, the startPoint is equal to the value of gridEnvelope::low from the grid definition. Exends GridFunctionType with a lookUpTable. This contains a list of indexes of members within the rangeSet corresponding with the members of the domainSet. The domainSet is traversed in list order if it is enumerated explicitly, or in the order specified by a SequenceRule if the domain is an implicit set. The length of the lookUpTable corresponds with the length of the subset of the domainSet for which the coverage is defined. List of codes (adopted from ISO 19123 Annex C) that identifies the rule for traversing a grid to correspond with the sequence of members of the rangeSet. The enumeration value here indicates the incrementation order to be used on the first 2 axes, i.e. "+x-y" means that the points on the first axis are to be traversed from lowest to highest and the points on the second axis are to be traversed from highest to lowest. The points on all other axes (if any) beyond the first 2 are assumed to increment from lowest to highest. A discrete coverage type whose domain is defined by a collection of point A discrete coverage type whose domain is defined by a collection of curves. A discrete coverage type whose domain is defined by a collection of surface patches (includes polygons, triangles, rectangles, etc). A discrete coverage type whose domain is defined by a collection of Solids. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/dataQuality.xsd ================================================ How to encode positional data quality information. Builds on units.xsd to encode the data needed to describe the positional accuracy of coordinate operations. This schema encodes the Data Quality (DQ) package of the extended UML Model for OGC Abstract Specification Topic 2: Spatial Referencing by Coordinates. That UML model is adapted from ISO 19111 - Spatial referencing by coordinates, as described in Annex C of Topic 2. Caution: The CRS package in GML 3.1 and GML 3.1.1 is preliminary, and is expected to undergo some modifications that are not backward compatible during the development of GML 3.2 (ISO 19136). The GML 3.2 package will implement the model described in the revised version of ISO 19111. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Position error estimate (or accuracy) data. A description of the position accuracy parameter(s) provided. Closeness of reported coordinate values to values accepted as or being true. Closeness of the relative positions of two or more positions to their respective relative positions accepted as or being true. A quantitative result defined by the evaluation procedure used, and identified by the measureDescription. Error estimate covariance matrix. Ordered sequence of units of measure, corresponding to the row and column index numbers of the covariance matrix, starting with row and column 1 and ending with row/column N. Each unit of measure is for the ordinate reflected in the relevant row and column of the covariance matrix. Unordered set of elements in this covariance matrix. Because the covariance matrix is symmetrical, only the elements in the upper or lower diagonal part (including the main diagonal) of the matrix need to be specified. Any zero valued covariance elements can be omitted. An element of a covariance matrix. Row number of this covariance element value. Column number of this covariance element value. Value of covariance matrix element. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/datums.xsd ================================================ How to encode datum definitions. Builds on referenceSystems.xsd to encode the data needed to define datums, including the specific subtypes of datums. This schema encodes the Datum (CD_) package of the extended UML Model for OGC Abstract Specification Topic 2: Spatial Referencing by Coordinates. That UML model is adapted from ISO 19111 - Spatial referencing by coordinates, as described in Annex C of Topic 2. Caution: The CRS package in GML 3.1 and GML 3.1.1 is preliminary, and is expected to undergo some modifications that are not backward compatible during the development of GML 3.2 (ISO 19136). The GML 3.2 package will implement the model described in the revised version of ISO 19111. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Basic encoding for datum objects, simplifying and restricting the DefinitionType as needed. The name by which this datum is identified. A datum specifies the relationship of a coordinate system to the earth, thus creating a coordinate reference system. A datum uses a parameter or set of parameters that determine the location of the origin of the coordinate reference system. Each datum subtype can be associated with only specific types of coordinate systems. This abstract complexType shall not be used, extended, or restricted, in an Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. Set of alternative identifications of this datum. The first datumID, if any, is normally the primary identification code, and any others are aliases. Comments on this reference system, including source information. An identification of a datum. Description, possibly including coordinates, of the point or points used to anchor the datum to the Earth. Also known as the "origin", especially for engineering and image datums. The codeSpace attribute can be used to reference a source of more detailed on this point or surface, or on a set of such descriptions. - For a geodetic datum, this point is also known as the fundamental point, which is traditionally the point where the relationship between geoid and ellipsoid is defined. In some cases, the "fundamental point" may consist of a number of points. In those cases, the parameters defining the geoid/ellipsoid relationship have been averaged for these points, and the averages adopted as the datum definition. - For an engineering datum, the anchor point may be a physical point, or it may be a point with defined coordinates in another CRS. When appropriate, the coordinates of this anchor point can be referenced in another document, such as referencing a GML feature that references or includes a point position. - For an image datum, the anchor point is usually either the centre of the image or the corner of the image. - For a temporal datum, this attribute is not defined. Instead of the anchor point, a temporal datum carries a separate time origin of type DateTime. The time after which this datum definition is valid. This time may be precise (e.g. 1997.0 for IRTF97) or merely a year (e.g. 1983 for NAD83). In the latter case, the epoch usually refers to the year in which a major recalculation of the geodetic control network, underlying the datum, was executed or initiated. An old datum can remain valid after a new datum is defined. Alternatively, a datum may be superseded by a later datum, in which case the realization epoch for the new datum defines the upper limit for the validity of the superseded datum. Association to a datum, either referencing or containing the definition of that datum. An engineering datum defines the origin of an engineering coordinate reference system, and is used in a region around that origin. This origin can be fixed with respect to the earth (such as a defined point at a construction site), or be a defined point on a moving vehicle (such as on a ship or satellite). Association to an engineering datum, either referencing or containing the definition of that datum. An image datum defines the origin of an image coordinate reference system, and is used in a local context only. For more information, see OGC Abstract Specification Topic 2. Specification of the way an image grid is associated with the image data attributes. Reference to a source of information specifying the values and meanings of all the allowed string values for this PixelInCellType. Association to an image datum, either referencing or containing the definition of that datum. A textual description and/or a set of parameters identifying a particular reference level surface used as a zero-height surface, including its position with respect to the Earth for any of the height types recognized by this standard. There are several types of Vertical Datums, and each may place constraints on the Coordinate Axis with which it is combined to create a Vertical CRS. Type of a vertical datum. Reference to a source of information specifying the values and meanings of all the allowed string values for this VerticalDatumTypeType. Association to a vertical datum, either referencing or containing the definition of that datum. Partially defines the origin of a temporal coordinate reference system. This type restricts the AbstractDatumType to remove the "anchorPoint" and "realizationEpoch" elements. Defines the origin of a temporal coordinate reference system. This type extends the TemporalDatumRestrictionType to add the "origin" element with the dateTime type. The date and time origin of this temporal datum. Association to a temporal datum, either referencing or containing the definition of that datum. A geodetic datum defines the precise location and orientation in 3-dimensional space of a defined ellipsoid (or sphere) that approximates the shape of the earth, or of a Cartesian coordinate system centered in this ellipsoid (or sphere). Association to the prime meridian used by this geodetic datum. Association to the ellipsoid used by this geodetic datum. Association to a geodetic datum, either referencing or containing the definition of that datum. Basic encoding for prime meridian objects, simplifying and restricting the DefinitionType as needed. The name by which this prime meridian is identified. The meridianName most common value is Greenwich, and that value shall be used when the greenwichLongitude value is zero. A prime meridian defines the origin from which longitude values are determined. Set of alternative identifications of this prime meridian. The first meridianID, if any, is normally the primary identification code, and any others are aliases. Comments on or information about this prime meridian, including source information. An identification of a prime meridian. Longitude of the prime meridian measured from the Greenwich meridian, positive eastward. The greenwichLongitude most common value is zero, and that value shall be used when the meridianName value is Greenwich. Association to a prime meridian, either referencing or containing the definition of that meridian. Basic encoding for ellipsoid objects, simplifying and restricting the DefinitionType as needed. The name by which this ellipsoid is identified. An ellipsoid is a geometric figure that can be used to describe the approximate shape of the earth. In mathematical terms, it is a surface formed by the rotation of an ellipse about its minor axis. Set of alternative identifications of this ellipsoid. The first ellipsoidID, if any, is normally the primary identification code, and any others are aliases. Comments on or information about this ellipsoid, including source information. An identification of an ellipsoid. Length of the semi-major axis of the ellipsoid, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a length, such as metres or feet. Association to an ellipsoid, either referencing or containing the definition of that ellipsoid. Definition of the second parameter that defines the shape of an ellipsoid. An ellipsoid requires two defining parameters: semi-major axis and inverse flattening or semi-major axis and semi-minor axis. When the reference body is a sphere rather than an ellipsoid, only a single defining parameter is required, namely the radius of the sphere; in that case, the semi-major axis "degenerates" into the radius of the sphere. Inverse flattening value of the ellipsoid. Value is a scale factor (or ratio) that has no physical unit. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a scale factor, such as percent, permil, or parts-per-million. Length of the semi-minor axis of the ellipsoid. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a length, such as metres or feet. The ellipsoid is degenerate and is actually a sphere. The sphere is completely defined by the semi-major axis, which is the radius of the sphere. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd ================================================ defaultStyle.xsd Default Style schema for GML 3.1.1 GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Top-level property. Used in application schemas to "attach" the styling information to GML data. The link between the data and the style should be established through this property only. [complexType of] Top-level property. Used in application schemas to "attach" the styling information to GML data. The link between the data and the style should be established through this property only. The value of the top-level property. It is an abstract element. Used as the head element of the substitution group for extensibility purposes. [complexType of] The value of the top-level property. It is an abstract element. Used as the head element of the substitution group for extensibility purposes. Predefined concrete value of the top-level property. Encapsulates all other styling information. [complexType of] Predefined concrete value of the top-level property. Encapsulates all other styling information. The style descriptor for features. [complexType of] The style descriptor for features. Used to specify the grammar of the feature query mechanism. Base complex type for geometry, topology, label and graph styles. The style descriptor for geometries of a feature. [complexType of] The style descriptor for geometries of a feature. deprecated Deprecated in GML version 3.1.0. Use symbol with inline content instead. The style descriptor for topologies of a feature. Describes individual topology elements styles. [complexType of] The style descriptor for topologies of a feature. Describes individual topology elements styles. deprecated Deprecated in GML version 3.1.0. Use symbol with inline content instead. The style descriptor for labels of a feature, geometry or topology. [complexType of] The style descriptor for labels of a feature, geometry or topology. The style descriptor for a graph consisting of a number of features. Describes graph-specific style attributes. [complexType of] The style descriptor for a graph consisting of a number of features. Describes graph-specific style attributes. The symbol property. Extends the gml:AssociationType to allow for remote referencing of symbols. [complexType of] The symbol property. Allows for remote referencing of symbols. Used to specify the type of the symbol used. Label is mixed -- composed of text and XPath expressions used to extract the useful information from the feature. Defines the geometric transformation of entities. There is no particular grammar defined for this value. Used to vary individual graphic parameters and attributes of the style, symbol or text. Graph-specific styling property. Graph-specific styling property. Graph-specific styling property. Graph-specific styling property. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/dictionary.xsd ================================================ Dictionary schema for GML 3.1.1 Components to support the lists of definitions. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This content model group makes it easier to construct types that derive from DefinitionType and its descendents "by restriction". A reference to the group saves having to enumerate the standard definition properties. See definition of StandardObjectProperties for more documentation A definition, which can be included in or referenced by a dictionary. In this extended type, the inherited "description" optional element can hold the definition whenever only text is needed. The inherited "name" elements can provide one or more brief terms for which this is the definition. The inherited "metaDataProperty" elements can be used to reference or include more information about this definition. The gml:id attribute is required - it must be possible to reference this definition using this handle. A non-abstract bag that is specialized for use as a dictionary which contains a set of definitions. These definitions are referenced from other places, in the same and different XML documents. In this restricted type, the inherited optional "description" element can be used for a description of this dictionary. The inherited optional "name" element can be used for the name(s) of this dictionary. The inherited "metaDataProperty" elements can be used to reference or contain more information about this dictionary. The inherited required gml:id attribute allows the dictionary to be referenced using this handle. An entry in this dictionary. The content of an entry can itself be a lower level dictionary or definition collection. This element follows the standard GML property model, so the value may be provided directly or by reference. Note that if the value is provided by reference, this definition does not carry a handle (gml:id) in this context, so does not allow external references to this specific entry in this context. When used in this way the referenced definition will usually be in a dictionary in the same XML document. An identified reference to a remote entry in this dictionary, to be used when this entry should be identified to allow external references to this specific entry. An entry in a dictionary of definitions. An instance of this type contains or refers to a definition object. The number of definitions contained in this dictionaryEntry is restricted to one, but a DefinitionCollection or Dictionary that contains multiple definitions can be substituted if needed. Specialized descendents of this dictionaryEntry might be restricted in an application schema to allow only including specified types of definitions as valid entries in a dictionary. This element in a dictionary entry contains the actual definition. A non-identified reference to a remote entry in this dictionary, to be used when this entry need not be identified to allow external references to this specific entry. The remote entry referenced will usually be in a dictionary in the same XML document. This element will usually be used in dictionaries that are inside of another dictionary. An entry in a dictionary of definitions that contains a GML object which references a remote definition object. This entry is expected to be convenient in allowing multiple elements in one XML document to contain short (abbreviated XPointer) references, which are resolved to an external definition provided in a Dictionary element in the same XML document. Specialized descendents of this dictionaryEntry might be restricted in an application schema to allow only including specified types of definitions as valid entries in a dictionary. A proxy entry in a dictionary of definitions. An element of this type contains a reference to a remote definition object. This entry is expected to be convenient in allowing multiple elements in one XML document to contain short (abbreviated XPointer) references, which are resolved to an external definition provided in a Dictionary element in the same XML document. A reference to a remote entry in this dictionary, used when this dictionary entry is identified to allow external references to this specific entry. The remote entry referenced can be in a dictionary in the same or different XML document. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/direction.xsd ================================================ direction.xsd This schema defines "direction" element and type. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Direction expressed as a vector, either using components, or using angles. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/dynamicFeature.xsd ================================================ Basic support for tracking moving objects and objects with changing state. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . A timeslice encapsulates the time-varying properties of a dynamic feature--it must be extended to represent a timestamped projection of a feature. The dataSource property describes how the temporal data was acquired. This type encapsulates various dynamic properties of moving objects (points, lines, regions). It is useful for dealing with features whose geometry or topology changes over time. The history relationship associates a feature with a sequence of TimeSlice instances. The track of a moving object is a sequence of specialized timeslices that indicate the status of the object. A dynamic feature may possess a history and/or a timestamp. A dynamic feature collection may possess a history and/or a timestamp. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/feature.xsd ================================================ GML Feature schema. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . An abstract feature provides a set of common properties, including id, metaDataProperty, name and description inherited from AbstractGMLType, plus boundedBy. A concrete feature type must derive from this type and specify additional properties in an application schema. A feature must possess an identifying attribute ('id' - 'fid' has been deprecated). deprecated deprecated in GML version 3.1 Bounding shape. Envelope that includes also a temporal extent. Container for a feature - follow gml:AssociationType pattern. Container for features - follow gml:ArrayAssociationType pattern. A feature collection contains zero or more features. Concrete generic feature collection. Makes boundedBy mandatory deprecated deprecated in GML version 3.1 Deprecated in GML 3.1.0 Convenience property for generalised location. A representative location for plotting or analysis. Often augmented by one or more additional geometry properties with more specific semantics. Deprecated in GML 3.1.0 Deprecated in GML 3.1.0 G-XML component Deprecated in GML 3.1.0 ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/geometryAggregates.xsd ================================================ geometryAggregates.xsd GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The "_GeometricAggregate" element is the abstract head of the substituition group for all geometric aggremates. This is the abstract root type of the geometric aggregates. A geometry collection must include one or more geometries, referenced through geometryMember elements. The members of the geometric aggregate can be specified either using the "standard" property or the array property style. It is also valid to use both the "standard" and the array property style in the same collection. NOTE: Array properties cannot reference remote geometry elements. This property element either references a geometric aggregate via the XLink-attributes or contains the "multi geometry" element. multiGeometryProperty is the predefined property which can be used by GML Application Schemas whenever a GML Feature has a property with a value that is substitutable for _GeometricAggregate. A property that has a geometric aggregate as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A MultiPoint is defined by one or more Points, referenced through pointMember elements. The members of the geometric aggregate can be specified either using the "standard" property or the array property style. It is also valid to use both the "standard" and the array property style in the same collection. NOTE: Array properties cannot reference remote geometry elements. This property element either references a point aggregate via the XLink-attributes or contains the "multi point" element. multiPointProperty is the predefined property which can be used by GML Application Schemas whenever a GML Feature has a property with a value that is substitutable for MultiPoint. A property that has a collection of points as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A MultiCurve is defined by one or more Curves, referenced through curveMember elements. The members of the geometric aggregate can be specified either using the "standard" property or the array property style. It is also valid to use both the "standard" and the array property style in the same collection. NOTE: Array properties cannot reference remote geometry elements. This property element either references a curve aggregate via the XLink-attributes or contains the "multi curve" element. multiCurveProperty is the predefined property which can be used by GML Application Schemas whenever a GML Feature has a property with a value that is substitutable for MultiCurve. A property that has a collection of curves as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A MultiSurface is defined by one or more Surfaces, referenced through surfaceMember elements. The members of the geometric aggregate can be specified either using the "standard" property or the array property style. It is also valid to use both the "standard" and the array property style in the same collection. NOTE: Array properties cannot reference remote geometry elements. This property element either references a surface aggregate via the XLink-attributes or contains the "multi surface" element. multiSurfaceProperty is the predefined property which can be used by GML Application Schemas whenever a GML Feature has a property with a value that is substitutable for MultiSurface. A property that has a collection of surfaces as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A MultiSolid is defined by one or more Solids, referenced through solidMember elements. The members of the geometric aggregate can be specified either using the "standard" property or the array property style. It is also valid to use both the "standard" and the array property style in the same collection. NOTE: Array properties cannot reference remote geometry elements. This property element either references a solid aggregate via the XLink-attributes or contains the "multi solid" element. multiSolidProperty is the predefined property which can be used by GML Application Schemas whenever a GML Feature has a property with a value that is substitutable for MultiSolid. A property that has a collection of solids as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. Deprecated with GML 3.0 and included for backwards compatibility with GML 2. Use the "MultiSurface" element instead. Deprecated with GML 3.0 and included for backwards compatibility with GML 2. Use the "MultiCurve" element instead. A MultiLineString is defined by one or more LineStrings, referenced through lineStringMember elements. Deprecated with GML version 3.0. Use MultiCurveType instead. This type is deprecated with GML 3 and shall not be used. It is included for backwards compatibility with GML 2. Use MultiCurvePropertyType instead. A property that has a collection of line strings as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A MultiPolygon is defined by one or more Polygons, referenced through polygonMember elements. Deprecated with GML version 3.0. Use MultiSurfaceType instead. This type is deprecated with GML 3 and shall not be used. It is included for backwards compatibility with GML 2. Use MultiSurfacePropertyType instead. A property that has a collection of polygons as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. This property element either references a geometry element via the XLink-attributes or contains the geometry element. This property element contains a list of geometry elements. The order of the elements is significant and shall be preserved when processing the array. This property element either references a Point via the XLink-attributes or contains the Point element. This property element contains a list of points. The order of the elements is significant and shall be preserved when processing the array. This property element contains a list of curves. The order of the elements is significant and shall be preserved when processing the array. This property element either references a surface via the XLink-attributes or contains the surface element. A surface element is any element which is substitutable for "_Surface". This property element contains a list of surfaces. The order of the elements is significant and shall be preserved when processing the array. This property element either references a solid via the XLink-attributes or contains the solid element. A solid element is any element which is substitutable for "_Solid". This property element contains a list of solids. The order of the elements is significant and shall be preserved when processing the array. deprecated Deprecated with GML 3.0 and included only for backwards compatibility with GML 2.0. Use "curveMember" instead. This property element either references a line string via the XLink-attributes or contains the line string element. deprecated Deprecated with GML 3.0 and included only for backwards compatibility with GML 2.0. Use "curveMember" instead. This property element either references a line string via the XLink-attributes or contains the line string element. deprecated Deprecated with GML 3.0 and included only for backwards compatibility with GML 2.0. Use "surfaceMember" instead. This property element either references a polygon via the XLink-attributes or contains the polygon element. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic0d1d.xsd ================================================ geometryBasic0d1d.xsd Schematron validation The presence of a dimension attribute implies the presence of the srsName attribute. The presence of an axisLabels attribute implies the presence of the srsName attribute. The presence of an uomLabels attribute implies the presence of the srsName attribute. The presence of an uomLabels attribute implies the presence of the axisLabels attribute and vice versa. The presence of a count attribute implies the presence of the dimension attribute. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This includes not only measures.xsd, but also units.xsd, gmlBase.xsd and basicTypes.xsd. The "_Geometry" element is the abstract head of the substituition group for all geometry elements of GML 3. This includes pre-defined and user-defined geometry elements. Any geometry element must be a direct or indirect extension/restriction of AbstractGeometryType and must be directly or indirectly in the substitution group of "_Geometry". A geometric property can either be any geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Note that either the reference or the contained element must be given, but not both or none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A container for an array of geometry elements. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements is not supported. All geometry elements are derived directly or indirectly from this abstract supertype. A geometry element may have an identifying attribute ("gml:id"), a name (attribute "name") and a description (attribute "description"). It may be associated with a spatial reference system (attribute "srsName"). The following rules shall be adhered: - Every geometry type shall derive from this abstract type. - Every geometry element (i.e. an element of a geometry type) shall be directly or indirectly in the substitution group of _Geometry. This attribute is included for backward compatibility with GML 2 and is deprecated with GML 3. This identifer is superceded by "gml:id" inherited from AbstractGMLType. The attribute "gid" should not be used anymore and may be deleted in future versions of GML without further notice. Optional reference to the CRS used by this geometry, with optional additional information to simplify use when a more complete definition of the CRS is not needed. In general this reference points to a CRS instance of gml:CoordinateReferenceSystemType (see coordinateReferenceSystems.xsd). For well known references it is not required that the CRS description exists at the location the URI points to. If no srsName attribute is given, the CRS must be specified as part of the larger context this geometry element is part of, e.g. a geometric element like point, curve, etc. It is expected that this attribute will be specified at the direct position level only in rare cases. The "srsDimension" is the length of coordinate sequence (the number of entries in the list). This dimension is specified by the coordinate reference system. When the srsName attribute is omitted, this attribute shall be omitted. Optional additional and redundant information for a CRS to simplify use when a more complete definition of the CRS is not needed. This information shall be the same as included in the more complete definition of the CRS, referenced by the srsName attribute. When the srsName attribute is included, either both or neither of the axisLabels and uomLabels attributes shall be included. When the srsName attribute is omitted, both of these attributes shall be omitted. Ordered list of labels for all the axes of this CRS. The gml:axisAbbrev value should be used for these axis labels, after spaces and forbiddden characters are removed. When the srsName attribute is included, this attribute is optional. When the srsName attribute is omitted, this attribute shall also be omitted. Ordered list of unit of measure (uom) labels for all the axes of this CRS. The value of the string in the gml:catalogSymbol should be used for this uom labels, after spaces and forbiddden characters are removed. When the axisLabels attribute is included, this attribute shall also be included. When the axisLabels attribute is omitted, this attribute shall also be omitted. The "_GeometricPrimitive" element is the abstract head of the substituition group for all (pre- and user-defined) geometric primitives. This is the abstract root type of the geometric primitives. A geometric primitive is a geometric object that is not decomposed further into other primitives in the system. All primitives are oriented in the direction implied by the sequence of their coordinate tuples. A property that has a geometric primitive as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A Point is defined by a single coordinate tuple. GML supports two different ways to specify the direct poisiton of a point. 1. The "pos" element is of type DirectPositionType. Deprecated with GML version 3.1.0 for coordinates with ordinate values that are numbers. Use "pos" instead. The "coordinates" element shall only be used for coordinates with ordinates that require a string representation, e.g. DMS representations. Deprecated with GML version 3.0. Use "pos" instead. The "coord" element is included for backwards compatibility with GML 2. This property element either references a point via the XLink-attributes or contains the point element. pointProperty is the predefined property which can be used by GML Application Schemas whenever a GML Feature has a property with a value that is substitutable for Point. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. A property that has a point as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A container for an array of points. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements is not supported. The "_Curve" element is the abstract head of the substituition group for all (continuous) curve elements. An abstraction of a curve to support the different levels of complexity. The curve can always be viewed as a geometric primitive, i.e. is continuous. This property element either references a curve via the XLink-attributes or contains the curve element. curveProperty is the predefined property which can be used by GML Application Schemas whenever a GML Feature has a property with a value that is substitutable for _Curve. A property that has a curve as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A container for an array of curves. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements is not supported. A LineString is a special curve that consists of a single segment with linear interpolation. It is defined by two or more coordinate tuples, with linear interpolation between them. It is backwards compatible with the LineString of GML 2, GM_LineString of ISO 19107 is implemented by LineStringSegment. GML supports two different ways to specify the control points of a line string. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this curve, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this curve (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this curve only. The number of direct positions in the list must be at least two. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.0. Use "pos" instead. The "coord" element is included for backwards compatibility with GML 2. Deprecated with GML version 3.1.0. Use "posList" instead. DirectPosition instances hold the coordinates for a position within some coordinate reference system (CRS). Since DirectPositions, as data types, will often be included in larger objects (such as geometry elements) that have references to CRS, the "srsName" attribute will in general be missing, if this particular DirectPosition is included in a larger element with such a reference to a CRS. In this case, the CRS is implicitly assumed to take on the value of the containing object's CRS. DirectPositionList instances hold the coordinates for a sequence of direct positions within the same coordinate reference system (CRS). "count" allows to specify the number of direct positions in the list. If the attribute count is present then the attribute srsDimension shall be present, too. Vector instances hold the compoents for a (usually spatial) vector within some coordinate reference system (CRS). Since Vectors will often be included in larger objects that have references to CRS, the "srsName" attribute may be missing. In this case, the CRS is implicitly assumed to take on the value of the containing object's CRS. Note that this content model is the same as DirectPositionType, but is defined separately to reflect the distinct semantics, and to avoid validation problems. SJDC 2004-12-02 A geometric position represented either by a DirectPosition or a Point. A list of geometric positions represented either by a DirectPosition or a Point. Deprecated with GML version 3.1.0. Envelope defines an extent using a pair of positions defining opposite corners in arbitrary dimensions. The first direct position is the "lower corner" (a coordinate position consisting of all the minimal ordinates for each dimension for all points within the envelope), the second one the "upper corner" (a coordinate position consisting of all the maximal ordinates for each dimension for all points within the envelope). deprecated deprecated with GML version 3.0 deprecated Deprecated with GML version 3.1. Use the explicit properties "lowerCorner" and "upperCorner" instead. Deprecated with GML version 3.1.0. Use the explicit properties "lowerCorner" and "upperCorner" instead. Deprecated with GML 3.0 and included for backwards compatibility with GML 2. Use the "pos" element instead. Represents a coordinate tuple in one, two, or three dimensions. Deprecated with GML 3.0 and replaced by DirectPositionType. Deprecated with GML 3.0 and included only for backwards compatibility with GML 2.0. Use "curveProperty" instead. This property element either references a line string via the XLink-attributes or contains the line string element. This type is deprecated with GML 3 and shall not be used. It is included for backwards compatibility with GML 2. Use CurvePropertyType instead. A property that has a line string as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic2d.xsd ================================================ geometryBasic2d.xsd GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The "_Surface" element is the abstract head of the substituition group for all (continuous) surface elements. An abstraction of a surface to support the different levels of complexity. A surface is always a continuous region of a plane. This property element either references a surface via the XLink-attributes or contains the surface element. surfaceProperty is the predefined property which can be used by GML Application Schemas whenever a GML Feature has a property with a value that is substitutable for _Surface. A property that has a surface as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A container for an array of surfaces. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements is not supported. A Polygon is a special surface that is defined by a single surface patch. The boundary of this patch is coplanar and the polygon uses planar interpolation in its interior. It is backwards compatible with the Polygon of GML 2, GM_Polygon of ISO 19107 is implemented by PolygonPatch. The "_Ring" element is the abstract head of the substituition group for all closed boundaries of a surface patch. An abstraction of a ring to support surface boundaries of different complexity. A boundary of a surface consists of a number of rings. In the normal 2D case, one of these rings is distinguished as being the exterior boundary. In a general manifold this is not always possible, in which case all boundaries shall be listed as interior boundaries, and the exterior will be empty. A boundary of a surface consists of a number of rings. The "interior" rings seperate the surface / surface patch from the area enclosed by the rings. Deprecated with GML 3.0, included only for backwards compatibility with GML 2. Use "exterior" instead. Deprecated with GML 3.0, included only for backwards compatibility with GML 2. Use "interior" instead. Encapsulates a ring to represent the surface boundary property of a surface. A LinearRing is defined by four or more coordinate tuples, with linear interpolation between them; the first and last coordinates must be coincident. GML supports two different ways to specify the control points of a linear ring. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this ring, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this ring (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this ring only. The number of direct positions in the list must be at least four. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. Deprecated with GML version 3.0 and included for backwards compatibility with GML 2. Use "pos" elements instead. Encapsulates a ring to represent properties in features or geometry collections. Deprecated with GML 3.0 and included only for backwards compatibility with GML 2.0. Use "surfaceProperty" instead. This property element either references a polygon via the XLink-attributes or contains the polygon element. This type is deprecated with GML 3 and shall not be used. It is included for backwards compatibility with GML 2. Use SurfacePropertyType instead. A property that has a polygon as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/geometryComplexes.xsd ================================================ geometryComplexes.xsd GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . A CompositeCurve is defined by a sequence of (orientable) curves such that the each curve in the sequence terminates at the start point of the subsequent curve in the list. This element references or contains one curve in the composite curve. The curves are contiguous, the collection of curves is ordered. NOTE: This definition allows for a nested structure, i.e. a CompositeCurve may use, for example, another CompositeCurve as a curve member. A CompositeSurface is defined by a set of orientable surfaces. A composite surface is geometry type with all the geometric properties of a (primitive) surface. Essentially, a composite surface is a collection of surfaces that join in pairs on common boundary curves and which, when considered as a whole, form a single surface. This element references or contains one surface in the composite surface. The surfaces are contiguous. NOTE: This definition allows for a nested structure, i.e. a CompositeSurface may use, for example, another CompositeSurface as a member. A composite solid is a geometry type with all the geometric properties of a (primitive) solid. Essentially, a composite solid is a collection of solids that join in pairs on common boundary surfaces and which, when considered as a whole, form a single solid. This element references or contains one solid in the composite solid. The solids are contiguous. NOTE: This definition allows for a nested structure, i.e. a CompositeSolid may use, for example, another CompositeSolid as a member. A geometric complex. A property that has a geometric complex as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. NOTE: The allowed geometry elements contained in such a property (or referenced by it) have to be modelled by an XML Schema choice element since the composites inherit both from geometric complex *and* geometric primitive and are already part of the _GeometricPrimitive substitution group. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/geometryPrimitives.xsd ================================================ geometryPrimitives.xsd GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Curve is a 1-dimensional primitive. Curves are continuous, connected, and have a measurable length in terms of the coordinate system. A curve is composed of one or more curve segments. Each curve segment within a curve may be defined using a different interpolation method. The curve segments are connected to one another, with the end point of each segment except the last being the start point of the next segment in the segment list. The orientation of the curve is positive. This element encapsulates the segments of the curve. This property element either references a curve via the XLink-attributes or contains the curve element. A curve element is any element which is substitutable for "_Curve". OrientableCurve consists of a curve and an orientation. If the orientation is "+", then the OrientableCurve is identical to the baseCurve. If the orientation is "-", then the OrientableCurve is related to another _Curve with a parameterization that reverses the sense of the curve traversal. References or contains the base curve (positive orientation). NOTE: This definition allows for a nested structure, i.e. an OrientableCurve may use another OrientableCurve as its base curve. If the orientation is "+", then the OrientableCurve is identical to the baseCurve. If the orientation is "-", then the OrientableCurve is related to another _Curve with a parameterization that reverses the sense of the curve traversal. "+" is the default value. The "_CurveSegment" element is the abstract head of the substituition group for all curve segment elements, i.e. continuous segments of the same interpolation mechanism. Curve segment defines a homogeneous segment of a curve. The attribute "numDerivativesAtStart" specifies the type of continuity between this curve segment and its predecessor. If this is the first curve segment in the curve, one of these values, as appropriate, is ignored. The default value of "0" means simple continuity, which is a mandatory minimum level of continuity. This level is referred to as "C 0 " in mathematical texts. A value of 1 means that the function and its first derivative are continuous at the appropriate end point: "C 1 " continuity. A value of "n" for any integer means the function and its first n derivatives are continuous: "C n " continuity. NOTE: Use of these values is only appropriate when the basic curve definition is an underdetermined system. For example, line string segments cannot support continuity above C 0 , since there is no spare control parameter to adjust the incoming angle at the end points of the segment. Spline functions on the other hand often have extra degrees of freedom on end segments that allow them to adjust the values of the derivatives to support C 1 or higher continuity. The attribute "numDerivativesAtEnd" specifies the type of continuity between this curve segment and its successor. If this is the last curve segment in the curve, one of these values, as appropriate, is ignored. The default value of "0" means simple continuity, which is a mandatory minimum level of continuity. This level is referred to as "C 0 " in mathematical texts. A value of 1 means that the function and its first derivative are continuous at the appropriate end point: "C 1 " continuity. A value of "n" for any integer means the function and its first n derivatives are continuous: "C n " continuity. NOTE: Use of these values is only appropriate when the basic curve definition is an underdetermined system. For example, line string segments cannot support continuity above C 0 , since there is no spare control parameter to adjust the incoming angle at the end points of the segment. Spline functions on the other hand often have extra degrees of freedom on end segments that allow them to adjust the values of the derivatives to support C 1 or higher continuity. The attribute "numDerivativesInterior" specifies the type of continuity that is guaranteed interior to the curve. The default value of "0" means simple continuity, which is a mandatory minimum level of continuity. This level is referred to as "C 0 " in mathematical texts. A value of 1 means that the function and its first derivative are continuous at the appropriate end point: "C 1 " continuity. A value of "n" for any integer means the function and its first n derivatives are continuous: "C n " continuity. NOTE: Use of these values is only appropriate when the basic curve definition is an underdetermined system. For example, line string segments cannot support continuity above C 0 , since there is no spare control parameter to adjust the incoming angle at the end points of the segment. Spline functions on the other hand often have extra degrees of freedom on end segments that allow them to adjust the values of the derivatives to support C 1 or higher continuity. This property element contains a list of curve segments. The order of the elements is significant and shall be preserved when processing the array. A container for an array of curve segments. A LineStringSegment is a curve segment that is defined by two or more coordinate tuples, with linear interpolation between them. Note: LineStringSegment implements GM_LineString of ISO 19107. GML supports two different ways to specify the control points of a curve segment. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this curve segment, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this curve segment (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this curve segment only. The number of direct positions in the list must be at least two. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. The attribute "interpolation" specifies the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. For a LineStringSegment the interpolation is fixed as "linear". An ArcString is a curve segment that uses three-point circular arc interpolation. GML supports two different ways to specify the control points of a curve segment. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this curve segment, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this curve segment (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this curve segment only. The number of direct positions in the list must be at least three. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. The attribute "interpolation" specifies the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. For an ArcString the interpolation is fixed as "circularArc3Points". The number of arcs in the arc string can be explicitly stated in this attribute. The number of control points in the arc string must be 2 * numArc + 1. An Arc is an arc string with only one arc unit, i.e. three control points. GML supports two different ways to specify the control points of a curve segment. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this curve segment, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this curve segment (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this curve segment only. The number of direct positions in the list must be three. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. An arc is an arc string consiting of a single arc, the attribute is fixed to "1". A Circle is an arc whose ends coincide to form a simple closed loop. The "start" and "end" bearing are equal and shall be the bearing for the first controlPoint listed. The three control points must be distinct non-co-linear points for the Circle to be unambiguously defined. The arc is simply extended past the third control point until the first control point is encountered. This variant of the arc computes the mid points of the arcs instead of storing the coordinates directly. The control point sequence consists of the start and end points of each arc plus the bulge. GML supports two different ways to specify the control points of a curve segment. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this curve segment, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this curve segment (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this curve segment only. The number of direct positions in the list must be at least two. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. The bulge controls the offset of each arc's midpoint. The "bulge" is the real number multiplier for the normal that determines the offset direction of the midpoint of each arc. The length of the bulge sequence is exactly 1 less than the length of the control point array, since a bulge is needed for each pair of adjacent points in the control point array. The bulge is not given by a distance, since it is simply a multiplier for the normal. The midpoint of the resulting arc is given by: midPoint = ((startPoint + endPoint)/2.0) + bulge*normal The attribute "normal" is a vector normal (perpendicular) to the chord of the arc, the line joining the first and last point of the arc. In a 2D coordinate system, there are only two possible directions for the normal, and it is often given as a signed real, indicating its length, with a positive sign indicating a left turn angle from the chord line, and a negative sign indicating a right turn from the chord. In 3D, the normal determines the plane of the arc, along with the start and endPoint of the arc. The normal is usually a unit vector, but this is not absolutely necessary. If the normal is a zero vector, the geometric object becomes equivalent to the straight line between the two end points. The length of the normal sequence is exactly the same as for the bulge sequence, 1 less than the control point sequence length. The attribute "interpolation" specifies the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. For an ArcStringByBulge the interpolation is fixed as "circularArc2PointWithBulge". The number of arcs in the arc string can be explicitly stated in this attribute. The number of control points in the arc string must be numArc + 1. An ArcByBulge is an arc string with only one arc unit, i.e. two control points and one bulge. GML supports two different ways to specify the control points of a curve segment. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this curve segment, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this curve segment (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this curve segment only. The number of direct positions in the list must be two. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. The bulge controls the offset of each arc's midpoint. The "bulge" is the real number multiplier for the normal that determines the offset direction of the midpoint of each arc. The length of the bulge sequence is exactly 1 less than the length of the control point array, since a bulge is needed for each pair of adjacent points in the control point array. The bulge is not given by a distance, since it is simply a multiplier for the normal. The midpoint of the resulting arc is given by: midPoint = ((startPoint + endPoint)/2.0) + bulge*normal The attribute "normal" is a vector normal (perpendicular) to the chord of the arc, the line joining the first and last point of the arc. In a 2D coordinate system, there are only two possible directions for the normal, and it is often given as a signed real, indicating its length, with a positive sign indicating a left turn angle from the chord line, and a negative sign indicating a right turn from the chord. In 3D, the normal determines the plane of the arc, along with the start and endPoint of the arc. The normal is usually a unit vector, but this is not absolutely necessary. If the normal is a zero vector, the geometric object becomes equivalent to the straight line between the two end points. The length of the normal sequence is exactly the same as for the bulge sequence, 1 less than the control point sequence length. An arc is an arc string consiting of a single arc, the attribute is fixed to "1". This variant of the arc requires that the points on the arc have to be computed instead of storing the coordinates directly. The control point is the center point of the arc plus the radius and the bearing at start and end. This represenation can be used only in 2D. GML supports two different ways to specify the control points of a curve segment. 1. A "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) element. The "pos" element contains a center point that is only part of this curve segment, a "pointProperty" element contains a point that may be referenced from other geometry elements or reference another point defined outside of this curve segment (reuse of existing points). 2. The "posList" element can be used to specifiy the coordinates of the center point, too. The number of direct positions in the list must be one. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. The radius of the arc. The bearing of the arc at the start. The bearing of the arc at the end. The attribute "interpolation" specifies the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. For an ArcByCenterPoint the interpolation is fixed as "circularArcCenterPointWithRadius". Since this type describes always a single arc, the attribute is fixed to "1". A CircleByCenterPoint is an ArcByCenterPoint with identical start and end angle to form a full circle. Again, this represenation can be used only in 2D. An offset curve is a curve at a constant distance from the basis curve. They can be useful as a cheap and simple alternative to constructing curves that are offsets by definition. offsetBase is a reference to thecurve from which this curve is define as an offset. distance is the distance at which the offset curve is generated from the basis curve. In 2D systems, positive distances are to be to the left of the basis curve, and the negative distances are to be to the right of the basis curve. refDistance is used to define the vector direction of the offset curve from the basis curve. It can be omitted in the 2D case, where the distance can be positive or negative. In that case, distance defines left side (positive distance) or right side (negative distance) with respect to the tangent to the basis curve. In 3D the basis curve shall have a well defined tangent direction for every point. The offset curve at any point in 3D, the basis curve shall have a well-defined tangent direction for every point. The offset curve at any point (parameter) on the basis curve c is in the direction - - - - s = v x t where v = c.refDirection() and - t = c.tangent() - For the offset direction to be well-defined, v shall not on any point of the curve be in the same, or opposite, direction as - t. The default value of the refDirection shall be the local co-ordinate axis vector for elevation, which indicates up for the curve in a geographic sense. NOTE! If the refDirection is the positive tangent to the local elevation axis ("points upward"), then the offset vector points to the left of the curve when viewed from above. A placement takes a standard geometric construction and places it in geographic space. It defines a transformation from a constructive parameter space to the co-ordinate space of the co-ordinate reference system being used. Parameter spaces in formulae in this International Standard are given as (u, v) in 2D and(u, v, w) in 3D. Co-ordinate reference systems positions are given in formulae, in this International Standard, by either (x, y) in 2D, or (x, y, z) in 3D. Affine placements are defined by linear transformations from parameter space to the target co-ordiante space. 2-dimensional Cartesian parameter space,(u,v) transforms into 3-dimensional co- ordinate reference systems,(x,y,z) by using an affine transformation,(u,v)->(x,y,z) which is defined : x ux vx x0 u y = uy vy + y0 v x uz vz z0 Then, given this equation, the location element of the AffinePlacement is the direct position (x0, y0, z0), which is the target position of the origin in (u, v). The two reference directions (ux, uy, uz) and (vx, vy, vz) are the target directions of the unit vectors at the origin in (u, v). The location property gives the target of the parameter space origin. This is the vector (x0, y0, z0) in the formulae above. The attribute refDirection gives the target directions for the co-ordinate basis vectors of the parameter space. These are the columns of the matrix in the formulae given above. The number of directions given shall be inDimension. The dimension of the directions shall be outDimension. Dimension of the constructive parameter space. Dimension of the co-ordinate space. A clothoid, or Cornu's spiral, is plane curve whose curvature is a fixed function of its length. In suitably chosen co-ordinates it is given by Fresnel's integrals. x(t) = 0-integral-t cos(AT*T/2)dT y(t) = 0-integral-t sin(AT*T/2)dT This geometry is mainly used as a transition curve between curves of type straight line to circular arc or circular arc to circular arc. With this curve type it is possible to achieve a C2-continous transition between the above mentioned curve types. One formula for the Clothoid is A*A = R*t where A is constant, R is the varying radius of curvature along the the curve and t is the length along and given in the Fresnel integrals. The "refLocation" is an affine mapping that places the curve defined by the Fresnel Integrals into the co-ordinate reference system of this object. The element gives the value for the constant in the Fresnel's integrals. The startParameter is the arc length distance from the inflection point that will be the start point for this curve segment. This shall be lower limit used in the Fresnel integral and is the value of the constructive parameter of this curve segment at its start point. The startParameter can either be positive or negative. NOTE! If 0.0 (zero), lies between the startParameter and the endParameter of the clothoid, then the curve goes through the clothoid's inflection point, and the direction of its radius of curvature, given by the second derivative vector, changes sides with respect to the tangent vector. The term length distance for the The endParameter is the arc length distance from the inflection point that will be the end point for this curve segment. This shall be upper limit used in the Fresnel integral and is the value of the constructive parameter of this curve segment at its start point. The startParameter can either be positive or negative. A GeodesicString consists of sequence of geodesic segments. The type essentially combines a sequence of Geodesic into a single object. The GeodesicString is computed from two or more positions and an interpolation using geodesics defined from the geoid (or ellipsoid) of the co-ordinate reference system being used. The attribute "interpolation" specifies the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. For an GeodesicString the interpolation is fixed as "geodesic". A Geodesic consists of two distinct positions joined by a geodesic curve. The control points of a Geodesic shall lie on the geodesic between its start point and end points. Between these two points, a geodesic curve defined from ellipsoid or geoid model used by the co-ordinate reference systems may be used to interpolate other positions. Any other point in the controlPoint array must fall on this geodesic. Cubic splines are similar to line strings in that they are a sequence of segments each with its own defining function. A cubic spline uses the control points and a set of derivative parameters to define a piecewise 3rd degree polynomial interpolation. Unlike line-strings, the parameterization by arc length is not necessarily still a polynomial. The function describing the curve must be C2, that is, have a continuous 1st and 2nd derivative at all points, and pass through the controlPoints in the order given. Between the control points, the curve segment is defined by a cubic polynomial. At each control point, the polynomial changes in such a manner that the 1st and 2nd derivative vectors are the same from either side. The control parameters record must contain vectorAtStart, and vectorAtEnd which are the unit tangent vectors at controlPoint[1] and controlPoint[n] where n = controlPoint.count. Note: only the direction of the vectors is relevant, not their length. GML supports two different ways to specify the control points of a curve segment. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this curve segment, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this curve segment (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this curve segment only. The number of direct positions in the list must be at least three. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. "vectorAtStart" is the unit tangent vector at the start point of the spline. "vectorAtEnd" is the unit tangent vector at the end point of the spline. The attribute "interpolation" specifies the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. For a CubicSpline the interpolation is fixed as "cubicSpline". The degree for a cubic spline is "3". A knot is a breakpoint on a piecewise spline curve. The property "value" is the value of the parameter at the knot of the spline. The sequence of knots shall be a non-decreasing sequence. That is, each knot's value in the sequence shall be equal to or greater than the previous knot's value. The use of equal consecutive knots is normally handled using the multiplicity. The property "multiplicity" is the multiplicity of this knot used in the definition of the spline (with the same weight). The property "weight" is the value of the averaging weight used for this knot of the spline. Encapsulates a knot to use it in a geometric type. A B-Spline is a piecewise parametric polynomial or rational curve described in terms of control points and basis functions. Knots are breakpoints on the curve that connect its pieces. They are given as a non-decreasing sequence of real numbers. If the weights in the knots are equal then it is a polynomial spline. The degree is the algebraic degree of the basis functions. GML supports two different ways to specify the control points of a curve segment. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this curve segment, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this curve segment (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this curve segment only. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. The attribute "degree" shall be the degree of the polynomial used for interpolation in this spline. The property "knot" shall be the sequence of distinct knots used to define the spline basis functions. The attribute "interpolation" specifies the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. For a BSpline the interpolation can be either "polynomialSpline" or "rationalSpline", default is "polynomialSpline". The attribute isPolynomial is set to true if this is a polynomial spline. The attribute "knotType" gives the type of knot distribution used in defining this spline. This is for information only and is set according to the different construction-functions. Bezier curves are polynomial splines that use Bezier or Bernstein polynomials for interpolation purposes. It is a special case of the B-Spline curve with two knots. GML supports two different ways to specify the control points of a curve segment. 1. A sequence of "pos" (DirectPositionType) or "pointProperty" (PointPropertyType) elements. "pos" elements are control points that are only part of this curve segment, "pointProperty" elements contain a point that may be referenced from other geometry elements or reference another point defined outside of this curve segment (reuse of existing points). 2. The "posList" element allows for a compact way to specifiy the coordinates of the control points, if all control points are in the same coordinate reference systems and belong to this curve segment only. Deprecated with GML version 3.1.0. Use "pointProperty" instead. Included for backwards compatibility with GML 3.0.0. Deprecated with GML version 3.1.0. Use "posList" instead. The attribute "degree" shall be the degree of the polynomial used for interpolation in this spline. The property "knot" shall be the sequence of distinct knots used to define the spline basis functions. The attribute "interpolation" specifies the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. For a Bezier the interpolation is fixed as "polynomialSpline". The attribute isPolynomial is set to true as this is a polynomial spline. The property "knotType" is not relevant for Bezier curve segments. A Surface is a 2-dimensional primitive and is composed of one or more surface patches. The surface patches are connected to one another. The orientation of the surface is positive ("up"). The orientation of a surface chooses an "up" direction through the choice of the upward normal, which, if the surface is not a cycle, is the side of the surface from which the exterior boundary appears counterclockwise. Reversal of the surface orientation reverses the curve orientation of each boundary component, and interchanges the conceptual "up" and "down" direction of the surface. If the surface is the boundary of a solid, the "up" direction is usually outward. For closed surfaces, which have no boundary, the up direction is that of the surface patches, which must be consistent with one another. Its included surface patches describe the interior structure of the Surface. This element encapsulates the patches of the surface. This property element either references a surface via the XLink-attributes or contains the surface element. A surface element is any element which is substitutable for "_Surface". OrientableSurface consists of a surface and an orientation. If the orientation is "+", then the OrientableSurface is identical to the baseSurface. If the orientation is "-", then the OrientableSurface is a reference to a Surface with an up-normal that reverses the direction for this OrientableSurface, the sense of "the top of the surface". References or contains the base surface (positive orientation). If the orientation is "+", then the OrientableSurface is identical to the baseSurface. If the orientation is "-", then the OrientableSurface is a reference to a Surface with an up-normal that reverses the direction for this OrientableSurface, the sense of "the top of the surface". "+" is the default value. The "_SurfacePatch" element is the abstract head of the substituition group for all surface pach elements describing a continuous portion of a surface. A surface patch defines a homogenuous portion of a surface. This property element contains a list of surface patches. The order of the elements is significant and shall be preserved when processing the array. A container for an array of surface patches. A PolygonPatch is a surface patch that is defined by a set of boundary curves and an underlying surface to which these curves adhere. The curves are coplanar and the polygon uses planar interpolation in its interior. Implements GM_Polygon of ISO 19107. The attribute "interpolation" specifies the interpolation mechanism used for this surface patch. Currently only planar surface patches are defined in GML 3, the attribute is fixed to "planar", i.e. the interpolation method shall return points on a single plane. The boundary of the patch shall be contained within that plane. Represents a triangle as a surface with an outer boundary consisting of a linear ring. Note that this is a polygon (subtype) with no inner boundaries. The number of points in the linear ring must be four. Constraint: The Ring shall be a LinearRing and must form a triangle, the first and the last position must be co-incident. The attribute "interpolation" specifies the interpolation mechanism used for this surface patch. Currently only planar surface patches are defined in GML 3, the attribute is fixed to "planar", i.e. the interpolation method shall return points on a single plane. The boundary of the patch shall be contained within that plane. Represents a rectangle as a surface with an outer boundary consisting of a linear ring. Note that this is a polygon (subtype) with no inner boundaries. The number of points in the linear ring must be five. Constraint: The Ring shall be a LinearRing and must form a rectangle; the first and the last position must be co-incident. The attribute "interpolation" specifies the interpolation mechanism used for this surface patch. Currently only planar surface patches are defined in GML 3, the attribute is fixed to "planar", i.e. the interpolation method shall return points on a single plane. The boundary of the patch shall be contained within that plane. This property element either references a curve via the XLink-attributes or contains the curve element. A curve element is any element which is substitutable for "_Curve". A Ring is used to represent a single connected component of a surface boundary. It consists of a sequence of curves connected in a cycle (an object whose boundary is empty). A Ring is structurally similar to a composite curve in that the endPoint of each curve in the sequence is the startPoint of the next curve in the Sequence. Since the sequence is circular, there is no exception to this rule. Each ring, like all boundaries, is a cycle and each ring is simple. NOTE: Even though each Ring is simple, the boundary need not be simple. The easiest case of this is where one of the interior rings of a surface is tangent to its exterior ring. This element references or contains one curve in the composite curve. The curves are contiguous, the collection of curves is ordered. NOTE: This definition allows for a nested structure, i.e. a CompositeCurve may use, for example, another CompositeCurve as a curve member. Encapsulates a ring to represent properties in features or geometry collections. Reference points which are organised into sequences or grids(sequences of equal length sequences). A gridded surface is a parametric curve surface derived from a rectangular grid in the parameter space. The rows from this grid are control points for horizontal surface curves; the columns are control points for vertical surface curves. The working assumption is that for a pair of parametric co-ordinates (s, t) that the horizontal curves for each integer offset are calculated and evaluated at "s". The defines a sequence of control points: cn(s) : s 1 .....columns From this sequence a vertical curve is calculated for "s", and evaluated at "t". In most cases, the order of calculation (horizontal-vertical vs. vertical-horizontal) does not make a difference. Where it does, the horizontal- vertical order shall be the one used. Logically, any pair of curve interpolation types can lead to a subtype of GriddedSurface. The following clauses define some most commonly encountered surfaces that can be represented in this manner. This is the double indexed sequence of control points, given in row major form. NOTE! There in no assumption made about the shape of the grid. For example, the positions need not effect a "21/2D" surface, consecutive points may be equal in any or all of the ordinates. Further, the curves in either or both directions may close. The attribute rows gives the number of rows in the parameter grid. The attribute columns gives the number of columns in the parameter grid. A cone is a gridded surface given as a family of conic sections whose control points vary linearly. NOTE! A 5-point ellipse with all defining positions identical is a point. Thus, a truncated elliptical cone can be given as a 2x5 set of control points ((P1, P1, P1, P1, P1), (P2, P3, P4, P5, P6)). P1 is the apex of the cone. P2, P3,P4, P5 and P6 are any five distinct points around the base ellipse of the cone. If the horizontal curves are circles as opposed to ellipses, the a circular cone can be constructed using ((P1, P1, P1),(P2, P3, P4)). The apex most not coinside with the other plane. A cylinder is a gridded surface given as a family of circles whose positions vary along a set of parallel lines, keeping the cross sectional horizontal curves of a constant shape. NOTE! Given the same working assumptions as in the previous note, a Cylinder can be given by two circles, giving us the control points of the form ((P1, P2, P3),(P4, P5, P6)). A sphere is a gridded surface given as a family of circles whose positions vary linearly along the axis of the sphere, and whise radius varies in proportions to the cosine function of the central angle. The horizontal circles resemble lines of constant latitude, and the vertical arcs resemble lines of constant longitude. NOTE! If the control points are sorted in terms of increasing longitude, and increasing latitude, the upNormal of a sphere is the outward normal. EXAMPLE If we take a gridded set of latitudes and longitudes in degrees,(u,v) such as (-90,-180) (-90,-90) (-90,0) (-90, 90) (-90, 180) (-45,-180) (-45,-90) (-45,0) (-45, 90) (-45, 180) ( 0,-180) ( 0,-90) ( 0,0) ( 0, 90) ( 0, 180) ( 45,-180) ( 45,-90) ( 45,0) ( 45, -90) ( 45, 180) ( 90,-180) ( 90,-90) ( 90,0) ( 90, -90) ( 90, 180) And map these points to 3D using the usual equations (where R is the radius of the required sphere). z = R sin u x = (R cos u)(sin v) y = (R cos u)(cos v) We have a sphere of Radius R, centred at (0,0), as a gridded surface. Notice that the entire first row and the entire last row of the control points map to a single point in each 3D Euclidean space, North and South poles respectively, and that each horizontal curve closes back on itself forming a geometric cycle. This gives us a metrically bounded (of finite size), topologically unbounded (not having a boundary, a cycle) surface. A polyhedral surface is a surface composed of polygon surfaces connected along their common boundary curves. This differs from the surface type only in the restriction on the types of surface patches acceptable. This property encapsulates the patches of the polyhedral surface. This property element contains a list of polygon patches. The order of the patches is significant and shall be preserved when processing the list. This type defines a container for an array of polygon patches. This property element contains a list of triangle patches. The order of the patches is significant and shall be preserved when processing the list. This type defines a container for an array of triangle patches. A triangulated surface is a polyhedral surface that is composed only of triangles. There is no restriction on how the triangulation is derived. This property encapsulates the patches of the triangulated surface. A tin is a triangulated surface that uses the Delauny algorithm or a similar algorithm complemented with consideration of breaklines, stoplines, and maximum length of triangle sides. These networks satisfy the Delauny's criterion away from the modifications: Fore each triangle in the network, the circle passing through its vertices does not contain, in its interior, the vertex of any other triangle. Stoplines are lines where the local continuity or regularity of the surface is questionable. In the area of these pathologies, triangles intersecting a stopline shall be removed from the tin surface, leaving holes in the surface. If coincidence occurs on surface boundary triangles, the result shall be a change of the surface boundary. Stoplines contains all these pathological segments as a set of line strings. Breaklines are lines of a critical nature to the shape of the surface, representing local ridges, or depressions (such as drainage lines) in the surface. As such their constituent segments must be included in the tin eve if doing so violates the Delauny criterion. Break lines contains these critical segments as a set of line strings. Areas of the surface where data is not sufficiently dense to assure reasonable calculation shall be removed by adding a retention criterion for triangles based on the length of their sides. For many triangle sides exceeding maximum length, the adjacent triangles to that triangle side shall be removed from the surface. The corners of the triangles in the TIN are often referred to as pots. ControlPoint shall contain a set of the GM_Position used as posts for this TIN. Since each TIN contains triangles, there must be at least 3 posts. The order in which these points are given does not affect the surface that is represented. Application schemas may add information based on ordering of control points to facilitate the reconstruction of the TIN from the control points. The "_Solid" element is the abstract head of the substituition group for all (continuous) solid elements. An abstraction of a solid to support the different levels of complexity. A solid is always contiguous. This property element either references a solid via the XLink-attributes or contains the solid element. solidProperty is the predefined property which can be used by GML Application Schemas whenever a GML Feature has a property with a value that is substitutable for _Solid. A property that has a solid as its value domain can either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element must be given, but neither both nor none. This attribute group includes the XLink attributes (see xlinks.xsd). XLink is used in GML to reference remote resources (including those elsewhere in the same document). A simple link element can be constructed by including a specific set of XLink attributes. The XML Linking Language (XLink) is currently a Proposed Recommendation of the World Wide Web Consortium. XLink allows elements to be inserted into XML documents so as to create sophisticated links between resources; such links can be used to reference remote properties. A simple link element can be used to implement pointer functionality, and this functionality has been built into various GML 3 elements by including the gml:AssociationAttributeGroup. A container for an array of solids. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements is not supported. A solid is the basis for 3-dimensional geometry. The extent of a solid is defined by the boundary surfaces (shells). A shell is represented by a composite surface, where every shell is used to represent a single connected component of the boundary of a solid. It consists of a composite surface (a list of orientable surfaces) connected in a topological cycle (an object whose boundary is empty). Unlike a Ring, a Shell's elements have no natural sort order. Like Rings, Shells are simple. Boundaries of solids are similar to surface boundaries. In normal 3-dimensional Euclidean space, one (composite) surface is distinguished as the exterior. In the more general case, this is not always possible. Boundaries of solids are similar to surface boundaries. CurveInterpolationType is a list of codes that may be used to identify the interpolation mechanisms specified by an application schema. SurfaceInterpolationType is a list of codes that may be used to identify the interpolation mechanisms specified by an application schema. Defines allowed values for the knots` type. Uniform knots implies that all knots are of multiplicity 1 and they differ by a positive constant from the preceding knot. Knots are quasi-uniform iff they are of multiplicity (degree + 1) at the ends, of multiplicity 1 elsewhere, and they differ by a positive constant from the preceding knot. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/gml.xsd ================================================ gml.xsd Top level GML schema GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/gmlBase.xsd ================================================ Schematron validation Property element may not carry both a reference to an object and contain an object. Property element must either carry a reference to an object or contain an object. GML base schema for GML 3 Components to support the GML encoding model. The abstract Schematron rules can be used by any schema that includes gmlBase. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This abstract element is the head of a substitutionGroup hierararchy which may contain either simpleContent or complexContent elements. It is used to assert the model position of "class" elements declared in other GML schemas. Global element which acts as the head of a substitution group that may include any element which is a GML feature, object, geometry or complex value This content model group makes it easier to construct types that derive from AbstractGMLType and its descendents "by restriction". A reference to the group saves having to enumerate the standard object properties. Multiple names may be provided. These will often be distinguished by being assigned by different authorities, as indicated by the value of the codeSpace attribute. In an instance document there will usually only be one name per authority. All complexContent GML elements are directly or indirectly derived from this abstract supertype to establish a hierarchy of GML types that may be distinguished from other XML types by their ancestry. Elements in this hierarchy may have an ID and are thus referenceable. Generic GML element to contain a heterogeneous collection of GML _Objects A non-abstract generic collection type that can be used as a document element for a collection of any GML types - Geometries, Topologies, Features ... FeatureCollections may only contain Features. GeometryCollections may only contain Geometrys. Bags are less constrained they must contain objects that are substitutable for gml:_Object. This may mix several levels, including Features, Definitions, Dictionaries, Geometries etc. The content model would ideally be member 0..* members 0..1 member 0..* for maximum flexibility in building a collection from both homogeneous and distinct components: included "member" elements each contain a single Object an included "members" element contains a set of Objects However, this is non-deterministic, thus prohibited by XSD. Generic GML element to contain a homogeneous array of GML _Objects A non-abstract generic collection type that can be used as a document element for a homogeneous collection of any GML types - Geometries, Topologies, Features ... Abstract element which acts as the head of a substitution group for packages of MetaData properties. An abstract base type for complex metadata types. Concrete element in the _MetaData substitution group, which permits any well-formed XML content. Intended to act as a container for metadata defined in external schemas, for which it is not possible to add the concrete components to the GML _MetaData substitution group directly. Deprecated with GML version 3.1.0. Deprecated with GML version 3.1.0. must carry a reference to an object or contain an object but not both A pattern or base for derived types used to specify complex types corresponding to an unspecified UML association - either composition or aggregation. Restricts the cardinality of Objects contained in the association to a maximum of one. An instance of this type can contain an element representing an Object, or serve as a pointer to a remote Object. Descendents of this type can be restricted in an application schema to * allow only specified classes as valid participants in the aggregation * allow only association by reference (i.e. empty the content model) or by value (i.e. remove the xlinks). When used for association by reference, the value of the gml:remoteSchema attribute can be used to locate a schema fragment that constrains the target instance. In many cases it is desirable to impose the constraint prohibiting the occurence of both reference and value in the same instance, as that would be ambiguous. This is accomplished by adding a directive in the annotation element of the element declaration. This directive can be in the form of normative prose, or can use a Schematron pattern to automatically constrain co-occurrence - see the declaration for _strictAssociation below. If co-occurence is not prohibited, then both a link and content may be present. If this occurs in an instance, then the rule for interpretation is that the instance found by traversing the href provides the normative value of the property, and should be used when possible. The value(s) included as content may be used if the remote instance cannot be resolved. This may be considered to be a "cached" version of the value(s). A pattern or base for derived types used to specify complex types corresponding to a UML aggregation association. An instance of this type serves as a pointer to a remote Object. A base for derived types used to specify complex types containing an array of objects, by unspecified UML association - either composition or aggregation. An instance of this type contains elements representing Objects. Ideally this type would be derived by extension of AssociationType. However, this leads to a non-deterministic content model, since both the base and the extension have minOccurs="0", and is thus prohibited in XML Schema. Contains or refers to a metadata package that contains metadata properties. Base type for complex metadata property types. Database handle for the object. It is of XML type ID, so is constrained to be unique in the XML document within which it occurs. An external identifier for the object in the form of a URI may be constructed using standard XML and XPointer methods. This is done by concatenating the URI for the document, a fragment separator, and the value of the id attribute. Reference to an XML Schema fragment that specifies the content model of the propertys value. This is in conformance with the XML Schema Section 4.14 Referencing Schemas from Elsewhere. Attribute group used to enable property elements to refer to their value remotely. It contains the simple link components from xlinks.xsd, with all members optional, and the remoteSchema attribute, which is also optional. These attributes can be attached to any element, thus allowing it to act as a pointer. The 'remoteSchema' attribute allows an element that carries link attributes to indicate that the element is declared in a remote schema rather than by the schema that constrains the current document instance. Label for the object, normally a descriptive name. An object may have several names, typically assigned by different authorities. The authority for a name is indicated by the value of its (optional) codeSpace attribute. The name may or may not be unique, as determined by the rules of the organization responsible for the codeSpace. Contains a simple text description of the object, or refers to an external description. This type is available wherever there is a need for a "text" type property. It is of string type, so the text can be included inline, but the value can also be referenced remotely via xlinks from the AssociationAttributeGroup. If the remote reference is present, then the value obtained by traversing the link should be used, and the string content of the element can be used for an annotation. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/grids.xsd ================================================ grids.xsd Grid geometries A subset of implicit geometries Designed for use with GML Coverage schema, but maybe useful elsewhere as well. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . An unrectified grid, which is a network composed of two or more sets of equally spaced parallel lines in which the members of each set intersect the members of the other sets at right angles. Provides grid coordinate values for the diametrically opposed corners of an envelope that bounds a section of grid. The value of a single coordinate is the number of offsets from the origin of the grid in the direction of a specific axis. Should be substitutionGroup="gml:Grid" but changed in order to accomplish Xerces-J schema validation A rectified grid has an origin and vectors that define its post locations. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/measures.xsd ================================================ Extends the units.xsd and basicTypes.xsd schemas with types for recording measures using specific types of units, especially the measures and units needed for coordinate reference systems and coordinate operations. The specific unit types encoded are length, angle, scale factor, time, area, volume, speed, and grid length. This schema allows angle values to be recorded as single numbers or in degree-minute-second format. Parts of this schema are based on Subclause 6.5.7 of ISO/CD 19103 Geographic information - Conceptual schema language, on Subclause A.5.2.2.3 of ISO/CD 19118 Geographic information - Encoding, and on Subclause 4.7 of OpenGIS Recommendation Paper OGC 02-007r4 Units of Measure Use and Definition Recommendations. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Value of a length (or distance) quantity, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a length, such as metres or feet. Value of a scale factor (or ratio) that has no physical unit. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a scale factor, such as percent, permil, or parts-per-million. Value of a time or temporal quantity, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a time value, such as seconds or weeks. Value of a length (or distance) quantity in a grid, where the grid spacing does not have any associated physical units, or does not have a constant physical spacing. This grid length will often be used in a digital image grid, where the base units are likely to be pixel spacings. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for length along the axes of a grid, such as pixel spacings or grid spacings. Value of a spatial area quantity, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for an area, such as square metres or square miles. Value of a spatial volume quantity, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a volume, such as cubic metres or cubic feet. Value of a speed, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a velocity, such as metres per second or miles per hour. Value of an angle quantity provided in either degree-minute-second format or single value format. Value of an angle quantity recorded as a single number, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for an angle, such as degrees or radians. Angle value provided in degree-minute-second or degree-minute format. Integer number of degrees, plus the angle direction. This element can be used for geographic Latitude and Longitude. For Latitude, the XML attribute direction can take the values "N" or "S", meaning North or South of the equator. For Longitude, direction can take the values "E" or "W", meaning East or West of the prime meridian. This element can also be used for other angles. In that case, the direction can take the values "+" or "-" (of SignType), in the specified rotational direction from a specified reference direction. Integer number of degrees in a degree-minute-second or degree-minute angular value, without indication of direction. Decimal number of arc-minutes in a degree-minute angular value. Integer number of arc-minutes in a degree-minute-second angular value. Number of arc-seconds in a degree-minute-second angular value. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/observation.xsd ================================================ observation.xsd Observation schema for GML 3.1 GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This element contains or points to a description of a sensor, instrument or procedure used for the observation This element contains or points to the specimen, region or station which is the object of the observation Synonym for target - common word used for photographs Container for an object representing the target or subject of an observation. The result of the observation: an image, external object, etc ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/referenceSystems.xsd ================================================ How to encode reference system definitions. Builds on several other parts of GML 3 to encode the data needed to define reference systems. This schema encodes the Reference System (RS_) package of the extended UML Model for OGC Abstract Specification Topic 2: Spatial Referencing by Coordinates. That UML model is adapted from ISO 19111 - Spatial referencing by coordinates, as described in Annex C of Topic 2. The SC_CRS class is also encoded here, to eliminate the (circular) references from coordinateOperations.xsd to coordinateReferenceSystems.xsd. The RS_SpatialReferenceSystemUsingGeographicIdentifier class is not encoded, since it is not applicable to coordinate positions. The CI_Citation class is not directly encoded, since such information can be included as metaDataProperty elements which are optionally allowed. A modified version of the EX_Extent (DataType) class from ISO 19115 is currently encoded here, using GML 3 schema types. (A more extensive version of the EX_Extent package might be XML encoded in the future, probably in a separate extent.xsd schema.) Caution: The CRS package in GML 3.1 and GML 3.1.1 is preliminary, and is expected to undergo some modifications that are not backward compatible during the development of GML 3.2 (ISO 19136). The GML 3.2 package will implement the model described in the revised version of ISO 19111. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Basic encoding for reference system objects, simplifying and restricting the DefinitionType as needed. The name by which this reference system is identified. Description of a spatial and/or temporal reference system used by a dataset. Set of alterative identifications of this reference system. The first srsID, if any, is normally the primary identification code, and any others are aliases. Comments on or information about this reference system, including source information. An identification of a reference system. Association to a reference system, either referencing or containing the definition of that reference system. Abstract coordinate reference system, usually defined by a coordinate system and a datum. This abstract complexType shall not be used, extended, or restricted, in an Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. Association to a CRS abstract coordinate reference system, either referencing or containing the definition of that CRS. An identification of a CRS object. The first use of the IdentifierType for an object, if any, is normally the primary identification code, and any others are aliases. The code or name for this Identifier, often from a controlled list or pattern defined by a code space. The optional codeSpace attribute is normally included to identify or reference a code space within which one or more codes are defined. This code space is often defined by some authority organization, where one organization may define multiple code spaces. The range and format of each Code Space identifier is defined by that code space authority. Information about that code space authority can be included as metaDataProperty elements which are optionally allowed in all CRS objects. Remarks about this code or alias. Identifier of the version of the associated codeSpace or code, as specified by the codeSpace or code authority. This version is included only when the "code" or "codeSpace" uses versions. When appropriate, the version is identified by the effective date, coded using ISO 8601 date format. Information about this object or code. Contains text or refers to external text. Description of domain of usage, or limitations of usage, for which this CRS object is valid. Area or region in which this CRS object is valid. Information about the spatial, vertical, and/or temporal extent of a reference system object. Constraints: At least one of the elements "description", "boundingBox", "boundingPolygon", "verticalExtent", and temporalExtent" must be included, but more that one can be included when appropriate. Furthermore, more than one "boundingBox", "boundingPolygon", "verticalExtent", and/or temporalExtent" element can be included, with more than one meaning the union of the individual domains. Description of spatial and/or temporal extent of this object. Geographic domain of this reference system object. Unordered list of bounding boxes (or envelopes) whose union describes the spatial domain of this object. Unordered list of bounding polygons whose union describes the spatial domain of this object. Unordered list of vertical intervals whose union describes the spatial domain of this object. Unordered list of time periods whose union describes the spatial domain of this object. A bounding box (or envelope) defining the spatial domain of this object. A bounding polygon defining the horizontal spatial domain of this object. An interval defining the vertical spatial domain of this object. A time period defining the temporal domain of this object. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/temporal.xsd ================================================ The temporal schema for GML 3.1 provides constructs for handling time-varying spatial data. This schema reflects a partial implementation of the model described in ISO 19108:2002. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This abstract element acts as the head of the substitution group for temporal primitives and complexes. The abstract supertype for temporal objects. This abstract element acts as the head of the substitution group for temporal primitives. The abstract supertype for temporal primitives. This abstract element acts as the head of the substitution group for temporal complexes. Temporal complex is an aggregation of temporal primitives as its components, represents a temporal geometric complex and a temporal topology complex. N.B. Temporal geometric complex is not defined in this schema. The abstract supertype for temporal complexes. This abstract element acts as the head of the substitution group for temporal geometric primitives. The abstract supertype for temporal geometric primitives. A temporal geometry must be associated with a temporal reference system via URI. The Gregorian calendar with UTC is the default reference system, following ISO 8601. Other reference systems in common use include the GPS calendar and the Julian calendar. Omit back-pointers begunBy, endedBy. This model group is provided as an alternative to the abstract susbstitutionGroup head _timeLength. ISO 19136 comment 411 This element is an instance of the primitive xsd:duration simple type to enable use of the ISO 8601 syntax for temporal length (e.g. P5DT4H30M). It is a valid subtype of TimeDurationType according to section 3.14.6, rule 2.2.4 in XML Schema, Part 1. This element is a valid subtype of TimeDurationType according to section 3.14.6, rule 2.2.4 in XML Schema, Part 1. This type extends the built-in xsd:decimal simple type to allow floating-point values for temporal length. According to the ISO 11404 model you have to use positiveInteger together with appropriate values for radix and factor. The resolution of the time interval is to one radix ^(-factor) of the specified time unit (e.g. unit="second", radix="10", factor="3" specifies a resolution of milliseconds). It is a subtype of TimeDurationType. Standard units for measuring time intervals (see ISO 31-1). Direct representation of a temporal position Direct representation of a temporal position. Indeterminate time values are also allowed, as described in ISO 19108. The indeterminatePosition attribute can be used alone or it can qualify a specific value for temporal position (e.g. before 2002-12, after 1019624400). For time values that identify position within a calendar, the calendarEraName attribute provides the name of the calendar era to which the date is referenced (e.g. the Meiji era of the Japanese calendar). The ISO 19108:2002 hierarchy of subtypes for temporal position are collapsed by defining a union of XML Schema simple types for indicating temporal position relative to a specific reference system. Dates and dateTime may be indicated with varying degrees of precision. dateTime by itself does not allow right-truncation, except for fractions of seconds. When used with non-Gregorian calendars based on years, months, days, the same lexical representation should still be used, with leading zeros added if the year value would otherwise have fewer than four digits. An ordinal position may be referenced via URI identifying the definition of an ordinal era. A time coordinate value is indicated as a decimal (e.g. UNIX time, GPS calendar). Calendar dates may be indicated with varying degrees of precision, using year, year-month, date. When used with non-Gregorian calendars based on years, months, days, the same lexical representation should still be used, with leading zeros added if the year value would otherwise have fewer than four digits. time is used for a position that recurs daily (see clause 5.4.4.2 of ISO 19108:2002). This enumerated data type specifies values for indeterminate positions. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/temporalReferenceSystems.xsd ================================================ The Temporal Reference Systems schema for GML 3.1 provides constructs for handling various styles of temporal reference system. This schema reflects a partial implementation of the model described in ISO 19108:2002. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Abstract element serves primarily as the head of a substitution group for temporal reference systems. A value in the time domain is measured relative to a temporal reference system. Common types of reference systems include calendars, ordinal temporal reference systems, and temporal coordinate systems (time elapsed since some epoch, e.g. UNIX time). A temporal coordinate system is based on a continuous interval scale defined in terms of a single time interval. In an ordinal reference system the order of events in time can be well established, but the magnitude of the intervals between them can not be accurately determined (e.g. a stratigraphic sequence). Ordinal temporal reference systems are often hierarchically structured such that an ordinal era at a given level of the hierarchy includes a sequence of shorter, coterminous ordinal eras. This captured using the member/group properties. Note that in this schema, TIme Ordinal Era is patterned on TimeEdge, which is a variation from ISO 19108. This is in order to fulfill the requirements of ordinal reference systems based on eras delimited by named points or nodes, which are common in geology, archeology, etc. This change is subject of a change proposal to ISO An Era may be composed of several member Eras. The "member" element implements the association to the Era at the next level down the hierarchy. "member" follows the standard GML property pattern whereby its (complex) value may be either described fully inline, or may be the target of a link carried on the member element and described fully elsewhere, either in the same document or from another service. In a particular Time System, an Era may be a member of a group. The "group" element implements the back-pointer to the Era at the next level up in the hierarchy. If the hierarchy is represented by describing the nested components fully in the their nested position inside "member" elements, then the parent can be easily inferred, so the group property is unnecessary. However, if the hierarchy is represented by links carried on the "member" property elements, pointing to Eras described fully elsewhere, then it may be useful for a child (member) era to carry an explicit pointer back to its parent (group) Era. A calendar is a discrete temporal reference system that provides a basis for defining temporal position to a resolution of one day. A single calendar may reference more than one calendar era. Link to the CalendarEras that it uses as a reference for dating. In every calendar, years are numbered relative to the date of a reference event that defines a calendar era. In this implementation, we omit the back-pointer "datingSystem". Name or description of a mythical or historic event which fixes the position of the base scale of the calendar era. Date of the referenceEvent expressed as a date in the given calendar. In most calendars, this date is the origin (i.e., the first day) of the scale, but this is not always true. Julian date that corresponds to the reference date. The Julian day numbering system is a temporal coordinate system that has an origin earlier than any known calendar, at noon on 1 January 4713 BC in the Julian proleptic calendar. The Julian day number is an integer value; the Julian date is a decimal value that allows greater resolution. Transforming calendar dates to and from Julian dates provides a relatively simple basis for transforming dates from one calendar to another. Period for which the calendar era was used as a basis for dating. A clock provides a basis for defining temporal position within a day. A clock must be used with a calendar in order to provide a complete description of a temporal position within a specific day. Name or description of an event, such as solar noon or sunrise, which fixes the position of the base scale of the clock. time of day associated with the reference event expressed as a time of day in the given clock. The reference time is usually the origin of the clock scale. 24 hour local or UTC time that corresponds to the reference time. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/temporalTopology.xsd ================================================ The temporal topology schema for ISO19136 provides constructs for handling topological complexes and temporal feature relationships. Temporal geometric characteristics of features are represented as instants and periods. While, temporal context of features that does not relate to the position of time is described as connectivity relationships among instants and periods. These relationships are called temporal topology as they do not change in time, as long as the direction of time does not change. It is used effectively in the case of describing a family tree expressing evolution of species, an ecological cycle, a lineage of lands or buildings, or a history of separation and merger of administrative boundaries. This schema reflects a partial yet consistent implementation of the model described in ISO 19108:2002. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This element represents temporal topology complex. It shall be the connected acyclic directed graph composed of time nodes and time edges. A temporal topology complex. A time topology complex property can either be any time topology complex element encapsulated in an element of this type or an XLink reference to a remote time topology complex element (where remote includes elements located elsewhere in the same document). Note that either the reference or the contained element must be given, but not both or none. This abstract element acts as the head of the substitution group for temporal topology primitives. The element "complex" carries a reference to the complex containing this primitive. A time topology primitive property can either hold any time topology complex element eor carry an XLink reference to a remote time topology complex element (where remote includes elements located elsewhere in the same document). Note that either the reference or the contained element must be given, but not both or none. "TimeNode" is a zero dimensional temporal topology primitive, expresses a position in topological time, and is a start and an end of time edge, which represents states of time. Time node may be isolated. However, it cannot describe the ordering relationships with other primitives. An isolated node may not be an element of any temporal topology complex. Type declaration of the element "TimeNode". A time node property can either be any time node element encapsulated in an element of this type or an XLink reference to a remote time node element (where remote includes elements located elsewhere in the same document). Note that either the reference or the contained element must be given, but not both or none. TimeEdge is one dimensional temporal topology primitive, expresses a state in topological time. It has an orientation from its start toward the end, and its boundaries shall associate with two different time nodes. Type declaration of the element "TimeEdge". A time edge property can either be any time edge element encapsulated in an element of this type or an XLink reference to a remote time edge element (where remote includes elements located elsewhere in the same document). Note that either the reference or the contained element must be given, but not both or none. Feature succession is a semantic relationship derived from evaluation of observer, and Feature Substitution, Feature Division and Feature Fusion are defined as associations between previous features and next features in the temporal context. Successions shall be represented in either following two ways. * define a temporal topological complex element as a feature element * define an association same as temporal topological complex between features. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/topology.xsd ================================================ topology.xsd GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Substitution group branch for Topo Primitives, used by TopoPrimitiveArrayAssociationType Its optional co-boundary is a set of connected directedEdges. The orientation of one of these dirEdges is "+" if the Node is the "to" node of the Edge, and "-" if it is the "from" node. There is precisely one positively directed and one negatively directed node in the boundary of every edge. The negatively and positively directed nodes correspond to the start and end nodes respectively. The optional coboundary of an edge is a circular sequence of directed faces which are incident on this edge in document order. Faces which use a particular boundary edge in its positive orientation appear with positive orientation on the coboundary of the same edge. In the 2D case, the orientation of the face on the left of the edge is "+"; the orientation of the face on the right on its right is "-". An edge may optionally be realised by a 1-dimensional (curve) geometric primitive. . The topological boundary of a face consists of a set of directed edges. Note that all edges associated with a Face, including dangling and interior edges, appear in the boundary. Dangling and interior edges are each referenced by pairs of directedEdges with opposing orientations. The optional coboundary of a face is a pair of directed solids which are bounded by this face. If present, there is precisely one positively directed and one negatively directed solid in the coboundary of every face. The positively directed solid corresponds to the solid which lies in the direction of the positively directed normal to the face in any geometric realisation. A face may optionally be realised by a 2-dimensional (surface) geometric primitive. The topological boundary of a TopoSolid consists of a set of directed faces. Note that all faces associated with the TopoSolid, including dangling faces, appear in the boundary. The coboundary of a TopoSolid is empty and hence requires no representation. The intended use of TopoPoint is to appear within a point feature to express the structural and possibly geometric relationships of this point to other features via shared node definitions. Note the orientation assigned to the directedNode has no meaning in this context. It is preserved for symmetry with the types and elements which follow. The end Node of each directedEdge of a TopoCurveType is the start Node of the next directedEdge of the TopoCurveType in document order. The TopoCurve type and element represent a homogeneous topological expression, a list of directed edges, which if realised are isomorphic to a geometric curve primitive. The intended use of TopoCurve is to appear within a line feature instance to express the structural and geometric relationships of this line to other features via the shared edge definitions. The TopoSurface type and element represent a homogeneous topological expression, a set of directed faces, which if realised are isomorphic to a geometric surface primitive. The intended use of TopoSurface is to appear within a surface feature instance to express the structural and possibly geometric relationships of this surface to other features via the shared face definitions. The TopoVolume type and element represent a homogeneous topological expression, a set of directed TopoSolids, which if realised are isomorphic to a geometric solid primitive. The intended use of TopoVolume is to appear within a 3D solid feature instance to express the structural and geometric relationships of this solid to other features via the shared TopoSolid definitions. . Note the orientation assigned to the directedSolid has no meaning in three dimensions. It is preserved for symmetry with the preceding types and elements. This type represents a TP_Complex capable of holding topological primitives. Need schamatron test here that isMaximal attribute value is true This Property can be used to embed a TopoComplex in a feature collection. This type supports embedding topological primitives in a TopoComplex. This type supports embedding an array of topological primitives in a TopoComplex ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/units.xsd ================================================ Builds on gmlBase.xsd to encode units of measure (or uom), including definitions of units of measure and dictionaries of such definitions. GML 3.0 candidate schema, primary editor: Arliss Whiteside. Parts of this schema are based on Subclause 6.5.7 of ISO/CD 19103 Geographic information - Conceptual schema language, on Subclause A.5.2.2.3 of ISO/CD 19118 Geographic information - Encoding, and on most of OpenGIS Recommendation Paper OGC 02-007r4 Units of Measure Use and Definition Recommendations. GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Reference to a unit of measure definition that applies to all the numerical values described by the element containing this element. Notice that a complexType which needs to include the uom attribute can do so by extending this complexType. Alternately, this complexType can be used as a pattern for a new complexType. Reference to a unit of measure definition, usually within the same XML document but possibly outside the XML document which contains this reference. For a reference within the same XML document, the "#" symbol should be used, followed by a text abbreviation of the unit name. However, the "#" symbol may be optional, and still may be interpreted as a reference. Definition of a unit of measure (or uom). The definition includes a quantityType property, which indicates the phenomenon to which the units apply, and a catalogSymbol, which gives the short symbol used for this unit. This element is used when the relationship of this unit to other units or units systems is unknown. Definition of a unit of measure which is a base unit from the system of units. A base unit cannot be derived by combination of other base units within this system. Sometimes known as "fundamental unit". Definition of a unit of measure which is defined through algebraic combination of more primitive units, which are usually base units from a particular system of units. Derived units based directly on base units are usually preferred for quantities other than the base units or fundamental quantities within a system. If a derived unit is not the preferred unit, the ConventionalUnit element should be used instead. Definition of a unit of measure which is related to a preferred unit for this quantity type through a conversion formula. A method for deriving this unit by algebraic combination of more primitive units, may also be provided. Informal description of the phenomenon or type of quantity that is measured or observed. For example, "length", "angle", "time", "pressure", or "temperature". When the quantity is the result of an observation or measurement, this term is known as Observable Type or Measurand. For global understanding of a unit of measure, it is often possible to reference an item in a catalog of units, using a symbol in that catalog. The "codeSpace" attribute in "CodeType" identifies a namespace for the catalog symbol value, and might reference the catalog. The "string" value in "CodeType" contains the value of a symbol that is unique within this catalog namespace. This symbol often appears explicitly in the catalog, but it could be a combination of symbols using a specified algebra of units. For example, the symbol "cm" might indicate that it is the "m" symbol combined with the "c" prefix. Definition of one unit term for a derived unit of measure. This unit term references another unit of measure (uom) and provides an integer exponent applied to that unit in defining the compound unit. The exponent can be positive or negative, but not zero. This element is included when this unit has an accurate conversion to the preferred unit for this quantity type. This element is included when the correct definition of this unit is unknown, but this unit has a rough or inaccurate conversion to the preferred unit for this quantity type. Relation of a unit to the preferred unit for this quantity type, specified by an arithmetic conversion (scaling and/or offset). A preferred unit is either a base unit or a derived unit selected for all units of one quantity type. The mandatory attribute "uom" shall reference the preferred unit that this conversion applies to. The conversion is specified by one of two alternative elements: "factor" or "formula". Specification of the scale factor by which a value using this unit of measure can be multiplied to obtain the corresponding value using the preferred unit of measure. Specification of the formula by which a value using this unit of measure can be converted to obtain the corresponding value using the preferred unit of measure. Paremeters of a simple formula by which a value using this unit of measure can be converted to the corresponding value using the preferred unit of measure. The formula element contains elements a, b, c and d, whose values use the XML Schema type "double". These values are used in the formula y = (a + bx) / (c + dx), where x is a value using this unit, and y is the corresponding value using the preferred unit. The elements a and d are optional, and if values are not provided, those parameters are considered to be zero. If values are not provided for both a and d, the formula is equivalent to a fraction with numerator and denominator parameters. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/base/valueObjects.xsd ================================================ valueObjects.xsd GML conformant schema for Values in which the * scalar Value types and lists have their values recorded in simpleContent elements * complex Value types are built recursively GML is an OGC Standard. Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Utility choice group which unifies generic Values defined in this schema document with Geometry and Temporal objects and the Measures described above, so that any of these may be used within aggregate Values. A value from two-valued logic, using the XML Schema boolean type. An instance may take the values {true, false, 1, 0}. XML List based on XML Schema boolean type. An element of this type contains a space-separated list of boolean values {0,1,true,false} A term representing a classification. It has an optional XML attribute codeSpace, whose value is a URI which identifies a dictionary, codelist or authority for the term. A space-separated list of terms or nulls. A single XML attribute codeSpace may be provided, which authorises all the terms in the list. A numeric value with a scale. The content of the element is an amount using the XML Schema type double which permits decimal or scientific notation. An XML attribute uom (unit of measure) is required, whose value is a URI which identifies the definition of the scale or units by which the numeric value must be multiplied. A space separated list of amounts or nulls. The amounts use the XML Schema type double. A single XML attribute uom (unit of measure) is required, whose value is a URI which identifies the definition of the scale or units by which all the amounts in the list must be multiplied. An integer representing a frequency of occurrence. A space-separated list of integers or nulls. Aggregate value built from other Values using the Composite pattern. It contains zero or an arbitrary number of valueComponent elements, and zero or one valueComponents elements. It may be used for strongly coupled aggregates (vectors, tensors) or for arbitrary collections of values. Aggregate value built using the Composite pattern. A Value Array is used for homogeneous arrays of primitive and aggregate values. The member values may be scalars, composites, arrays or lists. ValueArray has the same content model as CompositeValue, but the member values must be homogeneous. The element declaration contains a Schematron constraint which expresses this restriction precisely. Since the members are homogeneous, the referenceSystem (uom, codeSpace) may be specified on the ValueArray itself and implicitly inherited by all the members if desired. Note that a_ScalarValueList is preferred for arrays of Scalar Values since this is a more efficient encoding. ValueArray may not carry both a reference to a codeSpace and a uom All components of must be of the same type All components of must be of the same type A Value Array is used for homogeneous arrays of primitive and aggregate values. _ScalarValueList is preferred for arrays of Scalar Values since this is more efficient. Since "choice" is not available for attribute groups, an external constraint (e.g. Schematron) would be required to enforce the selection of only one of these through schema validation Utility element to store a 2-point range of numeric values. If one member is a null, then this is a single ended interval. Restriction of list type to store a 2-point range of numeric values. If one member is a null, then this is a single ended interval. Utility element to store a 2-point range of ordinal values. If one member is a null, then this is a single ended interval. Restriction of list type to store a 2-point range of ordinal values. If one member is a null, then this is a single ended interval. Utility element to store a 2-point range of frequency values. If one member is a null, then this is a single ended interval. Restriction of list type to store a 2-point range of frequency values. If one member is a null, then this is a single ended interval. Element which refers to, or contains, a Value Element which refers to, or contains, a Value. This version is used in CompositeValues. GML property which refers to, or contains, a Value Element which refers to, or contains, a set of homogeneously typed Values. GML property which refers to, or contains, a set of homogeneously typed Values. Property whose content is a scalar value. Property whose content is a Boolean value. Property whose content is a Category. Property whose content is a Quantity. Property whose content is a Count. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/smil/smil20-language.xsd ================================================ ================================================ FILE: pycsw/core/schemas/ogc/gml/3.1.1/smil/smil20.xsd ================================================ ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/SchematronConstraints.xml ================================================ Schematron constraints for GML / ISO 19136 ValueArray may not carry both a reference to a codeSpace and a uom All components shall be of the same type All components shall be of the same type The presence of a dimension attribute implies the presence of the srsName attribute. The presence of an axisLabels attribute implies the presence of the srsName attribute. The presence of an uomLabels attribute implies the presence of the srsName attribute. The presence of an uomLabels attribute implies the presence of the axisLabels attribute and vice versa. All patches shall be gml:PolygonPatch elements or an element in the substitution group of gml:PolygonPatch. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future. All patches shall be gml:Triangle elements or an element in the substitution group of gml:PolygonPatch. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future. Property element may not carry both a reference to an object and contain an object. Property element shall either carry a reference to an object or contain an object. All values in the domain set shall be gml:MultiPoint elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future. All values in the domain set shall be gml:MultiCurve elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future. All values in the domain set shall be gml:MultiSurface elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future. All values in the domain set shall be gml:MultiSolid elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future. All values in the domain set shall be gml:Grid elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future. All values in the domain set shall be gml:RectifiedGrid elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/basicTypes.xsd ================================================ basicTypes.xsd See ISO/DIS 19136 8.2. W3C XML Schema provides a set of built-in "simple" types which define methods for representing values as literals without internal markup. These are described in W3C XML Schema Part 2:2001. Because GML is an XML encoding in which instances are described using XML Schema, these simple types shall be used as far as possible and practical for the representation of data types. W3C XML Schema also provides methods for defining - new simple types by restriction and combination of the built-in types, and - complex types, with simple content, but which also have XML attributes. In many places where a suitable built-in simple type is not available, simple content types derived using the XML Schema mechanisms are used for the representation of data types in GML. A set of these simple content types that are required by several GML components are defined in the basicTypes schema, as well as some elements based on them. These are primarily based around components needed to record amounts, counts, flags and terms, together with support for exceptions or null values. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . gml:NilReasonType defines a content model that allows recording of an explanation for a void value or other exception. gml:NilReasonType is a union of the following enumerated values: - inapplicable there is no value - missing the correct value is not readily available to the sender of this data. Furthermore, a correct value may not exist - template the value will be available later - unknown the correct value is not known to, and not computable by, the sender of this data. However, a correct value probably exists - withheld the value is not divulged - other:text other brief explanation, where text is a string of two or more characters with no included spaces and - anyURI which should refer to a resource which describes the reason for the exception A particular community may choose to assign more detailed semantics to the standard values provided. Alternatively, the URI method enables a specific or more complete explanation for the absence of a value to be provided elsewhere and indicated by-reference in an instance document. gml:NilReasonType is used as a member of a union in a number of simple content types where it is necessary to permit a value from the NilReasonType union as an alternative to the primary type. gml:SignType is a convenience type with values "+" (plus) and "-" (minus). Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. gml:CodeType is a generalized type to be used for a term, keyword or name. It adds a XML attribute codeSpace to a term, where the value of the codeSpace attribute (if present) shall indicate a dictionary, thesaurus, classification scheme, authority, or pattern for the term. gml:CodeWithAuthorityType requires that the codeSpace attribute is provided in an instance. gml:MeasureType supports recording an amount encoded as a value of XML Schema double, together with a units of measure indicated by an attribute uom, short for "units Of measure". The value of the uom attribute identifies a reference system for the amount, usually a ratio or interval scale. The simple type gml:UomIdentifer defines the syntax and value space of the unit of measure identifier. This type specifies a character string of length at least one, and restricted such that it must not contain any of the following characters: ":" (colon), " " (space), (newline), (carriage return), (tab). This allows values corresponding to familiar abbreviations, such as "kg", "m/s", etc. It is recommended that the symbol be an identifier for a unit of measure as specified in the "Unified Code of Units of Measure" (UCUM) (http://aurora.regenstrief.org/UCUM). This provides a set of symbols and a grammar for constructing identifiers for units of measure that are unique, and may be easily entered with a keyboard supporting the limited character set known as 7-bit ASCII. ISO 2955 formerly provided a specification with this scope, but was withdrawn in 2001. UCUM largely follows ISO 2955 with modifications to remove ambiguities and other problems. This type specifies a URI, restricted such that it must start with one of the following sequences: "#", "./", "../", or a string of characters followed by a ":". These patterns ensure that the most common URI forms are supported, including absolute and relative URIs and URIs that are simple fragment identifiers, but prohibits certain forms of relative URI that could be mistaken for unit of measure symbol . NOTE It is possible to re-write such a relative URI to conform to the restriction (e.g. "./m/s"). In an instance document, on elements of type gml:MeasureType the mandatory uom attribute shall carry a value corresponding to either - a conventional unit of measure symbol, - a link to a definition of a unit of measure that does not have a conventional symbol, or when it is desired to indicate a precise or variant definition. This type is deprecated for tuples with ordinate values that are numbers. CoordinatesType is a text string, intended to be used to record an array of tuples or coordinates. While it is not possible to enforce the internal structure of the string through schema validation, some optional attributes have been provided in previous versions of GML to support a description of the internal structure. These attributes are deprecated. The attributes were intended to be used as follows: Decimal symbol used for a decimal point (default="." a stop or period) cs symbol used to separate components within a tuple or coordinate string (default="," a comma) ts symbol used to separate tuples or coordinate strings (default=" " a space) Since it is based on the XML Schema string type, CoordinatesType may be used in the construction of tables of tuples or arrays of tuples, including ones that contain mixed text and numeric values. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. gml:CodeListType provides for lists of terms. The values in an instance element shall all be valid according to the rules of the dictionary, classification scheme, or authority identified by the value of its codeSpace attribute. gml:CodeOrNilReasonListType provides for lists of terms. The values in an instance element shall all be valid according to the rules of the dictionary, classification scheme, or authority identified by the value of its codeSpace attribute. An instance element may also include embedded values from NilReasonType. It is intended to be used in situations where a term or classification is expected, but the value may be absent for some reason. gml:MeasureListType provides for a list of quantities. gml:MeasureOrNilReasonListType provides for a list of quantities. An instance element may also include embedded values from NilReasonType. It is intended to be used in situations where a value is expected, but the value may be absent for some reason. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/coordinateOperations.xsd ================================================ coordinateOperations.xsd See ISO/DIS 19136 13.6. The spatial or temporal coordinate operations schema components can be divided into five logical parts, which define elements and types for XML encoding of the definitions of: - Multiple abstract coordinate operations - Multiple concrete types of coordinate operations, including Transformations and Conversions - Abstract and concrete parameter values and groups - Operation methods - Abstract and concrete operation parameters and groups These schema component encodes the Coordinate Operation package of the UML Model for ISO 19111 Clause 11. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . gml:AbstractCoordinateOperation is a mathematical operation on coordinates that transforms or converts coordinates to another coordinate reference system. Many but not all coordinate operations (from CRS A to CRS B) also uniquely define the inverse operation (from CRS B to CRS A). In some cases, the operation method algorithm for the inverse operation is the same as for the forward algorithm, but the signs of some operation parameter values shall be reversed. In other cases, different algorithms are required for the forward and inverse operations, but the same operation parameter values are used. If (some) entirely different parameter values are needed, a different coordinate operation shall be defined. The optional coordinateOperationAccuracy property elements provide estimates of the impact of this coordinate operation on point position accuracy. gml:operationVersion is the version of the coordinate transformation (i.e., instantiation due to the stochastic nature of the parameters). Mandatory when describing a transformation, and should not be supplied for a conversion. gml:coordinateOperationAccuracy is an association role to a DQ_PositionalAccuracy object as encoded in ISO/TS 19139, either referencing or containing the definition of that positional accuracy. That object contains an estimate of the impact of this coordinate operation on point accuracy. That is, it gives position error estimates for the target coordinates of this coordinate operation, assuming no errors in the source coordinates. gml:sourceCRS is an association role to the source CRS (coordinate reference system) of this coordinate operation. gml:targetCRS is an association role to the target CRS (coordinate reference system) of this coordinate operation. gml:CoordinateOperationPropertyType is a property type for association roles to a coordinate operation, either referencing or containing the definition of that coordinate operation. gml:AbstractSingleOperation is a single (not concatenated) coordinate operation. gml:SingleOperationPropertyType is a property type for association roles to a single operation, either referencing or containing the definition of that single operation. gm:AbstractGeneralConversion is an abstract operation on coordinates that does not include any change of datum. The best-known example of a coordinate conversion is a map projection. The parameters describing coordinate conversions are defined rather than empirically derived. Note that some conversions have no parameters. The operationVersion, sourceCRS, and targetCRS elements are omitted in a coordinate conversion. This abstract complex type is expected to be extended for well-known operation methods with many Conversion instances, in GML Application Schemas that define operation-method-specialized element names and contents. This conversion uses an operation method, usually with associated parameter values. However, operation methods and parameter values are directly associated with concrete subtypes, not with this abstract type. All concrete types derived from this type shall extend this type to include a "usesMethod" element that references the "OperationMethod" element. Similarly, all concrete types derived from this type shall extend this type to include zero or more elements each named "uses...Value" that each use the type of an element substitutable for the "AbstractGeneralParameterValue" element. gml:GeneralConversionPropertyType is a property type for association roles to a general conversion, either referencing or containing the definition of that conversion. gml:AbstractGeneralTransformation is an abstract operation on coordinates that usually includes a change of Datum. The parameters of a coordinate transformation are empirically derived from data containing the coordinates of a series of points in both coordinate reference systems. This computational process is usually "over-determined", allowing derivation of error (or accuracy) estimates for the transformation. Also, the stochastic nature of the parameters may result in multiple (different) versions of the same coordinate transformation. The operationVersion, sourceCRS, and targetCRS proeprty elements are mandatory in a coordinate transformation. This abstract complex type is expected to be extended for well-known operation methods with many Transformation instances, in Application Schemas that define operation-method-specialized value element names and contents. This transformation uses an operation method with associated parameter values. However, operation methods and parameter values are directly associated with concrete subtypes, not with this abstract type. All concrete types derived from this type shall extend this type to include a "usesMethod" element that references one "OperationMethod" element. Similarly, all concrete types derived from this type shall extend this type to include one or more elements each named "uses...Value" that each use the type of an element substitutable for the "AbstractGeneralParameterValue" element. gml:GeneralTransformationPropertyType is a property type for association roles to a general transformation, either referencing or containing the definition of that transformation. gml:ConcatenatedOperation is an ordered sequence of two or more coordinate operations. This sequence of operations is constrained by the requirement that the source coordinate reference system of step (n+1) must be the same as the target coordinate reference system of step (n). The source coordinate reference system of the first step and the target coordinate reference system of the last step are the source and target coordinate reference system associated with the concatenated operation. Instead of a forward operation, an inverse operation may be used for one or more of the operation steps mentioned above, if the inverse operation is uniquely defined by the forward operation. The gml:coordOperation property elements are an ordered sequence of associations to the two or more operations used by this concatenated operation. The AggregationAttributeGroup should be used to specify that the coordOperation associations are ordered. gml:coordOperation is an association role to a coordinate operation. gml:ConcatenatedOperationPropertyType is a property type for association roles to a concatenated operation, either referencing or containing the definition of that concatenated operation. gml:PassThroughOperation is a pass-through operation specifies that a subset of a coordinate tuple is subject to a specific coordinate operation. The modifiedCoordinate property elements are an ordered sequence of positive integers defining the positions in a coordinate tuple of the coordinates affected by this pass-through operation. The AggregationAttributeGroup should be used to specify that the modifiedCoordinate elements are ordered. gml:modifiedCoordinate is a positive integer defining a position in a coordinate tuple. gml:PassThroughOperationPropertyType is a property type for association roles to a pass through operation, either referencing or containing the definition of that pass through operation. gml:Conversion is a concrete operation on coordinates that does not include any change of Datum. The best-known example of a coordinate conversion is a map projection. The parameters describing coordinate conversions are defined rather than empirically derived. Note that some conversions have no parameters. This concrete complex type can be used without using a GML Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one Conversion instance. The usesValue property elements are an unordered list of composition associations to the set of parameter values used by this conversion operation. gml:method is an association role to the operation method used by a coordinate operation. gml:parameterValue is a composition association to a parameter value or group of parameter values used by a coordinate operation. gml:ConversionPropertyType is a property type for association roles to a concrete general-purpose conversion, either referencing or containing the definition of that conversion. gml:Transformation is a concrete object element derived from gml:GeneralTransformation (13.6.2.13). This concrete object can be used for all operation methods, without using a GML Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one Transformation instance. The parameterValue elements are an unordered list of composition associations to the set of parameter values used by this conversion operation. gml:TransformationPropertyType is a property type for association roles to a transformation, either referencing or containing the definition of that transformation. gml:AbstractGeneralParameterValue is an abstract parameter value or group of parameter values. This abstract complexType is expected to be extended and restricted for well-known operation methods with many instances, in Application Schemas that define operation-method-specialized element names and contents. Specific parameter value elements are directly contained in concrete subtypes, not in this abstract type. All concrete types derived from this type shall extend this type to include one "...Value" element with an appropriate type, which should be one of the element types allowed in the ParameterValueType. In addition, all derived concrete types shall extend this type to include a "operationParameter" property element that references one element substitutable for the "OperationParameter" object element. gml:AbstractGeneralParameterValuePropertyType is a property type for inline association roles to a parameter value or group of parameter values, always containing the values. gml:ParameterValue is a parameter value, an ordered sequence of values, or a reference to a file of parameter values. This concrete complex type may be used for operation methods without using an Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one instance. This complex type may be used, extended, or restricted for well-known operation methods, especially for methods with many instances. gml:value is a numeric value of an operation parameter, with its associated unit of measure. gml:stringValue is a character string value of an operation parameter. A string value does not have an associated unit of measure. gml:integerValue is a positive integer value of an operation parameter, usually used for a count. An integer value does not have an associated unit of measure. gml:booleanValue is a boolean value of an operation parameter. A Boolean value does not have an associated unit of measure. gml:valueList is an ordered sequence of two or more numeric values of an operation parameter list, where each value has the same associated unit of measure. An element of this type contains a space-separated sequence of double values. gml:integerValueList is an ordered sequence of two or more integer values of an operation parameter list, usually used for counts. These integer values do not have an associated unit of measure. An element of this type contains a space-separated sequence of integer values. gml:valueFile is a reference to a file or a part of a file containing one or more parameter values, each numeric value with its associated unit of measure. When referencing a part of a file, that file shall contain multiple identified parts, such as an XML encoded document. Furthermore, the referenced file or part of a file may reference another part of the same or different files, as allowed in XML documents. gml:operationParameter is an association role to the operation parameter of which this is a value. gml:ParameterValueGroup is a group of related parameter values. The same group can be repeated more than once in a Conversion, Transformation, or higher level ParameterValueGroup, if those instances contain different values of one or more parameterValues which suitably distinquish among those groups. This concrete complex type can be used for operation methods without using an Application Schema that defines operation-method-specialized element names and contents. This complex type may be used, extended, or restricted for well-known operation methods, especially for methods with only one instance. The parameterValue elements are an unordered set of composition association roles to the parameter values and groups of values included in this group. gml:group is an association role to the operation parameter group for which this element provides parameter values. gml:OperationMethod is a method (algorithm or procedure) used to perform a coordinate operation. Most operation methods use a number of operation parameters, although some coordinate conversions use none. Each coordinate operation using the method assigns values to these parameters. The parameter elements are an unordered list of associations to the set of operation parameters and parameter groups used by this operation method. gml:formulaCitation provides a reference to a publication giving the formula(s) or procedure used by an coordinate operation method. gml:formula Formula(s) or procedure used by an operation method. The use of the codespace attribite has been deprecated. The property value shall be a character string. gml:sourceDimensions is the number of dimensions in the source CRS of this operation method. gml:targetDimensions is the number of dimensions in the target CRS of this operation method. gml:parameter is an association to an operation parameter or parameter group. gml:OperationMethodPropertyType is a property type for association roles to a concrete general-purpose operation method, either referencing or containing the definition of that method. gml:GeneralOperationParameter is the abstract definition of a parameter or group of parameters used by an operation method. gml:minimumOccurs is the minimum number of times that values for this parameter group or parameter are required. If this attribute is omitted, the minimum number shall be one. gml:AbstractGeneralOperationParameterPropertyType is a property type for association roles to an operation parameter or group, either referencing or containing the definition of that parameter or group. gml:OperationParameter is the definition of a parameter used by an operation method. Most parameter values are numeric, but other types of parameter values are possible. This complex type is expected to be used or extended for all operation methods, without defining operation-method-specialized element names. gml:OperationParameterPropertyType is a property type for association roles to an operation parameter, either referencing or containing the definition of that parameter. gml:OperationParameterGroup is the definition of a group of parameters used by an operation method. This complex type is expected to be used or extended for all applicable operation methods, without defining operation-method-specialized element names. The generalOperationParameter elements are an unordered list of associations to the set of operation parameters that are members of this group. gml:maximumOccurs is the maximum number of times that values for this parameter group may be included. If this attribute is omitted, the maximum number shall be one. gml:OperationParameterPropertyType is a property type for association roles to an operation parameter group, either referencing or containing the definition of that parameter group. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/coordinateReferenceSystems.xsd ================================================ coordinateReferenceSystems.xsd See ISO/DIS 19136 13.3. The spatial-temporal coordinate reference systems schema components are divided into two logical parts. One part defines elements and types for XML encoding of abstract coordinate reference systems definitions. The larger part defines specialized constructs for XML encoding of definitions of the multiple concrete types of spatial-temporal coordinate reference systems. These schema components encode the Coordinate Reference System packages of the UML Models of ISO 19111 Clause 8 and ISO/DIS 19136 D.3.10, with the exception of the abstract "SC_CRS" class. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . gml:AbstractSingleCRS implements a coordinate reference system consisting of one coordinate system and one datum (as opposed to a Compound CRS). gml:SingleCRSPropertyType is a property type for association roles to a single coordinate reference system, either referencing or containing the definition of that coordinate reference system. gml:AbstractGeneralDerivedCRS is a coordinate reference system that is defined by its coordinate conversion from another coordinate reference system. This abstract complex type shall not be used, extended, or restricted, in a GML Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. gml:conversion is an association role to the coordinate conversion used to define the derived CRS. gml:CompundCRS is a coordinate reference system describing the position of points through two or more independent coordinate reference systems. It is associated with a non-repeating sequence of two or more instances of SingleCRS. The gml:componentReferenceSystem elements are an ordered sequence of associations to all the component coordinate reference systems included in this compound coordinate reference system. The gml:AggregationAttributeGroup should be used to specify that the gml:componentReferenceSystem properties are ordered. gml:CompoundCRSPropertyType is a property type for association roles to a compound coordinate reference system, either referencing or containing the definition of that reference system. gml:GeodeticCRS is a coordinate reference system based on a geodetic datum. gml:ellipsoidalCS is an association role to the ellipsoidal coordinate system used by this CRS. gml:cartesianCS is an association role to the Cartesian coordinate system used by this CRS. gml:sphericalCS is an association role to the spherical coordinate system used by this CRS. gml:geodeticDatum is an association role to the geodetic datum used by this CRS. gml:GeodeticCRSPropertyType is a property type for association roles to a geodetic coordinate reference system, either referencing or containing the definition of that reference system. gml:VerticalCRS is a 1D coordinate reference system used for recording heights or depths. Vertical CRSs make use of the direction of gravity to define the concept of height or depth, but the relationship with gravity may not be straightforward. By implication, ellipsoidal heights (h) cannot be captured in a vertical coordinate reference system. Ellipsoidal heights cannot exist independently, but only as an inseparable part of a 3D coordinate tuple defined in a geographic 3D coordinate reference system. gml:verticalCS is an association role to the vertical coordinate system used by this CRS. gml:verticalDatum is an association role to the vertical datum used by this CRS. gml:VerticalCRSPropertyType is a property type for association roles to a vertical coordinate reference system, either referencing or containing the definition of that reference system. gml:ProjectedCRS is a 2D coordinate reference system used to approximate the shape of the earth on a planar surface, but in such a way that the distortion that is inherent to the approximation is carefully controlled and known. Distortion correction is commonly applied to calculated bearings and distances to produce values that are a close match to actual field values. gml:baseGeodeticCRS is an association role to the geodetic coordinate reference system used by this projected CRS. gml:ProjectedCRSPropertyType is a property type for association roles to a projected coordinate reference system, either referencing or containing the definition of that reference system. gml:DerivedCRS is a single coordinate reference system that is defined by its coordinate conversion from another single coordinate reference system known as the base CRS. The base CRS can be a projected coordinate reference system, if this DerivedCRS is used for a georectified grid coverage as described in ISO 19123, Clause 8. gml:baseCRS is an association role to the coordinate reference system used by this derived CRS. The gml:derivedCRSType property describes the type of a derived coordinate reference system. The required codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property. An association role to the coordinate system used by this CRS. gml:DerivedCRSPropertyType is a property type for association roles to a non-projected derived coordinate reference system, either referencing or containing the definition of that reference system. gml:EngineeringCRS is a contextually local coordinate reference system which can be divided into two broad categories: - earth-fixed systems applied to engineering activities on or near the surface of the earth; - CRSs on moving platforms such as road vehicles, vessels, aircraft, or spacecraft, see ISO 19111 8.3. deprecated gml:cylindricalCS is an association role to the cylindrical coordinate system used by this CRS. gml:linearCS is an association role to the linear coordinate system used by this CRS. gml:polarCS is an association role to the polar coordinate system used by this CRS. gml:userDefinedCS is an association role to the user defined coordinate system used by this CRS. gml:engineeringDatum is an association role to the engineering datum used by this CRS. gml:EngineeringCRSPropertyType is a property type for association roles to an engineering coordinate reference system, either referencing or containing the definition of that reference system. gml:ImageCRS is an engineering coordinate reference system applied to locations in images. Image coordinate reference systems are treated as a separate sub-type because the definition of the associated image datum contains two attributes not relevant to other engineering datums. gml:affineCS is an association role to the affine coordinate system used by this CRS. gml:imageDatum is an association role to the image datum used by this CRS. gml:ImageCRSPropertyType is a property type for association roles to an image coordinate reference system, either referencing or containing the definition of that reference system. gml:TemporalCRS is a 1D coordinate reference system used for the recording of time. gml:timeCS is an association role to the time coordinate system used by this CRS. gml:temporalDatum is an association role to the temporal datum used by this CRS. gml:TemporalCRSPropertyType is a property type for association roles to a temporal coordinate reference system, either referencing or containing the definition of that reference system. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/coordinateSystems.xsd ================================================ coordinateSystems.xsd See ISO/DIS 19136 13.4. The coordinate systems schema components can be divded into three logical parts, which define elements and types for XML encoding of the definitions of: - Coordinate system axes - Abstract coordinate system - Multiple concrete types of spatial-temporal coordinate systems These schema components encode the Coordinate System packages of the UML Models of ISO 19111 Clause 9 and ISO/DIS 19136 D.3.10. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . gml:CoordinateSystemAxis is a definition of a coordinate system axis. The uom attribute provides an identifier of the unit of measure used for this coordinate system axis. The value of this coordinate in a coordinate tuple shall be recorded using this unit of measure, whenever those coordinates use a coordinate reference system that uses a coordinate system that uses this axis. gml:axisAbbrev is the abbreviation used for this coordinate system axis; this abbreviation is also used to identify the coordinates in the coordinate tuple. The codeSpace attribute may reference a source of more information on a set of standardized abbreviations, or on this abbreviation. gml:axisDirection is the direction of this coordinate system axis (or in the case of Cartesian projected coordinates, the direction of this coordinate system axis at the origin). Within any set of coordinate system axes, only one of each pair of terms may be used. For earth-fixed CRSs, this direction is often approximate and intended to provide a human interpretable meaning to the axis. When a geodetic datum is used, the precise directions of the axes may therefore vary slightly from this approximate direction. The codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property. The gml:minimumValue and gml:maximumValue properties allow the specification of minimum and maximum value normally allowed for this axis, in the unit of measure for the axis. For a continuous angular axis such as longitude, the values wrap-around at this value. Also, values beyond this minimum/maximum can be used for specified purposes, such as in a bounding box. A value of minus infinity shall be allowed for the gml:minimumValue element, a value of plus infiniy for the gml:maximumValue element. If these elements are omitted, the value is unspecified. The gml:minimumValue and gml:maximumValue properties allow the specification of minimum and maximum value normally allowed for this axis, in the unit of measure for the axis. For a continuous angular axis such as longitude, the values wrap-around at this value. Also, values beyond this minimum/maximum can be used for specified purposes, such as in a bounding box. A value of minus infinity shall be allowed for the gml:minimumValue element, a value of plus infiniy for the gml:maximumValue element. If these elements are omitted, the value is unspecified. gml:rangeMeaning describes the meaning of axis value range specified by gml:minimumValue and gml:maximumValue. This element shall be omitted when both gml:minimumValue and gml:maximumValue are omitted. This element should be included when gml:minimumValue and/or gml:maximumValue are included. If this element is omitted when the gml:minimumValue and/or gml:maximumValue are included, the meaning is unspecified. The codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property. gml:CoordinateSystemAxisPropertyType is a property type for association roles to a coordinate system axis, either referencing or containing the definition of that axis. gml:AbstractCoordinateSystem is a coordinate system (CS) is the non-repeating sequence of coordinate system axes that spans a given coordinate space. A CS is derived from a set of mathematical rules for specifying how coordinates in a given space are to be assigned to points. The coordinate values in a coordinate tuple shall be recorded in the order in which the coordinate system axes associations are recorded. This abstract complex type shall not be used, extended, or restricted, in an Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. The gml:axis property is an association role (ordered sequence) to the coordinate system axes included in this coordinate system. The coordinate values in a coordinate tuple shall be recorded in the order in which the coordinate system axes associations are recorded, whenever those coordinates use a coordinate reference system that uses this coordinate system. The gml:AggregationAttributeGroup should be used to specify that the axis objects are ordered. gml:CoordinateSystemPropertyType is a property type for association roles to a coordinate system, either referencing or containing the definition of that coordinate system. gml:EllipsoidalCS is a two- or three-dimensional coordinate system in which position is specified by geodetic latitude, geodetic longitude, and (in the three-dimensional case) ellipsoidal height. An EllipsoidalCS shall have two or three gml:axis property elements; the number of associations shall equal the dimension of the CS. gml:EllipsoidalCSPropertyType is a property type for association roles to an ellipsoidal coordinate system, either referencing or containing the definition of that coordinate system. gml:CartesianCS is a 1-, 2-, or 3-dimensional coordinate system. In the 1-dimensional case, it contains a single straight coordinate axis. In the 2- and 3-dimensional cases gives the position of points relative to orthogonal straight axes. In the multi-dimensional case, all axes shall have the same length unit of measure. A CartesianCS shall have one, two, or three gml:axis property elements. gml:CartesianCSPropertyType is a property type for association roles to a Cartesian coordinate system, either referencing or containing the definition of that coordinate system. gml:VerticalCS is a one-dimensional coordinate system used to record the heights or depths of points. Such a coordinate system is usually dependent on the Earth's gravity field, perhaps loosely as when atmospheric pressure is the basis for the vertical coordinate system axis. A VerticalCS shall have one gml:axis property element. gml:VerticalCSPropertyType is a property type for association roles to a vertical coordinate system, either referencing or containing the definition of that coordinate system. gml:TimeCS is a one-dimensional coordinate system containing a time axis, used to describe the temporal position of a point in the specified time units from a specified time origin. A TimeCS shall have one gml:axis property element. gml:TimeCSPropertyType is a property type for association roles to a time coordinate system, either referencing or containing the definition of that coordinate system. gml:LinearCS is a one-dimensional coordinate system that consists of the points that lie on the single axis described. The associated coordinate is the distance – with or without offset – from the specified datum to the point along the axis. A LinearCS shall have one gml:axis property element. gml:LinearCSPropertyType is a property type for association roles to a linear coordinate system, either referencing or containing the definition of that coordinate system. gml:UserDefinedCS is a two- or three-dimensional coordinate system that consists of any combination of coordinate axes not covered by any other coordinate system type. A UserDefinedCS shall have two or three gml:axis property elements; the number of property elements shall equal the dimension of the CS. gml:UserDefinedCSPropertyType is a property type for association roles to a user-defined coordinate system, either referencing or containing the definition of that coordinate system. gml:SphericalCS is a three-dimensional coordinate system with one distance measured from the origin and two angular coordinates. A SphericalCS shall have three gml:axis property elements. gml:SphericalCSPropertyType is property type for association roles to a spherical coordinate system, either referencing or containing the definition of that coordinate system. gml:PolarCS ia s two-dimensional coordinate system in which position is specified by the distance from the origin and the angle between the line from the origin to a point and a reference direction. A PolarCS shall have two gml:axis property elements. gml:PolarCSPropertyType is a property type for association roles to a polar coordinate system, either referencing or containing the definition of that coordinate system. gml:CylindricalCS is a three-dimensional coordinate system consisting of a polar coordinate system extended by a straight coordinate axis perpendicular to the plane spanned by the polar coordinate system. A CylindricalCS shall have three gml:axis property elements. gml:CylindricalCSPropertyType is a property type for association roles to a cylindrical coordinate system, either referencing or containing the definition of that coordinate system. gml:AffineCS is a two- or three-dimensional coordinate system with straight axes that are not necessarily orthogonal. An AffineCS shall have two or three gml:axis property elements; the number of property elements shall equal the dimension of the CS. gml:AffineCSPropertyType is a property type for association roles to an affine coordinate system, either referencing or containing the definition of that coordinate system. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/coverage.xsd ================================================ coverage.xsd See ISO/DIS 19136 20.3. A coverage incorporates a mapping from a spatiotemporal domain to a range set, the latter providing the set in which the attribute values live. The range set may be an arbitrary set including discrete lists, integer or floating point ranges, and multi-dimensional vector spaces. A coverage can be viewed as the graph of the coverage function f:A à B, that is as the set of ordered pairs {(x, f(x)) | where x is in A}. This view is especially applicable to the GML encoding of a coverage. In the case of a discrete coverage, the domain set A is partitioned into a collection of subsets (typically a disjoint collection) A = UAi and the function f is constant on each Ai. For a spatial domain, the Ai are geometry elements, hence the coverage can be viewed as a collection of (geometry,value) pairs, where the value is an element of the range set. If the spatial domain A is a topological space then the coverage can be viewed as a collection of (topology,value) pairs, where the topology element in the pair is a topological n-chain (in GML terms this is a gml:TopoPoint, gml:TopoCurve, gml:TopoSurface or gml:TopoSolid). A coverage is implemented as a GML feature. We can thus speak of a "temperature distribution feature", or a "remotely sensed image feature", or a "soil distribution feature". As is the case for any GML object, a coverage object may also be the value of a property of a feature. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The base type for coverages is gml:AbstractCoverageType. The basic elements of a coverage can be seen in this content model: the coverage contains gml:domainSet and gml:rangeSet properties. The gml:domainSet property describes the domain of the coverage and the gml:rangeSet property describes the range of the coverage. This element serves as the head of a substitution group which may contain any coverage whose type is derived from gml:AbstractCoverageType. It may act as a variable in the definition of content models where it is required to permit any coverage to be valid. A discrete coverage consists of a domain set, range set and optionally a coverage function. The domain set consists of either spatial or temporal geometry objects, finite in number. The range set is comprised of a finite number of attribute values each of which is associated to every direct position within any single spatiotemporal object in the domain. In other words, the range values are constant on each spatiotemporal object in the domain. This coverage function maps each element from the coverage domain to an element in its range. The coverageFunction element describes the mapping function. This element serves as the head of a substitution group which may contain any discrete coverage whose type is derived from gml:DiscreteCoverageType. A continuous coverage as defined in ISO 19123 is a coverage that can return different values for the same feature attribute at different direct positions within a single spatiotemporal object in its spatiotemporal domain. The base type for continuous coverages is AbstractContinuousCoverageType. The coverageFunction element describes the mapping function. The abstract element gml:AbstractContinuousCoverage serves as the head of a substitution group which may contain any continuous coverage whose type is derived from gml:AbstractContinuousCoverageType. The gml:domainSet property element describes the spatio-temporal region of interest, within which the coverage is defined. Its content model is given by gml:DomainSetType. The value of the domain is thus a choice between a gml:AbstractGeometry and a gml:AbstractTimeObject. In the instance these abstract elements will normally be substituted by a geometry complex or temporal complex, to represent spatial coverages and time-series, respectively. The presence of the gml:AssociationAttributeGroup means that domainSet follows the usual GML property model and may use the xlink:href attribute to point to the domain, as an alternative to describing the domain inline. Ownership semantics may be provided using the gml:OwnershipAttributeGroup. The gml:rangeSet property element contains the values of the coverage (sometimes called the attribute values). Its content model is given by gml:RangeSetType. This content model supports a structural description of the range. The semantic information describing the range set is embedded using a uniform method, as part of the explicit values, or as a template value accompanying the representation using gml:DataBlock and gml:File. The values from each component (or "band") in the range may be encoded within a gml:ValueArray element or a concrete member of the gml:AbstractScalarValueList substitution group . Use of these elements satisfies the value-type homogeneity requirement. gml:DataBlock describes the Range as a block of text encoded values similar to a Common Separated Value (CSV) representation. The range set parameterization is described by the property gml:rangeParameters. gml:CoordinatesType consists of a list of coordinate tuples, with each coordinate tuple separated by the ts or tuple separator (whitespace), and each coordinate in the tuple by the cs or coordinate separator (comma). The gml:tupleList encoding is effectively "band-interleaved". gml:doubleOrNilReasonList consists of a list of gml:doubleOrNilReason values, each separated by a whitespace. The gml:doubleOrNilReason values are grouped into tuples where the dimension of each tuple in the list is equal to the number of range parameters. for efficiency reasons, GML also provides a means of encoding the range set in an arbitrary external encoding, such as a binary file. This encoding may be "well-known" but this is not required. This mode uses the gml:File element. The values of the coverage (attribute values in the range set) are transmitted in a external file that is referenced from the XML structure described by gml:FileType. The external file is referenced by the gml:fileReference property that is an anyURI (the gml:fileName property has been deprecated). This means that the external file may be located remotely from the referencing GML instance. The gml:compression property points to a definition of a compression algorithm through an anyURI. This may be a retrievable, computable definition or simply a reference to an unambiguous name for the compression method. The gml:mimeType property points to a definition of the file mime type. The gml:fileStructure property is defined by a codelist. Note further that all values shall be enclosed in a single file. Multi-file structures for values are not supported in GML. The semantics of the range set is described as above using the gml:rangeParameters property. Note that if any compression algorithm is applied, the structure above applies only to the pre-compression or post-decompression structure of the file. Note that the fields within a record match the gml:valueComponents of the gml:CompositeValue in document order. deprecated The gml:coverageFunction property describes the mapping function from the domain to the range of the coverage. The value of the CoverageFunction is one of gml:CoverageMappingRule and gml:GridFunction. If the gml:coverageFunction property is omitted for a gridded coverage (including rectified gridded coverages) the gml:startPoint is assumed to be the value of the gml:low property in the gml:Grid geometry, and the gml:sequenceRule is assumed to be linear and the gml:axisOrder property is assumed to be "+1 +2". gml:CoverageMappingRule provides a formal or informal description of the coverage function. The mapping rule may be defined as an in-line string (gml:ruleDefinition) or via a remote reference through xlink:href (gml:ruleReference). If no rule name is specified, the default is 'Linear' with respect to members of the domain in document order. gml:GridFunction provides an explicit mapping rule for grid geometries, i.e. the domain shall be a geometry of type grid. It describes the mapping of grid posts (discrete point grid coverage) or grid cells (discrete surface coverage) to the values in the range set. The gml:startPoint is the index position of a point in the grid that is mapped to the first point in the range set (this is also the index position of the first grid post). If the gml:startPoint property is omitted the gml:startPoint is assumed to be equal to the value of gml:low in the gml:Grid geometry. Subsequent points in the mapping are determined by the value of the gml:sequenceRule. The gml:SequenceRuleType is derived from the gml:SequenceRuleEnumeration through the addition of an axisOrder attribute. The gml:SequenceRuleEnumeration is an enumerated type. The rule names are defined in ISO 19123. If no rule name is specified the default is "Linear". deprecated The different values in a gml:AxisDirectionList indicate the incrementation order to be used on all axes of the grid. Each axis shall be mentioned once and only once. The value of a gml:AxisDirection indicates the incrementation order to be used on an axis of the grid. In a gml:MultiPointCoverage the domain set is a gml:MultiPoint, that is a collection of arbitrarily distributed geometric points. The content model is identical with gml:DiscreteCoverageType, but that gml:domainSet shall have values gml:MultiPoint. In a gml:MultiPointCoverage the mapping from the domain to the range is straightforward. - For gml:DataBlock encodings the points of the gml:MultiPoint are mapped in document order to the tuples of the data block. - For gml:CompositeValue encodings the points of the gml:MultiPoint are mapped to the members of the composite value in document order. - For gml:File encodings the points of the gml:MultiPoint are mapped to the records of the file in sequential order. In a gml:MultiCurveCoverage the domain is partioned into a collection of curves comprising a gml:MultiCurve. The coverage function then maps each curve in the collection to a value in the range set. The content model is identical with gml:DiscreteCoverageType, but that gml:domainSet shall have values gml:MultiCurve. In a gml:MultiCurveCoverage the mapping from the domain to the range is straightforward. - For gml:DataBlock encodings the curves of the gml:MultiCurve are mapped in document order to the tuples of the data block. - For gml:CompositeValue encodings the curves of the gml:MultiCurve are mapped to the members of the composite value in document order. - For gml:File encodings the curves of the gml:MultiCurve are mapped to the records of the file in sequential order. In a gml:MultiSurfaceCoverage the domain is partioned into a collection of surfaces comprising a gml:MultiSurface. The coverage function than maps each surface in the collection to a value in the range set. The content model is identical with gml:DiscreteCoverageType, but that gml:domainSet shall have values gml:MultiSurface. In a gml:MultiSurfaceCoverage the mapping from the domain to the range is straightforward. - For gml:DataBlock encodings the surfaces of the gml:MultiSurface are mapped in document order to the tuples of the data block. - For gml:CompositeValue encodings the surfaces of the gml:MultiSurface are mapped to the members of the composite value in document order. - For gml:File encodings the surfaces of the gml:MultiSurface are mapped to the records of the file in sequential order. In a gml:MultiSolidCoverage the domain is partioned into a collection of solids comprising a gml:MultiSolid. The coverage function than maps each solid in the collection to a value in the range set. The content model is identical with gml:DiscreteCoverageType, but that gml:domainSet shall have values gml:MultiSolid. In a gml:MultiSolidCoverage the mapping from the domain to the range is straightforward. - For gml:DataBlock encodings the solids of the gml:MultiSolid are mapped in document order to the tuples of the data block. - For gml:CompositeValue encodings the solids of the gml:MultiSolid are mapped to the members of the composite value in document order. - For gml:File encodings the solids of the gml:MultiSolid are mapped to the records of the file in sequential order. A gml:GriddedCoverage is a discrete point coverage in which the domain set is a geometric grid of points. Note that this is the same as the gml:MultiPointCoverage except that we have a gml:Grid to describe the domain. The simple gridded coverage is not geometrically referenced and hence no geometric positions are assignable to the points in the grid. Such geometric positioning is introduced in the gml:RectifiedGridCoverage. The gml:RectifiedGridCoverage is a discrete point coverage based on a rectified grid. It is similar to the grid coverage except that the points of the grid are geometrically referenced. The rectified grid coverage has a domain that is a gml:RectifiedGrid geometry. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/datums.xsd ================================================ datums.xsd See ISO/DIS 19136 13.5 The datums schema components can be divided into three logical parts, which define elements and types for XML encoding of the definitions of: - Abstract datum - Geodetic datums, including ellipsoid and prime meridian - Multiple other concrete types of spatial or temporal datums These schema components encode the Datum packages of the UML Models of ISO 19111 Clause 10 and ISO/DIS 19136 D.3.10. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . A gml:AbstractDatum specifies the relationship of a coordinate system to the earth, thus creating a coordinate reference system. A datum uses a parameter or set of parameters that determine the location of the origin of the coordinate reference system. Each datum subtype may be associated with only specific types of coordinate systems. This abstract complex type shall not be used, extended, or restricted, in a GML Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. gml:anchorDefinition is a description, possibly including coordinates, of the definition used to anchor the datum to the Earth. Also known as the "origin", especially for engineering and image datums. The codeSpace attribute may be used to reference a source of more detailed on this point or surface, or on a set of such descriptions. - For a geodetic datum, this point is also known as the fundamental point, which is traditionally the point where the relationship between geoid and ellipsoid is defined. In some cases, the "fundamental point" may consist of a number of points. In those cases, the parameters defining the geoid/ellipsoid relationship have been averaged for these points, and the averages adopted as the datum definition. - For an engineering datum, the anchor definition may be a physical point, or it may be a point with defined coordinates in another CRS.may - For an image datum, the anchor definition is usually either the centre of the image or the corner of the image. - For a temporal datum, this attribute is not defined. Instead of the anchor definition, a temporal datum carries a separate time origin of type DateTime. gml:realizationEpoch is the time after which this datum definition is valid. See ISO 19111 Table 32 for details. gml:DatumPropertyType is a property type for association roles to a datum, either referencing or containing the definition of that datum. gml:GeodeticDatum is a geodetic datum defines the precise location and orientation in 3-dimensional space of a defined ellipsoid (or sphere), or of a Cartesian coordinate system centered in this ellipsoid (or sphere). gml:primeMeridian is an association role to the prime meridian used by this geodetic datum. gml:ellipsoid is an association role to the ellipsoid used by this geodetic datum. gml:GeodeticDatumPropertyType is a property type for association roles to a geodetic datum, either referencing or containing the definition of that datum. A gml:Ellipsoid is a geometric figure that may be used to describe the approximate shape of the earth. In mathematical terms, it is a surface formed by the rotation of an ellipse about its minor axis. gml:semiMajorAxis specifies the length of the semi-major axis of the ellipsoid, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a length, such as metres or feet. gml:secondDefiningParameter is a property containing the definition of the second parameter that defines the shape of an ellipsoid. An ellipsoid requires two defining parameters: semi-major axis and inverse flattening or semi-major axis and semi-minor axis. When the reference body is a sphere rather than an ellipsoid, only a single defining parameter is required, namely the radius of the sphere; in that case, the semi-major axis "degenerates" into the radius of the sphere. The inverseFlattening element contains the inverse flattening value of the ellipsoid. This value is a scale factor (or ratio). It uses gml:LengthType with the restriction that the unit of measure referenced by the uom attribute must be suitable for a scale factor, such as percent, permil, or parts-per-million. The semiMinorAxis element contains the length of the semi-minor axis of the ellipsoid. When the isSphere element is included, the ellipsoid is degenerate and is actually a sphere. The sphere is completely defined by the semi-major axis, which is the radius of the sphere. gml:EllipsoidPropertyType is a property type for association roles to an ellipsoid, either referencing or containing the definition of that ellipsoid. A gml:PrimeMeridian defines the origin from which longitude values are determined. The default value for the prime meridian gml:identifier value is "Greenwich". gml:greenwichLongitude is the longitude of the prime meridian measured from the Greenwich meridian, positive eastward. If the value of the prime meridian "name" is "Greenwich" then the value of greenwichLongitude shall be 0 degrees. gml:PrimeMeridianPropertyType is a property type for association roles to a prime meridian, either referencing or containing the definition of that meridian. gml:EngineeringDatum defines the origin of an engineering coordinate reference system, and is used in a region around that origin. This origin may be fixed with respect to the earth (such as a defined point at a construction site), or be a defined point on a moving vehicle (such as on a ship or satellite). gml:EngineeringDatumPropertyType is a property type for association roles to an engineering datum, either referencing or containing the definition of that datum. gml:ImageDatum defines the origin of an image coordinate reference system, and is used in a local context only. For an image datum, the anchor definition is usually either the centre of the image or the corner of the image. For more information, see ISO 19111 B.3.5. gml:pixelInCell is a specification of the way an image grid is associated with the image data attributes. The required codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property. gml:ImageDatumPropertyType is a property type for association roles to an image datum, either referencing or containing the definition of that datum. gml:VerticalDatum is a textual description and/or a set of parameters identifying a particular reference level surface used as a zero-height surface, including its position with respect to the Earth for any of the height types recognized by this International Standard. gml:VerticalDatumPropertyType is property type for association roles to a vertical datum, either referencing or containing the definition of that datum. A gml:TemporalDatum defines the origin of a Temporal Reference System. This type omits the "anchorDefinition" and "realizationEpoch" elements and adds the "origin" element with the dateTime type. The TemporalDatumBaseType partially defines the origin of a temporal coordinate reference system. This type restricts the AbstractDatumType to remove the "anchorDefinition" and "realizationEpoch" elements. gml:origin is the date and time origin of this temporal datum. gml:TemporalDatumPropertyType is a property type for association roles to a temporal datum, either referencing or containing the definition of that datum. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/defaultStyle.xsd ================================================ defaultStyle.xsd GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Top-level property. Used in application schemas to "attach" the styling information to GML data. The link between the data and the style should be established through this property only. [complexType of] Top-level property. Used in application schemas to "attach" the styling information to GML data. The link between the data and the style should be established through this property only. The value of the top-level property. It is an abstract element. Used as the head element of the substitution group for extensibility purposes. [complexType of] The value of the top-level property. It is an abstract element. Used as the head element of the substitution group for extensibility purposes. Predefined concrete value of the top-level property. Encapsulates all other styling information. [complexType of] Predefined concrete value of the top-level property. Encapsulates all other styling information. The style descriptor for features. [complexType of] The style descriptor for features. Used to specify the grammar of the feature query mechanism. Base complex type for geometry, topology, label and graph styles. The style descriptor for geometries of a feature. [complexType of] The style descriptor for geometries of a feature. deprecated Deprecated in GML version 3.1.0. Use symbol with inline content instead. The style descriptor for topologies of a feature. Describes individual topology elements styles. [complexType of] The style descriptor for topologies of a feature. Describes individual topology elements styles. deprecated Deprecated in GML version 3.1.0. Use symbol with inline content instead. The style descriptor for labels of a feature, geometry or topology. [complexType of] The style descriptor for labels of a feature, geometry or topology. The style descriptor for a graph consisting of a number of features. Describes graph-specific style attributes. [complexType of] The style descriptor for a graph consisting of a number of features. Describes graph-specific style attributes. The symbol property. Extends the gml:AssociationType to allow for remote referencing of symbols. [complexType of] The symbol property. Allows for remote referencing of symbols. Used to specify the type of the symbol used. Label is mixed -- composed of text and XPath expressions used to extract the useful information from the feature. Defines the geometric transformation of entities. There is no particular grammar defined for this value. Used to vary individual graphic parameters and attributes of the style, symbol or text. Graph-specific styling property. Graph-specific styling property. Graph-specific styling property. Graph-specific styling property. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/deprecatedTypes.xsd ================================================ deprecatedTypes.xsd All global schema components that are part of the GML schema, but were deprecated. See Annex I. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/dictionary.xsd ================================================ dictionary.xsd See ISO/DIS 19136 Clause 16. Many applications require definitions of terms which are used within instance documents as the values of certain properties or as reference information to tie properties to standard information values in some way. Units of measure and descriptions of measurable phenomena are two particular examples. It will often be convenient to use definitions provided by external authorities. These may already be packaged for delivery in various ways, both online and offline. In order that they may be referred to from GML documents it is generally necessary that a URI be available for each definition. Where this is the case then it is usually preferable to refer to these directly. Alternatively, it may be convenient or necessary to capture definitions in XML, either embedded within an instance document containing features or as a separate document. The definitions may be transcriptions from an external source, or may be new definitions for a local purpose. In order to support this case, some simple components are provided in GML in the form of - a generic gml:Definition, which may serve as the basis for more specialized definitions - a generic gml:Dictionary, which allows a set of definitions or references to definitions to be collected These components may be used directly, but also serve as the basis for more specialised definition elements in GML, in particular: coordinate operations, coordinate reference systems, datums, temporal reference systems, and units of measure. Note that the GML definition and dictionary components implement a simple nested hierarchy of definitions with identifiers. The latter provide handles which may be used in the description of more complex relationships between terms. However, the GML dictionary components are not intended to provide direct support for complex taxonomies, ontologies or thesauri. Specialised XML tools are available to satisfy the more sophisticated requirements. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The basic gml:Definition element specifies a definition, which can be included in or referenced by a dictionary. The content model for a generic definition is a derivation from gml:AbstractGMLType. The gml:description property element shall hold the definition if this can be captured in a simple text string, or the gml:descriptionReference property element may carry a link to a description elsewhere. The gml:identifier element shall provide one identifier identifying this definition. The identifier shall be unique within the dictionaries using this definition. The gml:name elements shall provide zero or more terms and synonyms for which this is the definition. The gml:remarks element shall be used to hold additional textual information that is not conceptually part of the definition but is useful in understanding the definition. Sets of definitions may be collected into dictionaries or collections. A gml:Dictionary is a non-abstract collection of definitions. The gml:Dictionary content model adds a list of gml:dictionaryEntry properties that contain or reference gml:Definition objects. A database handle (gml:id attribute) is required, in order that this collection may be referred to. The standard gml:identifier, gml:description, gml:descriptionReference and gml:name properties are available to reference or contain more information about this dictionary. The gml:description and gml:descriptionReference property elements may be used for a description of this dictionary. The derived gml:name element may be used for the name(s) of this dictionary. for remote definiton references gml:dictionaryEntry shall be used. If a Definition object contained within a Dictionary uses the descriptionReference property to refer to a remote definition, then this enables the inclusion of a remote definition in a local dictionary, giving a handle and identifier in the context of the local dictionary. This property element contains or refers to the definitions which are members of a dictionary. The content model follows the standard GML property pattern, so a gml:dictionaryEntry may either contain or refer to a single gml:Definition. Since gml:Dictionary is substitutable for gml:Definition, the content of an entry may itself be a lower level dictionary. Note that if the value is provided by reference, this definition does not carry a handle (gml:id) in this context, so does not allow external references to this specific definition in this context. When used in this way the referenced definition will usually be in a dictionary in the same XML document. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/direction.xsd ================================================ direction.xsd See ISO/DIS 19136 Clause 18. The direction schema components provide the GML Application Schema developer with a standard property element to describe direction, and associated objects that may be used to express orientation, direction, heading, bearing or other directional aspects of geographic features. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The property gml:direction is intended as a pre-defined property expressing a direction to be assigned to features defined in a GML application schema. Direction vectors are specified by providing components of a vector. deprecated direction descriptions are specified by a compass point code, a keyword, a textual description or a reference to a description. A gml:compassPoint is specified by a simple enumeration. In addition, thre elements to contain text-based descriptions of direction are provided. If the direction is specified using a term from a list, gml:keyword should be used, and the list indicated using the value of the codeSpace attribute. if the direction is decribed in prose, gml:direction or gml:reference should be used, allowing the value to be included inline or by reference. These directions are necessarily approximate, giving direction with a precision of 22.5°. It is thus generally unnecessary to specify the reference frame, though this may be detailed in the definition of a GML application language. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/dynamicFeature.xsd ================================================ dynamicFeature.xsd See ISO/DIS 19136 15.6. A number of types and relationships are defined to represent the time-varying properties of geographic features. In a comprehensive treatment of spatiotemporal modeling, Langran (see Bibliography) distinguished three principal temporal entities: states, events, and evidence; the schema specified in the following Subclauses incorporates elements for each. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Evidence is represented by a simple gml:dataSource or gml:dataSourceReference property that indicates the source of the temporal data. The remote link attributes of the gml:dataSource element have been deprecated along with its current type. Evidence is represented by a simple gml:dataSource or gml:dataSourceReference property that indicates the source of the temporal data. A convenience group. This allows an application schema developer to include dynamic properties in a content model in a standard fashion. States are captured by time-stamped instances of a feature. The content model extends the standard gml:AbstractFeatureType with the gml:dynamicProperties model group. Each time-stamped instance represents a 'snapshot' of a feature. The dynamic feature classes will normally be extended to suit particular applications. A dynamic feature bears either a time stamp or a history. A gml:DynamicFeatureCollection is a feature collection that has a gml:validTime property (i.e. is a snapshot of the feature collection) or which has a gml:history property that contains one or more gml:AbstractTimeSlices each of which contain values of the time varying properties of the feature collection. Note that the gml:DynamicFeatureCollection may be one of the following: 1. A feature collection which consists of static feature members (members do not change in time) but which has properties of the collection object as a whole that do change in time . 2. A feature collection which consists of dynamic feature members (the members are gml:DynamicFeatures) but which also has properties of the collection as a whole that vary in time. To describe an event — an action that occurs at an instant or over an interval of time — GML provides the gml:AbtractTimeSlice element. A timeslice encapsulates the time-varying properties of a dynamic feature -- it shall be extended to represent a time stamped projection of a specific feature. The gml:dataSource property describes how the temporal data was acquired. A gml:AbstractTimeSlice instance is a GML object that encapsulates updates of the dynamic—or volatile—properties that reflect some change event; it thus includes only those feature properties that have actually changed due to some process. gml:AbstractTimeSlice basically provides a facility for attribute-level time stamping, in contrast to the object-level time stamping of dynamic feature instances. The time slice can thus be viewed as event or process-oriented, whereas a snapshot is more state or structure-oriented. A timeslice has richer causality, whereas a snapshot merely portrays the status of the whole. A generic sequence of events constitute a gml:history of an object. The gml:history element contains a set of elements in the substitution group headed by the abstract element gml:AbstractTimeSlice, representing the time-varying properties of interest. The history property of a dynamic feature associates a feature instance with a sequence of time slices (i.e. change events) that encapsulate the evolution of the feature. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/feature.xsd ================================================ feature.xsd See ISO/DIS 19136 Clause 9. A GML feature is a (representation of a) identifiable real-world object in a selected domain of discourse. The feature schema provides a framework for the creation of GML features and feature collections. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The basic feature model is given by the gml:AbstractFeatureType. The content model for gml:AbstractFeatureType adds two specific properties suitable for geographic features to the content model defined in gml:AbstractGMLType. The value of the gml:boundedBy property describes an envelope that encloses the entire feature instance, and is primarily useful for supporting rapid searching for features that occur in a particular location. The value of the gml:location property describes the extent, position or relative location of the feature. This abstract element serves as the head of a substitution group which may contain any elements whose content model is derived from gml:AbstractFeatureType. This may be used as a variable in the construction of content models. gml:AbstractFeature may be thought of as "anything that is a GML feature" and may be used to define variables or templates in which the value of a GML property is "any feature". This occurs in particular in a GML feature collection where the feature member properties contain one or multiple copies of gml:AbstractFeature respectively. This property describes the minimum bounding box or rectangle that encloses the entire feature. gml:EnvelopeWithTimePeriod is provided for envelopes that include a temporal extent. It adds two time position properties, gml:beginPosition and gml:endPosition, which describe the extent of a time-envelope. Since gml:EnvelopeWithTimePeriod is assigned to the substitution group headed by gml:Envelope, it may be used whenever gml:Envelope is valid. The gml:locationName property element is a convenience property where the text value describes the location of the feature. If the location names are selected from a controlled list, then the list shall be identified in the codeSpace attribute. The gml:locationReference property element is a convenience property where the text value referenced by the xlink:href attribute describes the location of the feature. To create a collection of GML features, a property type shall be derived by extension from gml:AbstractFeatureMemberType. By default, this abstract property type does not imply any ownership of the features in the collection. The owns attribute of gml:OwnershipAttributeGroup may be used on a property element instance to assert ownership of a feature in the collection. A collection shall not own a feature already owned by another object. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/geometryAggregates.xsd ================================================ geometryAggregates.xsd See ISO/DIS 19136 12.3. Geometric aggregates (i.e. instances of a subtype of gml:AbstractGeometricAggregateType) are arbitrary aggregations of geometry elements. They are not assumed to have any additional internal structure and are used to "collect" pieces of geometry of a specified type. Application schemas may use aggregates for features that use multiple geometric objects in their representations. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . gml:AbstractGeometricAggregate is the abstract head of the substitution group for all geometric aggregates. gml:MultiGeometry is a collection of one or more GML geometry objects of arbitrary type. The members of the geometric aggregate may be specified either using the "standard" property (gml:geometryMember) or the array property (gml:geometryMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element either references a geometry element via the XLink-attributes or contains the geometry element. This property element contains a list of geometry elements. The order of the elements is significant and shall be preserved when processing the array. A property that has a geometric aggregate as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. A gml:MultiPoint consists of one or more gml:Points. The members of the geometric aggregate may be specified either using the "standard" property (gml:pointMember) or the array property (gml:pointMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element either references a Point via the XLink-attributes or contains the Point element. This property element contains a list of points. The order of the elements is significant and shall be preserved when processing the array. A property that has a collection of points as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. A gml:MultiCurve is defined by one or more gml:AbstractCurves. The members of the geometric aggregate may be specified either using the "standard" property (gml:curveMember) or the array property (gml:curveMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element contains a list of curves. The order of the elements is significant and shall be preserved when processing the array. A property that has a collection of curves as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. A gml:MultiSurface is defined by one or more gml:AbstractSurfaces. The members of the geometric aggregate may be specified either using the "standard" property (gml:surfaceMember) or the array property (gml:surfaceMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element contains a list of surfaces. The order of the elements is significant and shall be preserved when processing the array. A property that has a collection of surfaces as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. A gml:MultiSolid is defined by one or more gml:AbstractSolids. The members of the geometric aggregate may be specified either using the "standard" property (gml:solidMember) or the array property (gml:solidMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element either references a solid via the XLink-attributes or contains the solid element. A solid element is any element, which is substitutable for gml:AbstractSolid. This property element contains a list of solids. The order of the elements is significant and shall be preserved when processing the array. A property that has a collection of solids as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic0d1d.xsd ================================================ geometryBasic0d1d.xsd See ISO/DIS 19136 Clause 10. Any geometry element that inherits the semantics of AbstractGeometryType may be viewed as a set of direct positions. All of the classes derived from AbstractGeometryType inherit an optional association to a coordinate reference system. All direct positions shall directly or indirectly be associated with a coordinate reference system. When geometry elements are aggregated in another geometry element (such as a MultiGeometry or GeometricComplex), which already has a coordinate reference system specified, then these elements are assumed to be in that same coordinate reference system unless otherwise specified. The geometry model distinguishes geometric primitives, aggregates and complexes. Geometric primitives, i.e. instances of a subtype of AbstractGeometricPrimitiveType, will be open, that is, they will not contain their boundary points; curves will not contain their end points, surfaces will not contain their boundary curves, and solids will not contain their bounding surfaces. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . All geometry elements are derived directly or indirectly from this abstract supertype. A geometry element may have an identifying attribute (gml:id), one or more names (elements identifier and name) and a description (elements description and descriptionReference) . It may be associated with a spatial reference system (attribute group gml:SRSReferenceGroup). The following rules shall be adhered to: - Every geometry type shall derive from this abstract type. - Every geometry element (i.e. an element of a geometry type) shall be directly or indirectly in the substitution group of AbstractGeometry. The attribute group SRSReferenceGroup is an optional reference to the CRS used by this geometry, with optional additional information to simplify the processing of the coordinates when a more complete definition of the CRS is not needed. In general the attribute srsName points to a CRS instance of gml:AbstractCoordinateReferenceSystem. For well-known references it is not required that the CRS description exists at the location the URI points to. If no srsName attribute is given, the CRS shall be specified as part of the larger context this geometry element is part of. The attributes uomLabels and axisLabels, defined in the SRSInformationGroup attribute group, are optional additional and redundant information for a CRS to simplify the processing of the coordinate values when a more complete definition of the CRS is not needed. This information shall be the same as included in the complete definition of the CRS, referenced by the srsName attribute. When the srsName attribute is included, either both or neither of the axisLabels and uomLabels attributes shall be included. When the srsName attribute is omitted, both of these attributes shall be omitted. The attribute axisLabels is an ordered list of labels for all the axes of this CRS. The gml:axisAbbrev value should be used for these axis labels, after spaces and forbidden characters are removed. When the srsName attribute is included, this attribute is optional. When the srsName attribute is omitted, this attribute shall also be omitted. The attribute uomLabels is an ordered list of unit of measure (uom) labels for all the axes of this CRS. The value of the string in the gml:catalogSymbol should be used for this uom labels, after spaces and forbidden characters are removed. When the axisLabels attribute is included, this attribute shall also be included. When the axisLabels attribute is omitted, this attribute shall also be omitted. The AbstractGeometry element is the abstract head of the substitution group for all geometry elements of GML. This includes pre-defined and user-defined geometry elements. Any geometry element shall be a direct or indirect extension/restriction of AbstractGeometryType and shall be directly or indirectly in the substitution group of AbstractGeometry. A geometric property may either be any geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same or another document). Note that either the reference or the contained element shall be given, but not both or none. If a feature has a property that takes a geometry element as its value, this is called a geometry property. A generic type for such a geometry property is GeometryPropertyType. If a feature has a property which takes an array of geometry elements as its value, this is called a geometry array property. A generic type for such a geometry property is GeometryArrayPropertyType. The elements are always contained inline in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported. Direct position instances hold the coordinates for a position within some coordinate reference system (CRS). Since direct positions, as data types, will often be included in larger objects (such as geometry elements) that have references to CRS, the srsName attribute will in general be missing, if this particular direct position is included in a larger element with such a reference to a CRS. In this case, the CRS is implicitly assumed to take on the value of the containing object's CRS. if no srsName attribute is given, the CRS shall be specified as part of the larger context this geometry element is part of, typically a geometric object like a point, curve, etc. posList instances (and other instances with the content model specified by DirectPositionListType) hold the coordinates for a sequence of direct positions within the same coordinate reference system (CRS). if no srsName attribute is given, the CRS shall be specified as part of the larger context this geometry element is part of, typically a geometric object like a point, curve, etc. The optional attribute count specifies the number of direct positions in the list. If the attribute count is present then the attribute srsDimension shall be present, too. The number of entries in the list is equal to the product of the dimensionality of the coordinate reference system (i.e. it is a derived value of the coordinate reference system definition) and the number of direct positions. GML supports two different ways to specify a geometric position: either by a direct position (a data type) or a point (a geometric object). pos elements are positions that are "owned" by the geometric primitive encapsulating this geometric position. pointProperty elements contain a point that may be referenced from other geometry elements or reference another point defined elsewhere (reuse of existing points). GML supports two different ways to specify a list of geometric positions: either by a sequence of geometric positions (by reusing the group definition) or a sequence of direct positions (element posList). The posList element allows for a compact way to specify the coordinates of the positions, if all positions are represented in the same coordinate reference system. For some applications the components of the position may be adjusted to yield a unit vector. deprecated Envelope defines an extent using a pair of positions defining opposite corners in arbitrary dimensions. The first direct position is the "lower corner" (a coordinate position consisting of all the minimal ordinates for each dimension for all points within the envelope), the second one the "upper corner" (a coordinate position consisting of all the maximal ordinates for each dimension for all points within the envelope). The use of the properties "coordinates" and "pos" has been deprecated. The explicitly named properties "lowerCorner" and "upperCorner" shall be used instead. gml:AbstractGeometricPrimitiveType is the abstract root type of the geometric primitives. A geometric primitive is a geometric object that is not decomposed further into other primitives in the system. All primitives are oriented in the direction implied by the sequence of their coordinate tuples. The AbstractGeometricPrimitive element is the abstract head of the substitution group for all (pre- and user-defined) geometric primitives. A property that has a geometric primitive as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. A Point is defined by a single coordinate tuple. The direct position of a point is specified by the pos element which is of type DirectPositionType. A property that has a point as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a point via the XLink-attributes or contains the point element. pointProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for Point. gml:PointArrayPropertyType is a container for an array of points. The elements are always contained inline in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported. gml:AbstractCurveType is an abstraction of a curve to support the different levels of complexity. The curve may always be viewed as a geometric primitive, i.e. is continuous. The AbstractCurve element is the abstract head of the substitution group for all (continuous) curve elements. A property that has a curve as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a curve via the XLink-attributes or contains the curve element. curveProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractCurve. A container for an array of curves. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported. A LineString is a special curve that consists of a single segment with linear interpolation. It is defined by two or more coordinate tuples, with linear interpolation between them. The number of direct positions in the list shall be at least two. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic2d.xsd ================================================ geometryBasic2d.xsd See ISO/DIS 19136 Clause 10. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . gml:AbstractSurfaceType is an abstraction of a surface to support the different levels of complexity. A surface is always a continuous region of a plane. The AbstractSurface element is the abstract head of the substitution group for all (continuous) surface elements. A property that has a surface as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a surface via the XLink-attributes or contains the surface element. surfaceProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractSurface. gml:SurfaceArrayPropertyType is a container for an array of surfaces. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported. A Polygon is a special surface that is defined by a single surface patch (see D.3.6). The boundary of this patch is coplanar and the polygon uses planar interpolation in its interior. The elements exterior and interior describe the surface boundary of the polygon. A boundary of a surface consists of a number of rings. In the normal 2D case, one of these rings is distinguished as being the exterior boundary. In a general manifold this is not always possible, in which case all boundaries shall be listed as interior boundaries, and the exterior will be empty. A boundary of a surface consists of a number of rings. The "interior" rings separate the surface / surface patch from the area enclosed by the rings. An abstraction of a ring to support surface boundaries of different complexity. The AbstractRing element is the abstract head of the substituition group for all closed boundaries of a surface patch. A property with the content model of gml:AbstractRingPropertyType encapsulates a ring to represent the surface boundary property of a surface. A LinearRing is defined by four or more coordinate tuples, with linear interpolation between them; the first and last coordinates shall be coincident. The number of direct positions in the list shall be at least four. A property with the content model of gml:LinearRingPropertyType encapsulates a linear ring to represent a component of a surface boundary. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/geometryComplexes.xsd ================================================ geometryComplexes.xsd See ISO/DIS 19136 12.2. Geometric complexes (i.e. instances of gml:GeometricComplexType) are closed collections of geometric primitives, i.e. they will contain their boundaries. A geometric complex (gml:GeometricComplex) is defined by ISO 19107:2003, 6.6.1 as "a set of primitive geometric objects (in a common coordinate system) whose interiors are disjoint. Further, if a primitive is in a geometric complex, then there exists a set of primitives in that complex whose point-wise union is the boundary of this first primitive." A geometric composite (gml:CompositeCurve, gml:CompositeSurface and gml:CompositeSolid) represents a geometric complex with an underlying core geometry that is isomorphic to a primitive, i.e. it can be viewed as a primitive and as a complex. See ISO 19107:2003, 6.1 and 6.6.3 for more details on the nature of composite geometries. Geometric complexes and composites are intended to be used in application schemas where the sharing of geometry is important. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . A property that has a geometric complex as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. A gml:CompositeCurve is represented by a sequence of (orientable) curves such that each curve in the sequence terminates at the start point of the subsequent curve in the list. curveMember references or contains inline one curve in the composite curve. The curves are contiguous, the collection of curves is ordered. Therefore, if provided, the aggregationType attribute shall have the value "sequence". A gml:CompositeSurface is represented by a set of orientable surfaces. It is geometry type with all the geometric properties of a (primitive) surface. Essentially, a composite surface is a collection of surfaces that join in pairs on common boundary curves and which, when considered as a whole, form a single surface. surfaceMember references or contains inline one surface in the composite surface. The surfaces are contiguous. gml:CompositeSolid implements ISO 19107 GM_CompositeSolid (see ISO 19107:2003, 6.6.7) as specified in D.2.3.6. A gml:CompositeSolid is represented by a set of orientable surfaces. It is a geometry type with all the geometric properties of a (primitive) solid. Essentially, a composite solid is a collection of solids that join in pairs on common boundary surfaces and which, when considered as a whole, form a single solid. solidMember references or contains one solid in the composite solid. The solids are contiguous. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/geometryPrimitives.xsd ================================================ geometryPrimitives.xsd See ISO/DIS 19136 Clause 11. Beside the "simple" geometric primitives specified in the previous Clause, this Clause specifies additional primitives to describe real world situations which require a more expressive geometry model. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . A curve is a 1-dimensional primitive. Curves are continuous, connected, and have a measurable length in terms of the coordinate system. A curve is composed of one or more curve segments. Each curve segment within a curve may be defined using a different interpolation method. The curve segments are connected to one another, with the end point of each segment except the last being the start point of the next segment in the segment list. The orientation of the curve is positive. The element segments encapsulates the segments of the curve. The property baseCurve references or contains the base curve, i.e. it either references the base curve via the XLink-attributes or contains the curve element. A curve element is any element which is substitutable for AbstractCurve. The base curve has positive orientation. OrientableCurve consists of a curve and an orientation. If the orientation is "+", then the OrientableCurve is identical to the baseCurve. If the orientation is "-", then the OrientableCurve is related to another AbstractCurve with a parameterization that reverses the sense of the curve traversal. A curve segment defines a homogeneous segment of a curve. The attributes numDerivativesAtStart, numDerivativesAtEnd and numDerivativesInterior specify the type of continuity as specified in ISO 19107:2003, 6.4.9.3. The AbstractCurveSegment element is the abstract head of the substituition group for all curve segment elements, i.e. continuous segments of the same interpolation mechanism. All curve segments shall have an attribute interpolation with type gml:CurveInterpolationType specifying the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. gml:CurveSegmentArrayPropertyType is a container for an array of curve segments. This property element contains a list of curve segments. The order of the elements is significant and shall be preserved when processing the array. gml:CurveInterpolationType is a list of codes that may be used to identify the interpolation mechanisms specified by an application schema. A LineStringSegment is a curve segment that is defined by two or more control points including the start and end point, with linear interpolation between them. The content model follows the general pattern for the encoding of curve segments. An ArcString is a curve segment that uses three-point circular arc interpolation ("circularArc3Points"). The number of arcs in the arc string may be explicitly stated in the attribute numArc. The number of control points in the arc string shall be 2 * numArc + 1. The content model follows the general pattern for the encoding of curve segments. An Arc is an arc string with only one arc unit, i.e. three control points including the start and end point. As arc is an arc string consisting of a single arc, the attribute "numArc" is fixed to "1". A Circle is an arc whose ends coincide to form a simple closed loop. The three control points shall be distinct non-co-linear points for the circle to be unambiguously defined. The arc is simply extended past the third control point until the first control point is encountered. This variant of the arc computes the mid points of the arcs instead of storing the coordinates directly. The control point sequence consists of the start and end points of each arc plus the bulge (see ISO 19107:2003, 6.4.17.2). The normal is a vector normal (perpendicular) to the chord of the arc (see ISO 19107:2003, 6.4.17.4). The interpolation is fixed as "circularArc2PointWithBulge". The number of arcs in the arc string may be explicitly stated in the attribute numArc. The number of control points in the arc string shall be numArc + 1. The content model follows the general pattern for the encoding of curve segments. An ArcByBulge is an arc string with only one arc unit, i.e. two control points, one bulge and one normal vector. As arc is an arc string consisting of a single arc, the attribute "numArc" is fixed to "1". This variant of the arc requires that the points on the arc shall be computed instead of storing the coordinates directly. The single control point is the center point of the arc plus the radius and the bearing at start and end. This representation can be used only in 2D. The element radius specifies the radius of the arc. The element startAngle specifies the bearing of the arc at the start. The element endAngle specifies the bearing of the arc at the end. The interpolation is fixed as "circularArcCenterPointWithRadius". Since this type describes always a single arc, the attribute "numArc" is fixed to "1". The content model follows the general pattern for the encoding of curve segments. A gml:CircleByCenterPoint is an gml:ArcByCenterPoint with identical start and end angle to form a full circle. Again, this representation can be used only in 2D. The number of control points shall be at least three. vectorAtStart is the unit tangent vector at the start point of the spline. vectorAtEnd is the unit tangent vector at the end point of the spline. Only the direction of the vectors shall be used to determine the shape of the cubic spline, not their length. interpolation is fixed as "cubicSpline". degree shall be the degree of the polynomial used for the interpolation in this spline. Therefore the degree for a cubic spline is fixed to "3". The content model follows the general pattern for the encoding of curve segments. A B-Spline is a piecewise parametric polynomial or rational curve described in terms of control points and basis functions as specified in ISO 19107:2003, 6.4.30. Therefore, interpolation may be either "polynomialSpline" or "rationalSpline" depending on the interpolation type; default is "polynomialSpline". degree shall be the degree of the polynomial used for interpolation in this spline. knot shall be the sequence of distinct knots used to define the spline basis functions (see ISO 19107:2003, 6.4.26.2). The attribute isPolynomial shall be set to "true" if this is a polynomial spline (see ISO 19107:2003, 6.4.30.5). The attribute knotType shall provide the type of knot distribution used in defining this spline (see ISO 19107:2003, 6.4.30.4). The content model follows the general pattern for the encoding of curve segments. gml:KnotPropertyType encapsulates a knot to use it in a geometric type. A knot is a breakpoint on a piecewise spline curve. value is the value of the parameter at the knot of the spline (see ISO 19107:2003, 6.4.24.2). multiplicity is the multiplicity of this knot used in the definition of the spline (with the same weight). weight is the value of the averaging weight used for this knot of the spline. This enumeration type specifies values for the knots' type (see ISO 19107:2003, 6.4.25). Bezier curves are polynomial splines that use Bezier or Bernstein polynomials for interpolation purposes. It is a special case of the B-Spline curve with two knots. degree shall be the degree of the polynomial used for interpolation in this spline. knot shall be the sequence of distinct knots used to define the spline basis functions. interpolation is fixed as "polynomialSpline". isPolynomial is fixed as "true". knotType is not relevant for Bezier curve segments. An offset curve is a curve at a constant distance from the basis curve. offsetBase is the base curve from which this curve is defined as an offset. distance and refDirection have the same meaning as specified in ISO 19107:2003, 6.4.23. The content model follows the general pattern for the encoding of curve segments. location, refDirection, inDimension and outDimension have the same meaning as specified in ISO 19107:2003, 6.4.21. A clothoid, or Cornu's spiral, is plane curve whose curvature is a fixed function of its length. refLocation, startParameter, endParameter and scaleFactor have the same meaning as specified in ISO 19107:2003, 6.4.22. interpolation is fixed as "clothoid". The content model follows the general pattern for the encoding of curve segments. A sequence of geodesic segments. The number of control points shall be at least two. interpolation is fixed as "geodesic". The content model follows the general pattern for the encoding of curve segments. A Surface is a 2-dimensional primitive and is composed of one or more surface patches as specified in ISO 19107:2003, 6.3.17.1. The surface patches are connected to one another. patches encapsulates the patches of the surface. The property baseSurface references or contains the base surface. The property baseSurface either references the base surface via the XLink-attributes or contains the surface element. A surface element is any element which is substitutable for gml:AbstractSurface. The base surface has positive orientation. OrientableSurface consists of a surface and an orientation. If the orientation is "+", then the OrientableSurface is identical to the baseSurface. If the orientation is "-", then the OrientableSurface is a reference to a gml:AbstractSurface with an up-normal that reverses the direction for this OrientableSurface, the sense of "the top of the surface". A surface patch defines a homogenuous portion of a surface. The AbstractSurfacePatch element is the abstract head of the substituition group for all surface patch elements describing a continuous portion of a surface. All surface patches shall have an attribute interpolation (declared in the types derived from gml:AbstractSurfacePatchType) specifying the interpolation mechanism used for the patch using gml:SurfaceInterpolationType. gml:SurfacePatchArrayPropertyType is a container for a sequence of surface patches. The patches property element contains the sequence of surface patches. The order of the elements is significant and shall be preserved when processing the array. gml:SurfaceInterpolationType is a list of codes that may be used to identify the interpolation mechanisms specified by an application schema. A gml:PolygonPatch is a surface patch that is defined by a set of boundary curves and an underlying surface to which these curves adhere. The curves shall be coplanar and the polygon uses planar interpolation in its interior. interpolation is fixed to "planar", i.e. an interpolation shall return points on a single plane. The boundary of the patch shall be contained within that plane. gml:Triangle represents a triangle as a surface patch with an outer boundary consisting of a linear ring. Note that this is a polygon (subtype) with no inner boundaries. The number of points in the linear ring shall be four. The ring (element exterior) shall be a gml:LinearRing and shall form a triangle, the first and the last position shall be coincident. interpolation is fixed to "planar", i.e. an interpolation shall return points on a single plane. The boundary of the patch shall be contained within that plane. gml:Rectangle represents a rectangle as a surface patch with an outer boundary consisting of a linear ring. Note that this is a polygon (subtype) with no inner boundaries. The number of points in the linear ring shall be five. The ring (element exterior) shall be a gml:LinearRing and shall form a rectangle; the first and the last position shall be coincident. interpolation is fixed to "planar", i.e. an interpolation shall return points on a single plane. The boundary of the patch shall be contained within that plane. A ring is used to represent a single connected component of a surface boundary as specified in ISO 19107:2003, 6.3.6. Every gml:curveMember references or contains one curve, i.e. any element which is substitutable for gml:AbstractCurve. In the context of a ring, the curves describe the boundary of the surface. The sequence of curves shall be contiguous and connected in a cycle. If provided, the aggregationType attribute shall have the value "sequence". A property with the content model of gml:RingPropertyType encapsulates a ring to represent a component of a surface boundary. A gml:PointGrid group contains or references points or positions which are organised into sequences or grids. All rows shall have the same number of positions (columns). The element provides a substitution group head for the surface patches based on parametric curves. All properties are specified in the derived subtypes. All derived subtypes shall conform to the constraints specified in ISO 19107:2003, 6.4.40. If provided, the aggregationType attribute shall have the value "set". if provided, rows gives the number of rows, columns the number of columns in the parameter grid. The parameter grid is represented by an instance of the gml:PointGrid group. The element provides a substitution group head for the surface patches based on a grid. All derived subtypes shall conform to the constraints specified in ISO 19107:2003, 6.4.41. A polyhedral surface is a surface composed of polygon patches connected along their common boundary curves. This differs from the surface type only in the restriction on the types of surface patches acceptable. polygonPatches encapsulates the polygon patches of the polyhedral surface. A triangulated surface is a polyhedral surface that is composed only of triangles. There is no restriction on how the triangulation is derived. trianglePatches encapsulates the triangles of the triangulated surface. A tin is a triangulated surface that uses the Delauny algorithm or a similar algorithm complemented with consideration of stoplines (stopLines), breaklines (breakLines), and maximum length of triangle sides (maxLength). controlPoint shall contain a set of the positions (three or more) used as posts for this TIN (corners of the triangles in the TIN). See ISO 19107:2003, 6.4.39 for details. gml:LineStringSegmentArrayPropertyType provides a container for line strings. gml:AbstractSolidType is an abstraction of a solid to support the different levels of complexity. The solid may always be viewed as a geometric primitive, i.e. is contiguous. The AbstractSolid element is the abstract head of the substituition group for all (continuous) solid elements. A property that has a solid as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a solid via the XLink-attributes or contains the solid element. solidProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractSolid. gml:SolidArrayPropertyType is a container for an array of solids. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements is not supported. A solid is the basis for 3-dimensional geometry. The extent of a solid is defined by the boundary surfaces as specified in ISO 19107:2003, 6.3.18. exterior specifies the outer boundary, interior the inner boundary of the solid. A shell is used to represent a single connected component of a solid boundary as specified in ISO 19107:2003, 6.3.8. Every gml:surfaceMember references or contains one surface, i.e. any element which is substitutable for gml:AbstractSurface. In the context of a shell, the surfaces describe the boundary of the solid. If provided, the aggregationType attribute shall have the value "set". This property element either references a surface via the XLink-attributes or contains the surface element. A surface element is any element, which is substitutable for gml:AbstractSurface. A property with the content model of gml:ShellPropertyType encapsulates a shell to represent a component of a solid boundary. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/gml.xsd ================================================ gml.xsd GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/gmlBase.xsd ================================================ gmlBase.xsd See ISO/DIS 19136 7.2. The gmlBase schema components establish the GML model and syntax, in particular - a root XML type from which XML types for all GML objects should be derived, - a pattern and components for GML properties, - patterns for collections and arrays, and components for generic collections and arrays, - components for associating metadata with GML objects, - components for constructing definitions and dictionaries. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This element has no type defined, and is therefore implicitly (according to the rules of W3C XML Schema) an XML Schema anyType. It is used as the head of an XML Schema substitution group which unifies complex content and certain simple content elements used for datatypes in GML, including the gml:AbstractGML substitution group. The abstract element gml:AbstractGML is "any GML object having identity". It acts as the head of an XML Schema substitution group, which may include any element which is a GML feature, or other object, with identity. This is used as a variable in content models in GML core and application schemas. It is effectively an abstract superclass for all GML objects. XLink components are the standard method to support hypertext referencing in XML. An XML Schema attribute group, gml:AssociationAttributeGroup, is provided to support the use of Xlinks as the method for indicating the value of a property by reference in a uniform manner in GML. deprecated Applying this pattern shall restrict the multiplicity of objects in a property element using this content model to exactly one. An instance of this type shall contain an element representing an object, or serve as a pointer to a remote object. Applying the pattern to define an application schema specific property type allows to restrict - the inline object to specified object types, - the encoding to "by-reference only" (see 7.2.3.7), - the encoding to "inline only" (see 7.2.3.8). Encoding a GML property inline vs. by-reference shall not imply anything about the "ownership" of the contained or referenced GML Object, i.e. the encoding style shall not imply any "deep-copy" or "deep-delete" semantics. To express ownership over the contained or referenced GML Object, the gml:OwnershipAttributeGroup attribute group may be added to object-valued property elements. If the attribute group is not part of the content model of such a property element, then the value may not be "owned". When the value of the owns attribute is "true", the existence of inline or referenced object(s) depends upon the existence of the parent object. This element shows how an element declaration may include a Schematron constraint to limit the property to act in either inline or by-reference mode, but not both. gml:abstractReference may be used as the head of a subtitution group of more specific elements providing a value by-reference. gml:ReferenceType is intended to be used in application schemas directly, if a property element shall use a "by-reference only" encoding. gml:abstractInlineProperty may be used as the head of a subtitution group of more specific elements providing a value inline. If the value of an object property is another object and that object contains also a property for the association between the two objects, then this name of the reverse property may be encoded in a gml:reversePropertyName element in an appinfo annotation of the property element to document the constraint between the two properties. The value of the element shall contain the qualified name of the property element. The value of this property is a text description of the object. gml:description uses gml:StringOrRefType as its content model, so it may contain a simple text string content, or carry a reference to an external description. The use of gml:description to reference an external description has been deprecated and replaced by the gml:descriptionReference property. The value of this property is a remote text description of the object. The xlink:href attribute of the gml:descriptionReference property references the external description. The gml:name property provides a label or identifier for the object, commonly a descriptive name. An object may have several names, typically assigned by different authorities. gml:name uses the gml:CodeType content model. The authority for a name is indicated by the value of its (optional) codeSpace attribute. The name may or may not be unique, as determined by the rules of the organization responsible for the codeSpace. In common usage there will be one name per authority, so a processing application may select the name from its preferred codeSpace. Often, a special identifier is assigned to an object by the maintaining authority with the intention that it is used in references to the object For such cases, the codeSpace shall be provided. That identifier is usually unique either globally or within an application domain. gml:identifier is a pre-defined property for such identifiers. The attribute gml:id supports provision of a handle for the XML element representing a GML Object. Its use is mandatory for all GML objects. It is of XML type ID, so is constrained to be unique in the XML document within which it occurs. To create a collection of GML Objects that are not all features, a property type shall be derived by extension from gml:AbstractMemberType. This abstract property type is intended to be used only in object types where software shall be able to identify that an instance of such an object type is to be interpreted as a collection of objects. By default, this abstract property type does not imply any ownership of the objects in the collection. The owns attribute of gml:OwnershipAttributeGroup may be used on a property element instance to assert ownership of an object in the collection. A collection shall not own an object already owned by another object. A GML Object Collection is any GML Object with a property element in its content model whose content model is derived by extension from gml:AbstractMemberType. In addition, the complex type describing the content model of the GML Object Collection may also include a reference to the attribute group gml:AggregationAttributeGroup to provide additional information about the semantics of the object collection. This information may be used by applications to group GML objects, and optionally to order and index them. The allowed values for the aggregationType attribute are defined by gml:AggregationType. See 8.4 of ISO/IEC 11404:1996 for the meaning of the values in the enumeration. To associate metadata described by any XML Schema with a GML object, a property element shall be defined whose content model is derived by extension from gml:AbstractMetadataPropertyType. The value of such a property shall be metadata. The content model of such a property type, i.e. the metadata application schema shall be specified by the GML Application Schema. By default, this abstract property type does not imply any ownership of the metadata. The owns attribute of gml:OwnershipAttributeGroup may be used on a metadata property element instance to assert ownership of the metadata. If metadata following the conceptual model of ISO 19115 is to be encoded in a GML document, the corresponding Implementation Specification specified in ISO/TS 19139 shall be used to encode the metadata information. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/gml_32_geometries.rdf ================================================ Point Abstract Gridded Surface Polyhedral Surface Arc Polynomial Spline Multi-Curve Composite Surface Arc String Cylinder Shell Polygon Triangulated Irregular Network Multi-Geometry Bezier Curve BSpline Line String Segment Geodesic Abstract Surface Patch Geometric Complex Arc by Bulge CircleByCenterPoint Multi-Point Arc by Center Point Offset Curve Spline Curve Composite Line String Circle Orientable Curve Orientable Surface Clothoid Arc String by Bulge Triangulated Surface Triangle Cubic Spline Abstract Geometry Cone Composite Solid Abstract Geometric Primitive Linear Ring Abstract Parametric Curve Surface Geodesic String Multi-Solid Solid Composite Curve Rectangle Sphere Ring Polygon Patch Multi-Surface Abstract Curve Segment Surface ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/gml_3_2_1-ReadMe.txt ================================================ OpenGIS(r) GML schema version 3.2.1 / ISO 19136 - ReadMe.txt The schema has been validated with Xerces-J, Xerces C++ and XSV. ------------------------------------------------------------------- 2012-07-21 Kevin Stegemoller * v2.0.0 - v3.2.1 WARNING XLink change is NOT BACKWARD COMPATIBLE. * changed OGC XLink (xlink:simpleLink) to W3C XLink (xlink:simpleAttrs) per an approved TC and PC motion during the Dec. 2011 Brussels meeting. see http://www.opengeospatial.org/blog/1597 * implement 11-025: retroactively require/add all leaf documents of an XML namespace shall explicitly the all-components schema * v3.2.1: updated xsd:schema:@version to 3.2.1.2 (06-135r7 s#13.4) 2007-09-06 Kevin Stegemoller GML 3.2.1 (ISO 19136) * Published GML 3.2.1 schemas from OGC 07-036 * validated with oXygen 8.2 (xerces-J 2.9.0) - Kevin Stegemoller * validated with Xerces-J, Xerces-C++ and XSV - Clemens Portele 2007-08-17 Kevin Stegemoller Changes made to these GML 3.2.1 / ISO 19136 schemas: * added ReadMe.txt * changed gmd.xsd references to "../../iso/19139/20070417/gmd/gmd.xsd" * changed xlink references to be relative to /xlink/1.0.0/xlinks.xsd available from schemas.opengis.net/xlink/1.0.0/xlinks.xsd (REMOVED 2012-07-21). * removed xlinks schema and directory Changes made to these ISO 19139 schemas by OGC: * added ReadMe.txt * changed ISO_19136 path to /gml/3.2.1/ * changed xlink references to be relative to /xlink/1.0.0/xlinks.xsd available from schemas.opengis.net/xlink/1.0.0/xlinks.xsd (REMOVED 2012-07-21). * removed xlinks schema and directory OGC GML 3.2.1 / ISO 19136 schemas files will be published at: - http://schemas.opengis.net/gml/3.2.1/ - http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19136_Schemas/ Files in the folder "ISO/19139/20070417" are also published at - http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/ ------------------------------------------------------------------- The Open Geospatial Consortium, Inc. official schema repository is at http://schemas.opengis.net/ . Policies, Procedures, Terms, and Conditions of OGC(r) are available http://www.opengeospatial.org/ogc/policies/ . Additional rights of use are described at http://www.opengeospatial.org/legal/ . Copyright (c) 2007 Open Geospatial Consortium. ------------------------------------------------------------------- ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/grids.xsd ================================================ grids.xsd See ISO/DIS 19136 20.2. An implicit description of geometry is one in which the items of the geometry do not explicitly appear in the encoding. Instead, a compact notation records a set of parameters, and a set of objects may be generated using a rule with these parameters. This Clause provides grid geometries that are used in the description of gridded coverages and other applications. In GML two grid structures are defined, namely gml:Grid and gml:RectifiedGrid. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The gml:Grid implicitly defines an unrectified grid, which is a network composed of two or more sets of curves in which the members of each set intersect the members of the other sets in an algorithmic way. The region of interest within the grid is given in terms of its gml:limits, being the grid coordinates of diagonally opposed corners of a rectangular region. gml:axisLabels is provided with a list of labels of the axes of the grid (gml:axisName has been deprecated). gml:dimension specifies the dimension of the grid. The gml:limits element contains a single gml:GridEnvelope. The gml:low and gml:high property elements of the envelope are each integerLists, which are coordinate tuples, the coordinates being measured as offsets from the origin of the grid along each axis, of the diagonally opposing corners of a "rectangular" region of interest. A rectified grid is a grid for which there is an affine transformation between the grid coordinates and the coordinates of an external coordinate reference system. It is defined by specifying the position (in some geometric space) of the grid "origin" and of the vectors that specify the post locations. Note that the grid limits (post indexes) and axis name properties are inherited from gml:GridType and that gml:RectifiedGrid adds a gml:origin property (contains or references a gml:Point) and a set of gml:offsetVector properties. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/measures.xsd ================================================ measures.xsd See ISO/DIS 19136 17.3. gml:MeasureType is defined in the basicTypes schema. The measure types defined here correspond with a set of convenience measure types described in ISO/TS 19103. The XML implementation is based on the XML Schema simple type "double" which supports both decimal and scientific notation, and includes an XML attribute "uom" which refers to the units of measure for the value. Note that, there is no requirement to store values using any particular format, and applications receiving elements of this type may choose to coerce the data to any other type as convenient. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The value of a physical quantity, together with its unit. This is a prototypical definition for a specific measure type defined as a vacuous extension (i.e. aliases) of gml:MeasureType. In this case, the content model supports the description of a length (or distance) quantity, with its units. The unit of measure referenced by uom shall be suitable for a length, such as metres or feet. The gml:angle property element is used to record the value of an angle quantity as a single number, with its units. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/observation.xsd ================================================ observation.xsd See ISO/DIS 19136 Clause 19. A GML observation models the act of observing, often with a camera, a person or some form of instrument. An observation feature describes the "metadata" associated with an information capture event, together with a value for the result of the observation. This covers a broad range of cases, from a tourist photo (not the photo but the act of taking the photo), to images acquired by space borne sensors or the measurement of a temperature 5 meters below the surfaces of a lake. The basic structures introduced in this schema are intended to serve as the foundation for more comprehensive schemas for scientific, technical and engineering measurement schemas. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The content model is a straightforward extension of gml:AbstractFeatureType; it automatically has the gml:identifier, gml:description, gml:descriptionReference, gml:name, and gml:boundedBy properties. The gml:validTime element describes the time of the observation. Note that this may be a time instant or a time period. The gml:using property contains or references a description of a sensor, instrument or procedure used for the observation. The gml:target property contains or references the specimen, region or station which is the object of the observation. This property is particularly useful for remote observations, such as photographs, where a generic location property might apply to the location of the camera or the location of the field of view, and thus may be ambiguous. The gml:subject element is provided as a convenient synonym for gml:target. This is the term commonly used in phtotography. The gml:resultOf property indicates the result of the observation. The value may be inline, or a reference to a value elsewhere. A gml:DirectedObservation is the same as an observation except that it adds an additional gml:direction property. This is the direction in which the observation was acquired. Clearly this applies only to certain types of observations such as visual observations by people, or observations obtained from terrestrial cameras. gml:DirectedObservationAtDistance adds an additional distance property. This is the distance from the observer to the subject of the observation. Clearly this applies only to certain types of observations such as visual observations by people, or observations obtained from terrestrial cameras. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/referenceSystems.xsd ================================================ referenceSystems.xsd See ISO/DIS 19136 13.2. The reference systems schema components have two logical parts, which define elements and types for XML encoding of the definitions of: - Identified Object, inherited by the ten types of GML objects used for coordinate reference systems and coordinate operations - High-level part of the definitions of coordinate reference systems This schema encodes the Identified Object and Reference System packages of the UML Model for ISO 19111. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . gml:IdentifiedObjectType provides identification properties of a CRS-related object. In gml:DefinitionType, the gml:identifier element shall be the primary name by which this object is identified, encoding the "name" attribute in the UML model. Zero or more of the gml:name elements can be an unordered set of "identifiers", encoding the "identifier" attribute in the UML model. Each of these gml:name elements can reference elsewhere the object's defining information or be an identifier by which this object can be referenced. Zero or more other gml:name elements can be an unordered set of "alias" alternative names by which this CRS related object is identified, encoding the "alias" attributes in the UML model. An object may have several aliases, typically used in different contexts. The context for an alias is indicated by the value of its (optional) codeSpace attribute. Any needed version information shall be included in the codeSpace attribute of a gml:identifier and gml:name elements. In this use, the gml:remarks element in the gml:DefinitionType shall contain comments on or information about this object, including data source information. gml:AbstractCRS specifies a coordinate reference system which is usually single but may be compound. This abstract complex type shall not be used, extended, or restricted, in a GML Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. The gml:domainOfValidity property implements an association role to an EX_Extent object as encoded in ISO/TS 19139, either referencing or containing the definition of that extent. The gml:scope property provides a description of the usage, or limitations of usage, for which this CRS-related object is valid. If unknown, enter "not known". gml:CRSPropertyType is a property type for association roles to a CRS abstract coordinate reference system, either referencing or containing the definition of that CRS. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/temporal.xsd ================================================ temporal.xsd See ISO/DIS 19136 15.2. The GML temporal schemas include components for describing temporal geometry and topology, temporal reference systems, and the temporal characteristics of geographic data. The model underlying the representation constitutes a profile of the conceptual schema described in ISO 19108. The underlying spatiotemporal model strives to accommodate both feature-level and attribute-level time stamping; basic support for tracking moving objects is also included. Time is measured on two types of scales: interval and ordinal. An interval scale offers a basis for measuring duration, an ordinal scale provides information only about relative position in time. Two other ISO standards are relevant to describing temporal objects: ISO 8601 describes encodings for time instants and time periods, as text strings with particular structure and punctuation; ISO 11404 provides a detailed description of time intervals as part of a general discussion of language independent datatypes. The temporal schemas cover two interrelated topics and provide basic schema components for representing temporal instants and periods, temporal topology, and reference systems; more specialized schema components defines components used for dynamic features. Instances of temporal geometric types are used as values for the temporal properties of geographic features. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . gml:AbstractTimeObject acts as the head of a substitution group for all temporal primitives and complexes. gml:AbstractTimePrimitive acts as the head of a substitution group for geometric and topological temporal primitives. gml:TimePrimitivePropertyType provides a standard content model for associations between an arbitrary member of the substitution group whose head is gml:AbstractTimePrimitive and another object. gml:validTime is a convenience property element. gml:RelatedTimeType provides a content model for indicating the relative position of an arbitrary member of the substitution group whose head is gml:AbstractTimePrimitive. It extends the generic gml:TimePrimitivePropertyType with an XML attribute relativePosition, whose value is selected from the set of 13 temporal relationships identified by Allen (1983) gml:AbstractTimeComplex is an aggregation of temporal primitives and acts as the head of a substitution group for temporal complexes. gml:TimeGeometricPrimitive acts as the head of a substitution group for geometric temporal primitives. A temporal geometry shall be associated with a temporal reference system through the frame attribute that provides a URI reference that identifies a description of the reference system. Following ISO 19108, the Gregorian calendar with UTC is the default reference system, but others may also be used. The GPS calendar is an alternative reference systems in common use. The two geometric primitives in the temporal dimension are the instant and the period. GML components are defined to support these as follows. gml:TimeInstant acts as a zero-dimensional geometric primitive that represents an identifiable position in time. gml:TimeInstantPropertyType provides for associating a gml:TimeInstant with an object. gml:TimePeriod acts as a one-dimensional geometric primitive that represents an identifiable extent in time. The location in of a gml:TimePeriod is described by the temporal positions of the instants at which it begins and ends. The length of the period is equal to the temporal distance between the two bounding temporal positions. Both beginning and end may be described in terms of their direct position using gml:TimePositionType which is an XML Schema simple content type, or by reference to an indentifiable time instant using gml:TimeInstantPropertyType. Alternatively a limit of a gml:TimePeriod may use the conventional GML property model to make a reference to a time instant described elsewhere, or a limit may be indicated as a direct position. gml:TimePeriodPropertyType provides for associating a gml:TimePeriod with an object. The method for identifying a temporal position is specific to each temporal reference system. gml:TimePositionType supports the description of temporal position according to the subtypes described in ISO 19108. Values based on calendars and clocks use lexical formats that are based on ISO 8601, as described in XML Schema Part 2:2001. A decimal value may be used with coordinate systems such as GPS time or UNIX time. A URI may be used to provide a reference to some era in an ordinal reference system . In common with many of the components modelled as data types in the ISO 19100 series of International Standards, the corresponding GML component has simple content. However, the content model gml:TimePositionType is defined in several steps. Three XML attributes appear on gml:TimePositionType: A time value shall be associated with a temporal reference system through the frame attribute that provides a URI reference that identifies a description of the reference system. Following ISO 19108, the Gregorian calendar with UTC is the default reference system, but others may also be used. Components for describing temporal reference systems are described in 14.4, but it is not required that the reference system be described in this, as the reference may refer to anything that may be indentified with a URI. For time values using a calendar containing more than one era, the (optional) calendarEraName attribute provides the name of the calendar era. Inexact temporal positions may be expressed using the optional indeterminatePosition attribute. This takes a value from an enumeration. These values are interpreted as follows: - "unknown" indicates that no specific value for temporal position is provided. - "now" indicates that the specified value shall be replaced with the current temporal position whenever the value is accessed. - "before" indicates that the actual temporal position is unknown, but it is known to be before the specified value. - "after" indicates that the actual temporal position is unknown, but it is known to be after the specified value. A value for indeterminatePosition may - be used either alone, or - qualify a specific value for temporal position. The simple type gml:TimePositionUnion is a union of XML Schema simple types which instantiate the subtypes for temporal position described in ISO 19108. An ordinal era may be referenced via URI. A decimal value may be used to indicate the distance from the scale origin . time is used for a position that recurs daily (see ISO 19108:2002 5.4.4.2). Finally, calendar and clock forms that support the representation of time in systems based on years, months, days, hours, minutes and seconds, in a notation following ISO 8601, are assembled by gml:CalDate This element is used directly as a property of gml:TimeInstant (see 15.2.2.3), and may also be used in application schemas. The length of a time period. gml:duration conforms to the ISO 8601 syntax for temporal length as implemented by the XML Schema duration type. gml:timeInterval conforms to ISO 11404 which is based on floating point values for temporal length. ISO 11404 syntax specifies the use of a positiveInteger together with appropriate values for radix and factor. The resolution of the time interval is to one radix ^(-factor) of the specified time unit. The value of the unit is either selected from the units for time intervals from ISO 31-1:1992, or is another suitable unit. The encoding is defined for GML in gml:TimeUnitType. The second component of this union type provides a method for indicating time units other than the six standard units given in the enumeration. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/temporalReferenceSystems.xsd ================================================ temporalReferenceSystems.xsd See ISO/DIS 19136 15.5. A value in the time domain is measured relative to a temporal reference system. Common types of reference systems include calendars, ordinal temporal reference systems, and temporal coordinate systems (time elapsed since some epoch). The primary temporal reference system for use with geographic information is the Gregorian Calendar and 24 hour local or Coordinated Universal Time (UTC), but special applications may entail the use of alternative reference systems. The Julian day numbering system is a temporal coordinate system that has an origin earlier than any known calendar, at noon on 1 January 4713 BC in the Julian proleptic calendar, and is useful in transformations between dates in different calendars. In GML seven concrete elements are used to describe temporal reference systems: gml:TimeReferenceSystem, gml:TimeCoordinateSystem, gml:TimeCalendar, gml:TimeCalendarEra, gml:TimeClock, gml:TimeOrdinalReferenceSystem, and gml:TimeOrdinalEra. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . A reference system is characterized in terms of its domain of validity: the spatial and temporal extent over which it is applicable. The basic GML element for temporal reference systems is gml:TimeReferenceSystem. Its content model extends gml:DefinitionType with one additional property, gml:domainOfValidity. A temporal coordinate system shall be based on a continuous interval scale defined in terms of a single time interval. The differences to ISO 19108 TM_CoordinateSystem are: - the origin is specified either using the property gml:originPosition whose value is a direct time position, or using the property gml:origin whose model is gml:TimeInstantPropertyType; this permits more flexibility in representation and also supports referring to a value fixed elsewhere; - the interval uses gml:TimeIntervalLengthType. A calendar is a discrete temporal reference system that provides a basis for defining temporal position to a resolution of one day. gml:TimeCalendar adds one property to those inherited from gml:TimeReferenceSystem. A gml:referenceFrame provides a link to a gml:TimeCalendarEra that it uses. A gml:TimeCalendar may reference more than one calendar era. The referenceFrame element follows the standard GML property model, allowing the association to be instantiated either using an inline description using the gml:TimeCalendarEra element, or a link to a gml:TimeCalendarEra which is explicit elsewhere. gml:TimeCalendarEra inherits basic properties from gml:DefinitionType and has the following additional properties: - gml:referenceEvent is the name or description of a mythical or historic event which fixes the position of the base scale of the calendar era. This is given as text or using a link to description held elsewhere. - gml:referenceDate specifies the date of the referenceEvent expressed as a date in the given calendar. In most calendars, this date is the origin (i.e., the first day) of the scale, but this is not always true. - gml:julianReference specifies the Julian date that corresponds to the reference date. The Julian day number is an integer value; the Julian date is a decimal value that allows greater resolution. Transforming calendar dates to and from Julian dates provides a relatively simple basis for transforming dates from one calendar to another. - gml:epochOfUse is the period for which the calendar era was used as a basis for dating. gml:TimeCalendarPropertyType provides for associating a gml:TimeCalendar with an object. gml:TimeCalendarEraPropertyType provides for associating a gml:TimeCalendarEra with an object. A clock provides a basis for defining temporal position within a day. A clock shall be used with a calendar in order to provide a complete description of a temporal position within a specific day. gml:TimeClock adds the following properties to those inherited from gml:TimeReferenceSystemType: - gml:referenceEvent is the name or description of an event, such as solar noon or sunrise, which fixes the position of the base scale of the clock. - gml:referenceTime specifies the time of day associated with the reference event expressed as a time of day in the given clock. The reference time is usually the origin of the clock scale. - gml:utcReference specifies the 24 hour local or UTC time that corresponds to the reference time. - gml:dateBasis contains or references the calendars that use this clock. gml:TimeClockPropertyType provides for associating a gml:TimeClock with an object. In some applications of geographic information — such as geology and archaeology — relative position in time is known more precisely than absolute time or duration. The order of events in time can be well established, but the magnitude of the intervals between them cannot be accurately determined; in such cases, the use of an ordinal temporal reference system is appropriate. An ordinal temporal reference system is composed of a sequence of named coterminous eras, which may in turn be composed of sequences of member eras at a finer scale, giving the whole a hierarchical structure of eras of verying resolution. An ordinal temporal reference system whose component eras are not further subdivided is effectively a temporal topological complex constrained to be a linear graph. An ordinal temporal reference system some or all of whose component eras are subdivided is effectively a temporal topological complex with the constraint that parallel branches may only be constructed in pairs where one is a single temporal ordinal era and the other is a sequence of temporal ordinal eras that are called "members" of the "group". This constraint means that within a single temporal ordinal reference system, the relative position of all temporal ordinal eras is unambiguous. The positions of the beginning and end of a given era may calibrate the relative time scale. gml:TimeOrdinalReferenceSystem adds one or more gml:component properties to the generic temporal reference system model. Its content model follows the pattern of gml:TimeEdge, inheriting standard properties from gml:DefinitionType, and adding gml:start, gml:end and gml:extent properties, a set of gml:member properties which indicate ordered gml:TimeOrdinalEra elements, and a gml:group property which points to the parent era. The recursive inclusion of gml:TimeOrdinalEra elements allow the construction of an arbitrary depth hierarchical ordinal reference schema, such that an ordinal era at a given level of the hierarchy includes a sequence of shorter, coterminous ordinal eras. gml:TimeOrdinalEraPropertyType provides for associating a gml:TimeOrdinalEra with an object. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/temporalTopology.xsd ================================================ temporalTopology.xsd See ISO/DIS 19136 15.3. Temporal topology is described in terms of time complexes, nodes, and edges, and the connectivity between these. Temporal topology does not directly provide information about temporal position. It is used in the case of describing a lineage or a history (e.g. a family tree expressing evolution of species, an ecological cycle, a lineage of lands or buildings, or a history of separation and merger of administrative boundaries). The following Subclauses specifies the temporal topology as temporal characteristics of features in compliance with ISO 19108. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . gml:TimeTopologyPrimitive acts as the head of a substitution group for topological temporal primitives. Temporal topology primitives shall imply the ordering information between features or feature properties. The temporal connection of features can be examined if they have temporal topology primitives as values of their properties. Usually, an instantaneous feature associates with a time node, and a static feature associates with a time edge. A feature with both modes associates with the temporal topology primitive: a supertype of time nodes and time edges. A topological primitive is always connected to one or more other topological primitives, and is, therefore, always a member of a topological complex. In a GML instance, this will often be indicated by the primitives being described by elements that are descendents of an element describing a complex. However, in order to support the case where a temporal topological primitive is described in another context, the optional complex property is provided, which carries a reference to the parent temporal topological complex. gml:TimeTopologyPrimitivePropertyType provides for associating a gml:AbstractTimeTopologyPrimitive with an object. A temporal topology complex shall be the connected acyclic directed graph composed of temporal topological primitives, i.e. time nodes and time edges. Because a time edge may not exist without two time nodes on its boundaries, static features have time edges from a temporal topology complex as the values of their temporal properties, regardless of explicit declarations. A temporal topology complex expresses a linear or a non-linear graph. A temporal linear graph, composed of a sequence of time edges, provides a lineage described only by "substitution" of feature instances or feature element values. A time node as the start or the end of the graph connects with at least one time edge. A time node other than the start and the end shall connect to at least two time edges: one of starting from the node, and another ending at the node. A temporal topological complex is a set of connected temporal topological primitives. The member primtives are indicated, either by reference or by value, using the primitive property. gml:TimeTopologyComplexPropertyType provides for associating a gml:TimeTopologyComplex with an object. A time node is a zero-dimensional topological primitive that represents an identifiable node in time (it is equivalent to a point in space). A node may act as the termination or initiation of any number of time edges. A time node may be realised as a geometry, its position, whose value is a time instant. gml:TimeNodePropertyType provides for associating a gml:TimeNode with an object A time edge is a one-dimensional topological primitive. It is an open interval that starts and ends at a node. The edge may be realised as a geometry whose value is a time period. gml:TimeEdgePropertyType provides for associating a gml:TimeEdge with an object. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/topology.xsd ================================================ topology.xsd See ISO/DIS 19136 Clause 14. Topology is the branch of mathematics describing the properties of objects which are invariant under continuous deformation. For example, a circle is topologically equivalent to an ellipse because one can be transformed into the other by stretching. In geographic modelling, the foremost use of topology is in accelerating computational geometry. The constructs of topology allow characterisation of the spatial relationships between objects using simple combinatorial or algebraic algorithms. Topology, realised by the appropriate geometry, also allows a compact and unambiguous mechanism for expressing shared geometry among geographic features. There are four instantiable classes of primitive topology objects, one for each dimension up to 3D. In addition, topological complexes are supported, too. There is strong symmetry in the (topological boundary and coboundary) relationships between topology primitives of adjacent dimensions. Topology primitives are bounded by directed primitives of one lower dimension. The coboundary of each topology primitive is formed from directed topology primitives of one higher dimension. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This abstract type supplies the root or base type for all topological elements including primitives and complexes. It inherits AbstractGMLType and hence can be identified using the gml:id attribute. gml:AbstractTopoPrimitive acts as the base type for all topological primitives. Topology primitives are the atomic (smallest possible) units of a topology complex. Each topology primitive may contain references to other topology primitives of codimension 2 or more (gml:isolated). Conversely, nodes may have faces as containers and nodes and edges may have solids as containers (gml:container). In the case of planar topology, a gml:Node must have a clockwise sequence of gml:directedEdge properties, to ensure a lossless topology representation as defined by Kuijpers, et. al. (see OGC 05-102 Topology IPR). gml:Node represents the 0-dimensional primitive. The optional coboundary of a node (gml:directedEdge) is a sequence of directed edges which are incident on this node. Edges emanating from this node appear in the node coboundary with a negative orientation. If provided, the aggregationType attribute shall have the value "sequence". A node may optionally be realised by a 0-dimensional geometric primitive (gml:pointProperty). A gml:directedNode property element describes the boundary of topology edges and is used in the support of topological point features via the gml:TopoPoint expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included node is used: start ("-") or end ("+") node. gml:Edge represents the 1-dimensional primitive. The topological boundary of an Edge (gml:directedNode) consists of a negatively directed start Node and a positively directed end Node. The optional coboundary of an edge (gml:directedFace) is a circular sequence of directed faces which are incident on this edge in document order. In the 2D case, the orientation of the face on the left of the edge is "+"; the orientation of the face on the right on its right is "-". If provided, the aggregationType attribute shall have the value "sequence". An edge may optionally be realised by a 1-dimensional geometric primitive (gml:curveProperty). A gml:directedEdge property element describes the boundary of topology faces, the coBoundary of topology nodes and is used in the support of topological line features via the gml:TopoCurve expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included edge is used, i.e. forward or reverse. If the topological representation exists an unbounded manifold (e.g. Euclidean plane), a gml:Face must indicate whether it is a universal face or not, to ensure a lossless topology representation as defined by Kuijpers, et. al. (see OGC 05-102 Topology IPR). The optional universal attribute of type boolean is used to indicate this. NOTE The universal face is normally not part of any feature, and is used to represent the unbounded portion of the data set. Its interior boundary (it has no exterior boundary) would normally be considered the exterior boundary of the map represented by the data set. gml:Face represents the 2-dimensional topology primitive. The topological boundary of a face (gml:directedEdge) consists of a sequence of directed edges. If provided, the aggregationType attribute shall have the value "sequence". The optional coboundary of a face (gml:directedTopoSolid) is a pair of directed solids which are bounded by this face. A positively directed solid corresponds to a solid which lies in the direction of the negatively directed normal to the face in any geometric realisation. A face may optionally be realised by a 2-dimensional geometric primitive (gml:surfaceProperty). The gml:directedFace property element describes the boundary of topology solids, in the coBoundary of topology edges and is used in the support of surface features via the gml:TopoSurface expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included face is used i.e. inward or outward with respect to the surface normal in any geometric realisation. A gml:TopoSolid must indicate whether it is a universal topo-solid or not, to ensure a lossless topology representation as defined by Kuijpers, et. al. (see OGC 05-102 Topology IPR). The optional universal attribute of type boolean is used to indicate this and the default is fault. NOTE The universal topo-solid is normally not part of any feature, and is used to represent the unbounded portion of the data set. Its interior boundary (it has no exterior boundary) would normally be considered the exterior boundary of the data set. gml:TopoSolid represents the 3-dimensional topology primitive. The topological boundary of a solid (gml:directedFace) consists of a set of directed faces. A solid may optionally be realised by a 3-dimensional geometric primitive (gml:solidProperty). The gml:directedSolid property element describes the coBoundary of topology faces and is used in the support of volume features via the gml:TopoVolume expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included solid appears in the face coboundary. In the context of a gml:TopoVolume the orientation attribute has no meaning. The intended use of gml:TopoPoint is to appear within a point feature to express the structural and possibly geometric relationships of this feature to other features via shared node definitions. The gml:topoPointProperty property element may be used in features to express their relationship to the referenced topology node. gml:TopoCurve represents a homogeneous topological expression, a sequence of directed edges, which if realised are isomorphic to a geometric curve primitive. The intended use of gml:TopoCurve is to appear within a line feature to express the structural and geometric relationships of this feature to other features via the shared edge definitions. If provided, the aggregationType attribute shall have the value "sequence". The gml:topoCurveProperty property element may be used in features to express their relationship to the referenced topology edges. gml:TopoSurface represents a homogeneous topological expression, a set of directed faces, which if realised are isomorphic to a geometric surface primitive. The intended use of gml:TopoSurface is to appear within a surface feature to express the structural and possibly geometric relationships of this surface feature to other features via the shared face definitions. The gml:topoSurfaceProperty property element may be used in features to express their relationship to the referenced topology faces. gml:TopoVolume represents a homogeneous topological expression, a set of directed topologic solids, which if realised are isomorphic to a geometric solid primitive. The intended use of gml:TopoVolume is to appear within a solid feature to express the structural and geometric relationships of this solid feature to other features via the shared solid definitions. The gml:topoVolumeProperty element may be used in features to express their relationship to the referenced topology volume. gml:TopoComplex is a collection of topological primitives. Each complex holds a reference to its maximal complex (gml:maximalComplex) and optionally to sub- or super-complexes (gml:subComplex, gml:superComplex). A topology complex contains its primitive and sub-complex members. The property elements gml:subComplex, gml:superComplex and gml:maximalComplex provide an encoding for relationships between topology complexes as described for gml:TopoComplex above. The property elements gml:subComplex, gml:superComplex and gml:maximalComplex provide an encoding for relationships between topology complexes as described for gml:TopoComplex above. The property elements gml:subComplex, gml:superComplex and gml:maximalComplex provide an encoding for relationships between topology complexes as described for gml:TopoComplex above. The gml:topoPrimitiveMember property element encodes for the relationship between a topology complex and a single topology primitive. The gml:topoPrimitiveMembers property element encodes the relationship between a topology complex and an arbitrary number of topology primitives. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/units.xsd ================================================ units.xsd See ISO/DIS 17.2. Several GML Schema components concern or require a reference scale or units of measure. Units are required for quantities that may occur as values of properties of feature types, as the results of observations, in the range parameters of a coverage, and for measures used in Coordinate Reference System definitions. The basic unit definition is an extension of the general gml:Definition element defined in 16.2.1. Three specialized elements for unit definition are further derived from this. This model is based on the SI system of units [ISO 1000], which distinguishes between Base Units and Derived Units. - Base Units are the preferred units for a set of orthogonal fundamental quantities which define the particular system of units, which may not be derived by combination of other base units. - Derived Units are the preferred units for other quantities in the system, which may be defined by algebraic combination of the base units. In some application areas Conventional units are used, which may be converted to the preferred units using a scaling factor or a formula which defines a re-scaling and offset. The set of preferred units for all physical quantity types in a particular system of units is composed of the union of its base units and derived units. Unit definitions are substitutable for the gml:Definition element declared as part of the dictionary model. A dictionary that contains only unit definitions and references to unit definitions is a units dictionary. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . The element gml:unitOfMeasure is a property element to refer to a unit of measure. This is an empty element which carries a reference to a unit of measure definition. A gml:UnitDefinition is a general definition of a unit of measure. This generic element is used only for units for which no relationship with other units or units systems is known. The content model of gml:UnitDefinition adds three additional properties to gml:Definition, gml:quantityType, gml:quantityTypeReference and gml:catalogSymbol. The gml:catalogSymbol property optionally gives the short symbol used for this unit. This element is usually used when the relationship of this unit to other units or units systems is unknown. The gml:quantityType property indicates the phenomenon to which the units apply. This element contains an informal description of the phenomenon or type of physical quantity that is measured or observed. When the physical quantity is the result of an observation or measurement, this term is known as observable type or measurand. The use of gml:quantityType for references to remote values is deprecated. The gml:quantityTypeReference property indicates the phenomenon to which the units apply. The content is a reference to a remote value. The catalogSymbol is the preferred lexical symbol used for this unit of measure. The codeSpace attribute in gml:CodeType identifies a namespace for the catalog symbol value, and might reference the external catalog. The string value in gml:CodeType contains the value of a symbol that should be unique within this catalog namespace. This symbol often appears explicitly in the catalog, but it could be a combination of symbols using a specified algebra of units. A base unit is a unit of measure that cannot be derived by combination of other base units within a particular system of units. For example, in the SI system of units, the base units are metre, kilogram, second, Ampere, Kelvin, mole, and candela, for the physical quantity types length, mass, time interval, electric current, thermodynamic temperature, amount of substance and luminous intensity, respectively. gml:BaseUnit extends generic gml:UnitDefinition with the property gml:unitsSystem, which carries a reference to the units system to which this base unit is asserted to belong. Derived units are defined by combination of other units. Derived units are used for quantities other than those corresponding to the base units, such as hertz (s-1) for frequency, Newton (kg.m/s2) for force. Derived units based directly on base units are usually preferred for quantities other than the fundamental quantities within a system. If a derived unit is not the preferred unit, the gml:ConventionalUnit element should be used instead. The gml:DerivedUnit extends gml:UnitDefinition with the property gml:derivationUnitTerms. A set of gml:derivationUnitTerm elements describes a derived unit of measure. Each element carries an integer exponent. The terms are combined by raising each referenced unit to the power of its exponent and forming the product. This unit term references another unit of measure (uom) and provides an integer exponent applied to that unit in defining the compound unit. The exponent may be positive or negative, but not zero. Conventional units that are neither base units nor defined by direct combination of base units are used in many application domains. For example electronVolt for energy, feet and nautical miles for length. In most cases there is a known, usually linear, conversion to a preferred unit which is either a base unit or derived by direct combination of base units. The gml:ConventionalUnit extends gml:UnitDefinition with a property that describes a conversion to a preferred unit for this physical quantity. When the conversion is exact, the element gml:conversionToPreferredUnit should be used, or when the conversion is not exact the element gml:roughConversionToPreferredUnit is available. Both of these elements have the same content model. The gml:derivationUnitTerm property defined above is included to allow a user to optionally record how this unit may be derived from other ("more primitive") units. The elements gml:conversionToPreferredUnit and gml:roughConversionToPreferredUnit represent parameters used to convert conventional units to preferred units for this physical quantity type. A preferred unit is either a Base Unit or a Derived Unit that is selected for all values of one physical quantity type. The elements gml:conversionToPreferredUnit and gml:roughConversionToPreferredUnit represent parameters used to convert conventional units to preferred units for this physical quantity type. A preferred unit is either a Base Unit or a Derived Unit that is selected for all values of one physical quantity type. The inherited attribute uom references the preferred unit that this conversion applies to. The conversion of a unit to the preferred unit for this physical quantity type is specified by an arithmetic conversion (scaling and/or offset). The content model extends gml:UnitOfMeasureType, which has a mandatory attribute uom which identifies the preferred unit for the physical quantity type that this conversion applies to. The conversion is specified by a choice of - gml:factor, which defines the scale factor, or - gml:formula, which defines a formula by which a value using the conventional unit of measure can be converted to obtain the corresponding value using the preferred unit of measure. The formula defines the parameters of a simple formula by which a value using the conventional unit of measure can be converted to the corresponding value using the preferred unit of measure. The formula element contains elements a, b, c and d, whose values use the XML Schema type double. These values are used in the formula y = (a + bx) / (c + dx), where x is a value using this unit, and y is the corresponding value using the base unit. The elements a and d are optional, and if values are not provided, those parameters are considered to be zero. If values are not provided for both a and d, the formula is equivalent to a fraction with numerator and denominator parameters. ================================================ FILE: pycsw/core/schemas/ogc/gml/3.2.1/valueObjects.xsd ================================================ valueObjects.xsd See ISO/DIS 19136 17.5. The elements declared in this Clause build on other GML schema components, in particular gml:AbstractTimeObject, gml:AbstractGeometry, and the following types: gml:MeasureType, gml:MeasureListType, gml:CodeType, gml:CodeOrNilReasonListType, gml:BooleanOrNilReasonListType, gml:IntegerOrNilReasonList. Of particular interest are elements that are the heads of substitution groups, and one named choice group. These are the primary reasons for the value objects schema, since they may act as variables in the definition of content models, such as Observations, when it is desired to permit alternative value types to occur some of which may have complex content such as arrays, geometry and time objects, and where it is useful not to prescribe the actual value type in advance. The members of the groups include quantities, category classifications, boolean, count, temporal and spatial values, and aggregates of these. The value objects are defined in a hierarchy. The following relationships are defined: - Concrete elements gml:Quantity, gml:Category, gml:Count and gml:Boolean are substitutable for the abstract element gml:AbstractScalarValue. - Concrete elements gml:QuantityList, gml:CategoryList, gml:CountList and gml:BooleanList are substitutable for the abstract element gml:AbstractScalarValueList. - Concrete element gml:ValueArray is substitutable for the concrete element gml:CompositeValue. - Abstract elements gml:AbstractScalarValue and gml:AbstractScalarValueList, and concrete elements gml:CompositeValue, gml:ValueExtent, gml:CategoryExtent, gml:CountExtent and gml:QuantityExtent are substitutable for abstract element gml:AbstractValue. - Abstract elements gml:AbstractValue, gml:AbstractTimeObject and gml:AbstractGeometry are all in a choice group named gml:Value, which is used for compositing in gml:CompositeValue and gml:ValueExtent. - Schemas which need values may use the abstract element gml:AbstractValue in a content model in order to permit any of the gml:AbstractScalarValues, gml:AbstractScalarValueLists, gml:CompositeValue or gml:ValueExtent to occur in an instance, or the named group gml:Value to also permit gml:AbstractTimeObjects, gml:AbstractGeometrys. GML is an OGC Standard. Copyright (c) 2007,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . A gml:Category has an optional XML attribute codeSpace, whose value is a URI which identifies a dictionary, codelist or authority for the term. An XML attribute uom ("unit of measure") is required, whose value is a URI which identifies the definition of a ratio scale or units by which the numeric value shall be multiplied, or an interval or position scale on which the value occurs. gml:AbstractValue is an abstract element which acts as the head of a substitution group which contains gml:AbstractScalarValue, gml:AbstractScalarValueList, gml:CompositeValue and gml:ValueExtent, and (transitively) the elements in their substitution groups. These elements may be used in an application schema as variables, so that in an XML instance document any member of its substitution group may occur. gml:AbstractScalarValue is an abstract element which acts as the head of a substitution group which contains gml:Boolean, gml:Category, gml:Count and gml:Quantity, and (transitively) the elements in their substitution groups. gml:AbstractScalarValueList is an abstract element which acts as the head of a substitution group which contains gml:BooleanList, gml:CategoryList, gml:CountList and gml:QuantityList, and (transitively) the elements in their substitution groups. This is a convenience choice group which unifies generic values defined in this Clause with spatial and temporal objects and the measures described above, so that any of these may be used within aggregate values. Property that refers to, or contains, a Value. Convenience element for general use. Property that refers to, or contains, a Value. Property that contains Values. gml:CompositeValue is an aggregate value built from other values . It contains zero or an arbitrary number of gml:valueComponent elements, and zero or one gml:valueComponents property elements. It may be used for strongly coupled aggregates (vectors, tensors) or for arbitrary collections of values. A Value Array is used for homogeneous arrays of primitive and aggregate values. The member values may be scalars, composites, arrays or lists. ValueArray has the same content model as CompositeValue, but the member values shall be homogeneous. The element declaration contains a Schematron constraint which expresses this restriction precisely. Since the members are homogeneous, the gml:referenceSystem (uom, codeSpace) may be specified on the gml:ValueArray itself and inherited by all the members if desired. ================================================ FILE: pycsw/core/schemas/ogc/ogcapi/records/part1/1.0/ogcapi-records-1.yaml ================================================ openapi: 3.0.2 info: title: "Building Blocks specified in OGC API - Records - Part 1: Core" description: |- Common components used in the [OGC standard "OGC API - Records - Part 1: Core"] (https://docs.ogc.org/DRAFTS/20-004.html). OGC API - Records - Part 1: Core 1.0 is an OGC Standard. Copyright (c) 2020 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This document is also available on [OGC](http://schemas.opengis.net/ogcapi/records/part1/1.0/openapi/ogcapi-records-1.yaml). version: '1.0.0' contact: name: Panagiotis (Peter) A. Vretanos email: pvretano@pvretano.com license: name: OGC License url: 'http://www.opengeospatial.org/legal/' components: parameters: bbox: name: bbox in: query description: |- Only records that have a geometry that intersects the bounding box are selected. The bounding box is provided as four or six numbers, depending on whether the coordinate reference system includes a vertical axis (height or depth): * Lower left corner, coordinate axis 1 * Lower left corner, coordinate axis 2 * Minimum value, coordinate axis 3 (optional) * Upper right corner, coordinate axis 1 * Upper right corner, coordinate axis 2 * Maximum value, coordinate axis 3 (optional) The coordinate reference system of the values is WGS 84 long/lat (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless a different coordinate reference system is specified in the parameter `bbox-crs`. For WGS 84 longitude/latitude the values are in most cases the sequence of minimum longitude, minimum latitude, maximum longitude and maximum latitude. However, in cases where the box spans the antimeridian the first value (west-most box edge) is larger than the third value (east-most box edge). If the vertical axis is included, the third and the sixth number are the bottom and the top of the 3-dimensional bounding box. If a record has multiple spatial geometry properties, it is the decision of the server whether only a single spatial geometry property is used to determine the extent or all relevant geometries. required: false schema: type: array oneOf: - minItems: 4 maxItems: 4 - minItems: 6 maxItems: 6 items: type: number style: form explode: false datetime: name: datetime in: query description: |- Either a date-time or an interval, open or closed. Date and time expressions adhere to RFC 3339. Open intervals are expressed using double-dots. Examples: * A date-time: "2018-02-12T23:20:50Z" * A closed interval: "2018-02-12T00:00:00Z/2018-03-18T12:31:12Z" * Open intervals: "2018-02-12T00:00:00Z/.." or "../2018-03-18T12:31:12Z" Only records that have a temporal property that intersects the value of `datetime` are selected. It is left to the decision of the server whether only a single temporal property is used to determine the extent or all relevant temporal properties. required: false schema: type: string style: form explode: false limit: name: limit in: query description: |- The optional limit parameter limits the number of items that are presented in the response document. Only items are counted that are on the first level of the collection in the response document. Nested objects contained within the explicitly requested items shall not be counted. required: false schema: type: integer minimum: 1 maximum: 10000 default: 10 style: form explode: false q: name: q in: query description: |- The optional q parameter supports keyword searching. Only records whose text fields contain one or more of the specified search terms are selected. The specific set of text keys/fields/properties of a record to which the q operator is applied is up to the description of the server. Implementations should, however, apply the q operator to the title, description and keywords keys/fields/properties. required: false schema: type: array items: type: string explode: false style: form type: name: type in: query description: |- The optional type parameter supports searching by resource type. Only records whose type, as indicated by the value of the type core queryable, is equal to one of the listed values shall be selected. required: false schema: type: array items: type: string explode: false style: form externalId: name: externalId in: query description: |- The optional externalId parameter supports searching by an identifier that was not assigned by the catalogue (i.e. an external identifier). Only records with an external identifer, as indicated by the value of the externalId core queryable array, that is equal to one of the listed values shall be selected. required: false schema: type: array items: type: string explode: false style: form sortby: name: sortby in: query required: false schema: type: array minItems: 1 items: type: string pattern: '[+|-][A-Za-z_][A-Za-z_0-9]*' style: form explode: false collectionId: name: collectionId in: path description: local identifier of a collection required: true schema: type: string recordId: name: recordId in: path description: local identifier of a record required: true schema: type: string schemas: collectionInfo: type: object required: - id - links properties: id: description: identifier of the collection used, for example, in URIs type: string title: description: human readable title of the collection type: string description: description: a description of the records in the collection type: string links: type: array items: $ref: "#/components/schemas/link" extent: $ref: "#/components/schemas/extent" itemType: description: |- indicator about the type of the items in the collection (the default value is 'record' for OAPIR). type: string default: record crs: description: |- the list of coordinate reference systems supported by the service type: array items: type: string default: - http://www.opengis.net/def/crs/OGC/1.3/CRS84 collections: type: object required: - links - collections properties: links: type: array items: $ref: "#/components/schemas/link" collections: type: array items: $ref: "#/components/schemas/collectionInfo" confClasses: type: object required: - conformsTo properties: conformsTo: type: array items: type: string exception: type: object description: |- information about the exception; an error code plus an optional description. required: - code properties: code: type: string description: type: string extent: type: object description: |- The extent of the records in the collection. In the Core only spatial and temporal extents are specified. Extensions may add additional members to represent other extents, for example, thermal or pressure ranges. properties: spatial: description: |- The spatial extent of the records in the collection. type: object properties: bbox: description: |- One or more bounding boxes that describe the spatial extent of the dataset. In the Core only a single bounding box is supported. Extensions may support additional areas. If multiple areas are provided, the union of the bounding boxes describes the spatial extent. type: array minItems: 1 items: description: |- Each bounding box is provided as four or six numbers, depending on whether the coordinate reference system includes a vertical axis (height or depth): * Lower left corner, coordinate axis 1 * Lower left corner, coordinate axis 2 * Minimum value, coordinate axis 3 (optional) * Upper right corner, coordinate axis 1 * Upper right corner, coordinate axis 2 * Maximum value, coordinate axis 3 (optional) The coordinate reference system of the values is WGS 84 long/lat (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless a different coordinate reference system is specified in `crs`. For WGS 84 longitude/latitude the values are in most cases the sequence of minimum longitude, minimum latitude, maximum longitude and maximum latitude. However, in cases where the box spans the antimeridian the first value (west-most box edge) is larger than the third value (east-most box edge). If the vertical axis is included, the third and the sixth number are the bottom and the top of the 3-dimensional bounding box. If a record has multiple spatial geometry properties, it is the decision of the server whether only a single spatial geometry property is used to determine the extent or all relevant geometries. type: array oneOf: - minItems: 4 maxItems: 4 - minItems: 6 maxItems: 6 items: type: number example: - -180 - -90 - 180 - 90 crs: description: |- Coordinate reference system of the coordinates in the spatial extent (property `bbox`). The default reference system is WGS 84 longitude/latitude. In the Core this is the only supported coordinate reference system. Extensions may support additional coordinate reference systems and add additional enum values. type: string enum: - 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' default: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' temporal: description: |- The temporal extent of the records in the collection. type: object properties: interval: description: |- One or more time intervals that describe the temporal extent of the dataset. The value `null` is supported and indicates an open time interval. In the Core only a single time interval is supported. Extensions may support multiple intervals. If multiple intervals are provided, the union of the intervals describes the temporal extent. type: array minItems: 1 items: description: |- Begin and end times of the time interval. The timestamps are in the temporal coordinate reference system specified in `trs`. By default this is the Gregorian calendar. type: array minItems: 2 maxItems: 2 items: type: string format: date-time nullable: true example: - '2011-11-11T12:22:11Z' - null trs: description: |- Coordinate reference system of the coordinates in the temporal extent (property `interval`). The default reference system is the Gregorian calendar. In the Core this is the only supported temporal coordinate reference system. Extensions may support additional temporal coordinate reference systems and add additional enum values. type: string enum: - 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian' default: 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian' featureCollectionGeoJSON: type: object required: - type - features properties: type: type: string enum: - FeatureCollection features: type: array items: $ref: "#/components/schemas/recordGeoJSON" links: type: array items: $ref: "#/components/schemas/link" timeStamp: $ref: "#/components/schemas/timeStamp" numberMatched: $ref: "#/components/schemas/numberMatched" numberReturned: $ref: "#/components/schemas/numberReturned" recordGeoJSON: type: object required: - id - type - geometry - properties properties: id: type: string description: A unique identifier of the catalogue record. format: uri type: type: string enum: - Feature geometry: $ref: "#/components/schemas/geometryGeoJSON" properties: type: object required: - type - title properties: recordCreated: type: string description: Date of creation of this record. format: date-time recordUpdated: type: string description: The most recent date on which the record was changed. format: date-time type: type: string description: The nature or genre of the resource. format: uri title: type: string description: A human-readable name given to the resource. description: type: string description: A free-text account of the resource. keywords: type: array description: |- The topic or topics of the resource. Typically represented using keywords, tags, key phrases, or classification codes. Recommended best practice is to use a controlled vocabulary. items: type: string keywordsCodespace: type: string description: |- A reference to a controlled vocabulary used for the keywords. format: uri language: type: string description: |- The natural language used for textual values (e.g. titles, descriptions, etc.) of the resource. ISO 639-1/639-2 codes should be used. default: en externalId: type: array description: |- An identifier for the resource assigned by an external (to the catalogue) entity. items: type: string created: type: string description: Date of creation of the resource. format: date-time updated: type: string description: Most recent date on which the resource was changed. format: date-time publisher: type: string description: |- Link to the entity making the resource available. Recommended best practice is to use a VCard (see http://www.w3.org/TR/vcard-rdf/). format: uri themes: type: array description: |- A knowledge organization system used to classify the resource. items: type: object properties: scheme: type: string description: |- An identifier for the knowledge organization system used to classify the resource. It is recommended that the identifier by a resolvable URI. concepts: type: array description: |- One or more entity/concept identifers from this knowledge system. it is recommended that a resolvable URI be used for each entity/concept identifier. items: type: string formats: type: array description: A list of available distributions of the resource. items: type: string contactPoint: type: string description: |- Link to relevant contact information. Recommended best practice is to use a VCard (see http://www.w3.org/TR/vcard-rdf/). format: uri license: type: string description: |- A legal document under which the resource is made available. format: uri rights: type: string description: |- A statement that concerns all rights not addresses by the license such as a copyright statement. extent: $ref: "#/components/schemas/extent" associations: type: array description: |- A list of links for accessing the resource (e.g. download link, access link) in one of the supported distribution formats and/or links to other resources associated with this resource. items: $ref: "#/components/schemas/link" additionalProperties: true links: type: array description: |- A list of links for navigating the API (e.g. prev, next, etc.). items: $ref: "#/components/schemas/link" geometryGeoJSON: oneOf: - $ref: "#/components/schemas/pointGeoJSON" - $ref: "#/components/schemas/multipointGeoJSON" - $ref: "#/components/schemas/linestringGeoJSON" - $ref: "#/components/schemas/multilinestringGeoJSON" - $ref: "#/components/schemas/polygonGeoJSON" - $ref: "#/components/schemas/multipolygonGeoJSON" - $ref: "#/components/schemas/geometrycollectionGeoJSON" geometrycollectionGeoJSON: type: object required: - type - geometries properties: type: type: string enum: - GeometryCollection geometries: type: array items: $ref: "#/components/schemas/geometryGeoJSON" landingPage: type: object required: - links properties: title: type: string description: type: string links: type: array items: $ref: "#/components/schemas/link" linestringGeoJSON: type: object required: - type - coordinates properties: type: type: string enum: - LineString coordinates: type: array minItems: 2 items: type: array minItems: 2 items: type: number link: type: object required: - href properties: href: type: string rel: type: string type: type: string hreflang: type: string title: type: string length: type: integer multilinestringGeoJSON: type: object required: - type - coordinates properties: type: type: string enum: - MultiLineString coordinates: type: array items: type: array minItems: 2 items: type: array minItems: 2 items: type: number multipointGeoJSON: type: object required: - type - coordinates properties: type: type: string enum: - MultiPoint coordinates: type: array items: type: array minItems: 2 items: type: number multipolygonGeoJSON: type: object required: - type - coordinates properties: type: type: string enum: - MultiPolygon coordinates: type: array items: type: array items: type: array minItems: 4 items: type: array minItems: 2 items: type: number numberMatched: description: |- The number of records of the record type that match the selection parameters like `bbox`. type: integer minimum: 0 numberReturned: description: |- The number of records in the record collection. A server may omit this information in a response, if the information about the number of records is not known or difficult to compute. If the value is provided, the value shall be identical to the number of items in the "records" array. type: integer minimum: 0 pointGeoJSON: type: object required: - type - coordinates properties: type: type: string enum: - Point coordinates: type: array minItems: 2 items: type: number polygonGeoJSON: type: object required: - type - coordinates properties: type: type: string enum: - Polygon coordinates: type: array items: type: array minItems: 4 items: type: array minItems: 2 items: type: number sortable: type: object required: - id properties: id: description: the identifier/name for the sortable type: string title: description: a human readable title for the sortable type: string description: description: a human-readable narrative describing the sortable type: string language: description: the language used for the title and description type: string links: type: array items: $ref: "#/components/schemas/link" timeStamp: description: |- This property indicates the time and date when the response was generated. type: string format: date-time example: '2017-08-17T08:05:32Z' responses: LandingPage: description: |- The landing page provides links to the API definition (link relations `service-desc` and `service-doc`), the Conformance declaration (path `/conformance`, link relation `conformance`), and the Record Collections (path `/collections`, link relation `data`). content: application/json: schema: $ref: '#/components/schemas/landingPage' text/html: schema: type: string ConformanceDeclaration: description: |- The URIs of all conformance classes supported by the server. To support "generic" clients that want to access multiple OGC API Records implementations - and not "just" a specific API / server, the server declares the conformance classes it implements and conforms to. content: application/json: schema: $ref: '#/components/schemas/confClasses' text/html: schema: type: string Collections: description: |- The record collections shared by this API. Catalogues are organized as one or more record collections. This resource provides information about and access to these collections. The response contains the list of record collections (itemType=record). For each record collection, a link to the items in the collection (path `/collections/{collectionId}/items`, link relation `items`) as well as key information about the collection. This information includes... * A local identifier for the collection that is unique for the + catalogue; * A list of coordinate reference systems (CRS) in which geometries + may be returned by the server. The first CRS is the default + coordinate reference system (the default is always WGS 84 with axis + order longitude/latitude); * An optional title and description for the collection; * An optional extent that can be used to provide an indication of the + spatial and temporal extent of the collection - typically derived + from the data; * An optional indicator about the type of the items in the collection + (the default value, if the indicator is not provided, is 'record'). content: application/json: schema: $ref: '#/components/schemas/collections' text/html: schema: type: string Collection: description: |- Information about the record collection with id `collectionId`. The response contains a link to the items in the collection (path `/collections/{collectionId}/items`, link relation `items`) as well as key information about the collection. This information includes: * A local identifier for the collection that is unique for the + catalogue; * A list of coordinate reference systems (CRS) in which geometries + may be returned by the server. The first CRS is the default + coordinate reference system (the default is always WGS 84 with + axis order longitude/latitude); * An optional title and description for the collection; * An optional extent that can be used to provide an indication of + the spatial and temporal extent of the collection - typically + derived from the data; * An optional indicator about the type of the items in the collection + (the default value, if the indicator is not provided, is 'record'). content: application/json: schema: $ref: '#/components/schemas/collectionInfo' text/html: schema: type: string Records: description: |- The response is a document consisting of records in the collection. The records included in the response are determined by the server based on the query parameters of the request. To support access to larger collections without overloading the client, the API supports paged access with links to the next page, if more records are selected that the page size. The `bbox` and `datetime` parameter can be used to select only a subset of the records in the collection (the records that are in the bounding box or time interval). The `bbox` parameter matches all records in the collection that are not associated with a location, too. The `datetime` parameter matches all records in the collection that are not associated with a time stamp or interval, too. The `limit` parameter may be used to control the subset of the selected records that should be returned in the response, the page size. Each page may include information about the number of selected and returned records (`numberMatched` and `numberReturned`) as well as links to support paging (link relation `next`). The XML representation of the response document is an ATOM feed. content: application/geo+json: schema: $ref: '#/components/schemas/featureCollectionGeoJSON' text/html: schema: type: string application/atom+xml: schema: type: string Record: description: |- Fetch the record with id `recordId` in the record collection with id `collectionId`. The XML representation of a record is an ATOM entry. content: application/geo+json: schema: $ref: '#/components/schemas/recordGeoJSON' text/html: schema: type: string application/atom+xml: schema: type: string Sortables: type: array items: $ref: "#/components/schemas/sortable" OpenSearchDescriptionDocument: description: |- description document for OpenSearch clients content: application/opensearchdescription+xml: schema: type: string InvalidParameter: description: |- A query parameter has an invalid value. content: application/json: schema: $ref: '#/components/schemas/exception' text/html: schema: type: string NotFound: description: |- The requested resource does not exist on the server. For example, a path parameter had an incorrect value. NotAcceptable: description: |- Content negotiation failed. For example, the `Accept` header submitted in the request did not support any of the media types supported by the server for the requested resource. ServerError: description: |- A server error occurred. content: application/json: schema: $ref: '#/components/schemas/exception' text/html: schema: type: string ================================================ FILE: pycsw/core/schemas/ogc/ows/1.0.0/ows19115subset.xsd ================================================ ows19115subset.xsd 2010-01-30 This XML Schema Document encodes the parts of ISO 19115 used by the common "ServiceIdentification" and "ServiceProvider" sections of the GetCapabilities operation response, known as the service metadata XML document. The parts encoded here are the MD_Keywords, CI_ResponsibleParty, and related classes. This XML Schema largely follows the current draft for ISO 19139, with the addition of documentation text extracted and edited from Annex B of ISO 19115. The UML package prefixes were omitted from XML names, and the XML element names were all capitalized, for consistency with other OWS Schemas. Also, the optional smXML:id attributes were omitted, as not being useful in a service metadata document. OWS is an OGC Standard. Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Title of this resource, normally used for display to a human. Brief narrative description of this resource, normally used for display to a human. Unordered list of one or more commonly used or formalised word(s) or phrase(s) used to describe the subject. When needed, the optional "type" can name the type of the associated list of keywords that shall all have the same type. Also when needed, the codeSpace attribute of that "type" can reference the type name authority and/or thesaurus. For OWS use, the optional thesaurusName element was omitted as being complex information that could be referenced by the codeSpace attribute of the Type element. Name or code with an (optional) authority. If the codeSpace attribute is present, its value should reference a dictionary, thesaurus, or authority for the name or code, such as the organisation who assigned the value, or the dictionary from which it is taken. Type copied from basicTypes.xsd of GML 3 with documentation edited, for possible use outside the ServiceIdentification section of a service metadata document. Identification of, and means of communication with, person(s) responsible for the resource(s). For OWS use in the ServiceProvider section of a service metadata document, the optional organizationName element was removed, since this type is always used with the ProviderName element which provides that information. The optional individualName element was made mandatory, since either the organizationName or individualName element is mandatory. The mandatory "role" element was changed to optional, since no clear use of this information is known in the ServiceProvider section. Identification of, and means of communication with, person responsible for the server. At least one of IndividualName, OrganisationName, or PositionName shall be included. Identification of, and means of communication with, person responsible for the server. For OWS use in the ServiceProvider section of a service metadata document, the optional organizationName element was removed, since this type is always used with the ProviderName element which provides that information. The mandatory "role" element was changed to optional, since no clear use of this information is known in the ServiceProvider section. Name of the responsible person: surname, given name, title separated by a delimiter. Name of the responsible organization. Role or position of the responsible person. Function performed by the responsible party. Possible values of this Role shall include the values and the meanings listed in Subclause B.5.5 of ISO 19115:2003. Address of the responsible party. Information required to enable contact with the responsible person and/or organization. For OWS use in the service metadata document, the optional hoursOfService and contactInstructions elements were retained, as possibly being useful in the ServiceProvider section. Telephone numbers at which the organization or individual may be contacted. Physical and email address at which the organization or individual may be contacted. On-line information that can be used to contact the individual or organization. OWS specifics: The xlink:href attribute in the xlink:simpleAttrs attribute group shall be used to reference this resource. Whenever practical, the xlink:href attribute with type anyURI should be a URL from which more contact information can be electronically retrieved. The xlink:title attribute with type "string" can be used to name this set of information. The other attributes in the xlink:simpleAttrs attribute group should not be used. Time period (including time zone) when individuals can contact the organization or individual. Supplemental instructions on how or when to contact the individual or organization. Reference to on-line resource from which data can be obtained. For OWS use in the service metadata document, the CI_OnlineResource class was XML encoded as the attributeGroup "xlink:simpleAttrs", as used in GML. Telephone numbers for contacting the responsible individual or organization. Telephone number by which individuals can speak to the responsible organization or individual. Telephone number of a facsimile machine for the responsible organization or individual. Location of the responsible individual or organization. Address line for the location. City of the location. State or province of the location. ZIP or other postal code. Country of the physical address. Address of the electronic mailbox of the responsible organization or individual. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.0.0/owsAll.xsd ================================================ owsAll.xsd 2010-01-30 This XML Schema Document includes and imports, directly and indirectly, all the XML Schemas defined by the OWS Common Implemetation Specification. OWS is an OGC Standard. Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/ows/1.0.0/owsCommon.xsd ================================================ owsCommon.xsd 2010-01-30 This XML Schema Document encodes various parameters and parameter types that can be used in OWS operation requests and responses. OWS is an OGC Standard. Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . XML encoded identifier of a standard MIME type, possibly a parameterized MIME type. Specification version for OWS operation. The string value shall contain one x.y.z "version" value (e.g., "2.1.3"). A version number shall contain three non-negative integers separated by decimal points, in the form "x.y.z". The integers y and z shall not exceed 99. Each version shall be for the Implementation Specification (document) and the associated XML Schemas to which requested operations will conform. An Implementation Specification version normally specifies XML Schemas against which an XML encoded operation response must conform and should be validated. See Version negotiation subclause for more information. This element either references or contains more metadata about the element that includes this element. To reference metadata stored remotely, at least the xlinks:href attribute in xlink:simpleAttrs shall be included. Either at least one of the attributes in xlink:simpleAttrs or a substitute for the AbstractMetaData element shall be included, but not both. An Implementation Specification can restrict the contents of this element to always be a reference or always contain metadata. (Informative: This element was adapted from the metaDataProperty element in GML 3.0.) Reference to metadata recorded elsewhere, either external to this XML document or within it. Whenever practical, the xlink:href attribute with type anyURI should include a URL from which this metadata can be electronically retrieved. Optional reference to the aspect of the element which includes this "metadata" element that this metadata provides more information about. Abstract element containing more metadata about the element that includes the containing "metadata" element. A specific server implementation, or an Implementation Specification, can define concrete elements in the AbstractMetaData substitution group. XML encoded minimum rectangular bounding box (or region) parameter, surrounding all the associated data. This type is adapted from the EnvelopeType of GML 3.1, with modified contents and documentation for encoding a MINIMUM size box SURROUNDING all associated data. Position of the bounding box corner at which the value of each coordinate normally is the algebraic minimum within this bounding box. In some cases, this position is normally displayed at the top, such as the top left for some image coordinates. For more information, see Subclauses 10.2.5 and C.13. Position of the bounding box corner at which the value of each coordinate normally is the algebraic maximum within this bounding box. In some cases, this position is normally displayed at the bottom, such as the bottom right for some image coordinates. For more information, see Subclauses 10.2.5 and C.13. Usually references the definition of a CRS, as specified in [OGC Topic 2]. Such a CRS definition can be XML encoded using the gml:CoordinateReferenceSystemType in [GML 3.1]. For well known references, it is not required that a CRS definition exist at the location the URI points to. If no anyURI value is included, the applicable CRS must be either: a) Specified outside the bounding box, but inside a data structure that includes this bounding box, as specified for a specific OWS use of this bounding box type. b) Fixed and specified in the Implementation Specification for a specific OWS use of the bounding box type. The number of dimensions in this CRS (the length of a coordinate sequence in this use of the PositionType). This number is specified by the CRS definition, but can also be specified here. Position instances hold the coordinates of a position in a coordinate reference system (CRS) referenced by the related "crs" attribute or elsewhere. For an angular coordinate axis that is physically continuous for multiple revolutions, but whose recorded values can be discontinuous, special conditions apply when the bounding box is continuous across the value discontinuity: a) If the bounding box is continuous clear around this angular axis, then ordinate values of minus and plus infinity shall be used. b) If the bounding box is continuous across the value discontinuity but is not continuous clear around this angular axis, then some non-normal value can be used if specified for a specific OWS use of the BoundingBoxType. For more information, see Subclauses 10.2.5 and C.13. This type is adapted from DirectPositionType and doubleList of GML 3.1. The adaptations include omission of all the attributes, since the needed information is included in the BoundingBoxType. XML encoded minimum rectangular bounding box (or region) parameter, surrounding all the associated data. This box is specialized for use with the 2D WGS 84 coordinate reference system with decimal values of longitude and latitude. This type is adapted from the general BoundingBoxType, with modified contents and documentation for use with the 2D WGS 84 coordinate reference system. Position of the bounding box corner at which the values of longitude and latitude normally are the algebraic minimums within this bounding box. For more information, see Subclauses 10.4.5 and C.13. Position of the bounding box corner at which the values of longitude and latitude normally are the algebraic minimums within this bounding box. For more information, see Subclauses 10.4.5 and C.13. This attribute can be included when considered useful. When included, this attribute shall reference the 2D WGS 84 coordinate reference system with longitude before latitude and decimal values of longitude and latitude. The number of dimensions in this CRS (the length of a coordinate sequence in this use of the PositionType). This number is specified by the CRS definition, but can also be specified here. Two-dimensional position instances hold the longitude and latitude coordinates of a position in the 2D WGS 84 coordinate reference system. The longitude value shall be listed first, followed by the latitude value, both in decimal degrees. Latitude values shall range from -90 to +90 degrees, and longitude values shall normally range from -180 to +180 degrees. For the longitude axis, special conditions apply when the bounding box is continuous across the +/- 180 degrees meridian longitude value discontinuity: a) If the bounding box is continuous clear around the Earth, then longitude values of minus and plus infinity shall be used. b) If the bounding box is continuous across the value discontinuity but is not continuous clear around the Earth, then some non-normal value can be used if specified for a specific OWS use of the WGS84BoundingBoxType. For more information, see Subclauses 10.4.5 and C.13. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd ================================================ owsDataIdentification.xsd 2010-01-30 This XML Schema Document encodes the parts of the MD_DataIdentification class of ISO 19115 (OGC Abstract Specification Topic 11) which are expected to be used for most datasets. This Schema also encodes the parts of this class that are expected to be useful for other metadata. Both are expected to be used within the Contents section of OWS service metadata (Capabilities) documents. OWS is an OGC Standard. Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Human-readable descriptive information for the object it is included within. This type shall be extended if needed for specific OWS use to include additional metadata for each type of information. This type shall not be restricted for a specific OWS to change the multiplicity (or optionality) of some elements. General metadata identifying and describing a set of data. This type shall be extended if needed for each specific OWS to include additional metadata for each type of dataset. If needed, this type should first be restricted for each specific OWS to change the multiplicity (or optionality) of some elements. Optional unique identifier or name of this dataset. Unordered list of zero or more bounding boxes whose union describes the extent of this dataset. Unordered list of zero or more references to data formats supported for server outputs. Unordered list of zero or more available coordinate reference systems. Optional unordered list of additional metadata about this data(set). A list of optional metadata elements for this data identification could be specified in the Implementation Specification for this service. Unique identifier or name of this dataset. Reference to a format in which this data can be encoded and transferred. More specific parameter names should be used by specific OWS specifications wherever applicable. More than one such parameter can be included for different purposes. Coordinate reference system in which data from this data(set) or resource is available or supported. More specific parameter names should be used by specific OWS specifications wherever applicable. More than one such parameter can be included for different purposes. Access constraint applied to assure the protection of privacy or intellectual property, or any other restrictions on retrieving or using data from or otherwise using this server. The reserved value NONE (case insensitive) shall be used to mean no access constraints are imposed. Fees and terms for retrieving data from or otherwise using this server, including the monetary units as specified in ISO 4217. The reserved value NONE (case insensitive) shall be used to mean no fees or terms. Identifier of a language used by the data(set) contents. This language identifier shall be as specified in IETF RFC 1766. When this element is omitted, the language used is not identified. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd ================================================ owsExceptionReport.xsd 2010-01-30 This XML Schema Document encodes the Exception Report response to all OWS operations. OWS is an OGC Standard. Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Report message returned to the client that requested any OWS operation when the server detects an error while processing that operation request. Unordered list of one or more Exception elements that each describes an error. These Exception elements shall be interpreted by clients as being independent of one another (not hierarchical). Specification version for OWS operation. The string value shall contain one x.y.z "version" value (e.g., "2.1.3"). A version number shall contain three non-negative integers separated by decimal points, in the form "x.y.z". The integers y and z shall not exceed 99. Each version shall be for the Implementation Specification (document) and the associated XML Schemas to which requested operations will conform. An Implementation Specification version normally specifies XML Schemas against which an XML encoded operation response must conform and should be validated. See Version negotiation subclause for more information. Identifier of the language used by all included exception text values. These language identifiers shall be as specified in IETF RFC 1766. When this attribute is omitted, the language used is not identified. An Exception element describes one detected error that a server chooses to convey to the client. Ordered sequence of text strings that describe this specific exception or error. The contents of these strings are left open to definition by each server implementation. A server is strongly encouraged to include at least one ExceptionText value, to provide more information about the detected error than provided by the exceptionCode. When included, multiple ExceptionText values shall provide hierarchical information about one detected error, with the most significant information listed first. A code representing the type of this exception, which shall be selected from a set of exceptionCode values specified for the specific service operation and server. When included, this locator shall indicate to the client where an exception was encountered in servicing the client's operation request. This locator should be included whenever meaningful information can be provided by the server. The contents of this locator will depend on the specific exceptionCode and OWS service, and shall be specified in the OWS Implementation Specification. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd ================================================ owsGetCapabilities.xsd 2010-01-30 This XML Schema Document defines the GetCapabilities operation request and response XML elements and types, which are common to all OWSs. This XML Schema shall be edited by each OWS, for example, to specify a specific value for the "service" attribute. OWS is an OGC Standard. Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . XML encoded GetCapabilities operation response. This document provides clients with service metadata about a specific service instance, usually including metadata about the tightly-coupled data served. If the server does not implement the updateSequence parameter, the server shall always return the complete Capabilities document, without the updateSequence parameter. When the server implements the updateSequence parameter and the GetCapabilities operation request included the updateSequence parameter with the current value, the server shall return this element with only the "version" and "updateSequence" attributes. Otherwise, all optional elements shall be included or not depending on the actual value of the Contents parameter in the GetCapabilities operation request. This base type shall be extended by each specific OWS to include the additional contents needed. XML encoded GetCapabilities operation request. This operation allows clients to retrieve service metadata about a specific service instance. In this XML encoding, no "request" parameter is included, since the element name specifies the specific operation. This base type shall be extended by each specific OWS to include the additional required "service" attribute, with the correct value for that OWS. When omitted, server shall return latest supported version. When omitted or not supported by server, server shall return complete service metadata (Capabilities) document. When omitted or not supported by server, server shall return service metadata document using the MIME type "text/xml". When omitted or not supported by server, server shall return latest complete service metadata document. Service type identifier, where the string value is the OWS type abbreviation, such as "WMS" or "WFS". Prioritized sequence of one or more specification versions accepted by client, with preferred versions listed first. See Version negotiation subclause for more information. Unordered list of zero or more names of requested sections in complete service metadata document. Each Section value shall contain an allowed section name as specified by each OWS specification. See Sections parameter subclause for more information. Service metadata document version, having values that are "increased" whenever any change is made in service metadata document. Values are selected by each server, and are always opaque to clients. See updateSequence parameter use subclause for more information. Prioritized sequence of zero or more GetCapabilities operation response formats desired by client, with preferred formats listed first. Each response format shall be identified by its MIME type. See AcceptFormats parameter use subclause for more information. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd ================================================ owsOperationsMetadata.xsd 2010-01-30 This XML Schema Document encodes the basic contents of the "OperationsMetadata" section of the GetCapabilities operation response, also known as the Capabilities XML document. OWS is an OGC Standard. Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Metadata about the operations and related abilities specified by this service and implemented by this server, including the URLs for operation requests. The basic contents of this section shall be the same for all OWS types, but individual services can add elements and/or change the optionality of optional elements. Metadata for unordered list of all the (requests for) operations that this server interface implements. The list of required and optional operations implemented shall be specified in the Implementation Specification for this service. Optional unordered list of parameter valid domains that each apply to one or more operations which this server interface implements. The list of required and optional parameter domain limitations shall be specified in the Implementation Specification for this service. Optional unordered list of valid domain constraints on non-parameter quantities that each apply to this server. The list of required and optional constraints shall be specified in the Implementation Specification for this service. Individual software vendors and servers can use this element to provide metadata about any additional server abilities. Metadata for one operation that this server implements. Unordered list of Distributed Computing Platforms (DCPs) supported for this operation. At present, only the HTTP DCP is defined, so this element will appear only once. Optional unordered list of parameter domains that each apply to this operation which this server implements. If one of these Parameter elements has the same "name" attribute as a Parameter element in the OperationsMetadata element, this Parameter element shall override the other one for this operation. The list of required and optional parameter domain limitations for this operation shall be specified in the Implementation Specification for this service. Optional unordered list of valid domain constraints on non-parameter quantities that each apply to this operation. If one of these Constraint elements has the same "name" attribute as a Constraint element in the OperationsMetadata element, this Constraint element shall override the other one for this operation. The list of required and optional constraints for this operation shall be specified in the Implementation Specification for this service. Optional unordered list of additional metadata about this operation and its' implementation. A list of required and optional metadata elements for this operation should be specified in the Implementation Specification for this service. (Informative: This metadata might specify the operation request parameters or provide the XML Schemas for the operation request.) Name or identifier of this operation (request) (for example, GetCapabilities). The list of required and optional operations implemented shall be specified in the Implementation Specification for this service. Information for one distributed Computing Platform (DCP) supported for this operation. At present, only the HTTP DCP is defined, so this element only includes the HTTP element. Connect point URLs for the HTTP Distributed Computing Platform (DCP). Normally, only one Get and/or one Post is included in this element. More than one Get and/or Post is allowed to support including alternative URLs for uses such as load balancing or backup. Connect point URL prefix and any constraints for the HTTP "Get" request method for this operation request. Connect point URL and any constraints for the HTTP "Post" request method for this operation request. Connect point URL and any constraints for this HTTP request method for this operation request. In the OnlineResourceType, the xlink:href attribute in the xlink:simpleAttrs attribute group shall be used to contain this URL. The other attributes in the xlink:simpleAttrs attribute group should not be used. Optional unordered list of valid domain constraints on non-parameter quantities that each apply to this request method for this operation. If one of these Constraint elements has the same "name" attribute as a Constraint element in the OperationsMetadata or Operation element, this Constraint element shall override the other one for this operation. The list of required and optional constraints for this request method for this operation shall be specified in the Implementation Specification for this service. Valid domain (or set of values) of one parameter or other quantity used by this server. A non-parameter quantity may not be explicitly represented in the server software. (Informative: An example is the outputFormat parameter of a WFS. Each WFS server should provide a Parameter element for the outputFormat parameter that lists the supported output formats, such as GML2, GML3, etc. as the allowed "Value" elements.) Unordered list of all the valid values for this parameter or other quantity. For those parameters that contain a list or sequence of values, these values shall be for individual values in the list. The allowed set of values and the allowed server restrictions on that set of values shall be specified in the Implementation Specification for this service. Optional unordered list of additional metadata about this parameter. A list of required and optional metadata elements for this domain should be specified in the Implementation Specification for this service. (Informative: This metadata might specify the meanings of the valid values.) Name or identifier of this parameter or other quantity. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd ================================================ owsServiceIdentification.xsd 2010-01-30 This XML Schema Document encodes the common "ServiceIdentification" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceIdentification class of ISO 19119 (OGC Abstract Specification Topic 12). OWS is an OGC Standard. Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . General metadata for this specific server. This XML Schema of this section shall be the same for all OWS. A service type name from a registry of services. For example, the values of the codeSpace URI and name and code string may be "OGC" and "catalogue." This type name is normally used for machine-to-machine communication. Unordered list of one or more versions of this service type implemented by this server. This information is not adequate for version negotiation, and shall not be used for that purpose. If this element is omitted, no meaning is implied. Unordered list of access constraints applied to assure the protection of privacy or intellectual property, and any other restrictions on retrieving or using data from or otherwise using this server. The reserved value NONE (case insensitive) shall be used to mean no access constraints are imposed. If this element is omitted, no meaning is implied. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd ================================================ owsServiceProvider.xsd 2010-01-30 This XML Schema Document encodes the common "ServiceProvider" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceProvider class of ISO 19119 (OGC Abstract Specification Topic 12). OWS is an OGC Standard. Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Metadata about the organization that provides this specific service instance or server. A unique identifier for the service provider organization. Reference to the most relevant web site of the service provider. Information for contacting the service provider. The OnlineResource element within this ServiceContact element should not be used to reference a web site of the service provider. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/ows19115subset.xsd ================================================ ows19115subset.xsd This XML Schema Document encodes the parts of ISO 19115 used by the common "ServiceIdentification" and "ServiceProvider" sections of the GetCapabilities operation response, known as the service metadata XML document. The parts encoded here are the MD_Keywords, CI_ResponsibleParty, and related classes. The UML package prefixes were omitted from XML names, and the XML element names were all capitalized, for consistency with other OWS Schemas. This document also provides a simple coding of text in multiple languages, simplified from Annex J of ISO 19115. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Text string with the language of the string identified as recommended in the XML 1.0 W3C Recommendation, section 2.12. Title of this resource, normally used for display to a human. Brief narrative description of this resource, normally used for display to a human. Unordered list of one or more commonly used or formalised word(s) or phrase(s) used to describe the subject. When needed, the optional "type" can name the type of the associated list of keywords that shall all have the same type. Also when needed, the codeSpace attribute of that "type" can reference the type name authority and/or thesaurus. If the xml:lang attribute is not included in a Keyword element, then no language is specified for that element unless specified by another means. All Keyword elements in the same Keywords element that share the same xml:lang attribute value represent different keywords in that language. For OWS use, the optional thesaurusName element was omitted as being complex information that could be referenced by the codeSpace attribute of the Type element. Name or code with an (optional) authority. If the codeSpace attribute is present, its value shall reference a dictionary, thesaurus, or authority for the name or code, such as the organisation who assigned the value, or the dictionary from which it is taken. Type copied from basicTypes.xsd of GML 3 with documentation edited, for possible use outside the ServiceIdentification section of a service metadata document. Identification of, and means of communication with, person(s) responsible for the resource(s). For OWS use in the ServiceProvider section of a service metadata document, the optional organizationName element was removed, since this type is always used with the ProviderName element which provides that information. The optional individualName element was made mandatory, since either the organizationName or individualName element is mandatory. The mandatory "role" element was changed to optional, since no clear use of this information is known in the ServiceProvider section. Identification of, and means of communication with, person responsible for the server. At least one of IndividualName, OrganisationName, or PositionName shall be included. Identification of, and means of communication with, person responsible for the server. For OWS use in the ServiceProvider section of a service metadata document, the optional organizationName element was removed, since this type is always used with the ProviderName element which provides that information. The mandatory "role" element was changed to optional, since no clear use of this information is known in the ServiceProvider section. Name of the responsible person: surname, given name, title separated by a delimiter. Name of the responsible organization. Role or position of the responsible person. Function performed by the responsible party. Possible values of this Role shall include the values and the meanings listed in Subclause B.5.5 of ISO 19115:2003. Address of the responsible party. Information required to enable contact with the responsible person and/or organization. For OWS use in the service metadata document, the optional hoursOfService and contactInstructions elements were retained, as possibly being useful in the ServiceProvider section. Telephone numbers at which the organization or individual may be contacted. Physical and email address at which the organization or individual may be contacted. On-line information that can be used to contact the individual or organization. OWS specifics: The xlink:href attribute in the xlink:simpleAttrs attribute group shall be used to reference this resource. Whenever practical, the xlink:href attribute with type anyURI should be a URL from which more contact information can be electronically retrieved. The xlink:title attribute with type "string" can be used to name this set of information. The other attributes in the xlink:simpleAttrs attribute group should not be used. Time period (including time zone) when individuals can contact the organization or individual. Supplemental instructions on how or when to contact the individual or organization. Reference to on-line resource from which data can be obtained. For OWS use in the service metadata document, the CI_OnlineResource class was XML encoded as the attributeGroup "xlink:simpleAttrs", as used in GML. Telephone numbers for contacting the responsible individual or organization. Telephone number by which individuals can speak to the responsible organization or individual. Telephone number of a facsimile machine for the responsible organization or individual. Location of the responsible individual or organization. Address line for the location. City of the location. State or province of the location. ZIP or other postal code. Country of the physical address. Address of the electronic mailbox of the responsible organization or individual. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsAll.xsd ================================================ owsAll.xsd This XML Schema Document includes and imports, directly and indirectly, all the XML Schemas defined by the OWS Common Implemetation Specification. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsCommon.xsd ================================================ owsCommon.xsd This XML Schema Document encodes various parameters and parameter types that can be used in OWS operation requests and responses. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . XML encoded identifier of a standard MIME type, possibly a parameterized MIME type. Specification version for OWS operation. The string value shall contain one x.y.z "version" value (e.g., "2.1.3"). A version number shall contain three non-negative integers separated by decimal points, in the form "x.y.z". The integers y and z shall not exceed 99. Each version shall be for the Implementation Specification (document) and the associated XML Schemas to which requested operations will conform. An Implementation Specification version normally specifies XML Schemas against which an XML encoded operation response must conform and should be validated. See Version negotiation subclause for more information. This element either references or contains more metadata about the element that includes this element. To reference metadata stored remotely, at least the xlinks:href attribute in xlink:simpleAttrs shall be included. Either at least one of the attributes in xlink:simpleAttrs or a substitute for the AbstractMetaData element shall be included, but not both. An Implementation Specification can restrict the contents of this element to always be a reference or always contain metadata. (Informative: This element was adapted from the metaDataProperty element in GML 3.0.) Reference to metadata recorded elsewhere, either external to this XML document or within it. Whenever practical, the xlink:href attribute with type anyURI should include a URL from which this metadata can be electronically retrieved. Optional reference to the aspect of the element which includes this "metadata" element that this metadata provides more information about. Abstract element containing more metadata about the element that includes the containing "metadata" element. A specific server implementation, or an Implementation Specification, can define concrete elements in the AbstractMetaData substitution group. XML encoded minimum rectangular bounding box (or region) parameter, surrounding all the associated data. This type is adapted from the EnvelopeType of GML 3.1, with modified contents and documentation for encoding a MINIMUM size box SURROUNDING all associated data. Position of the bounding box corner at which the value of each coordinate normally is the algebraic minimum within this bounding box. In some cases, this position is normally displayed at the top, such as the top left for some image coordinates. For more information, see Subclauses 10.2.5 and C.13. Position of the bounding box corner at which the value of each coordinate normally is the algebraic maximum within this bounding box. In some cases, this position is normally displayed at the bottom, such as the bottom right for some image coordinates. For more information, see Subclauses 10.2.5 and C.13. Usually references the definition of a CRS, as specified in [OGC Topic 2]. Such a CRS definition can be XML encoded using the gml:CoordinateReferenceSystemType in [GML 3.1]. For well known references, it is not required that a CRS definition exist at the location the URI points to. If no anyURI value is included, the applicable CRS must be either: a) Specified outside the bounding box, but inside a data structure that includes this bounding box, as specified for a specific OWS use of this bounding box type. b) Fixed and specified in the Implementation Specification for a specific OWS use of the bounding box type. The number of dimensions in this CRS (the length of a coordinate sequence in this use of the PositionType). This number is specified by the CRS definition, but can also be specified here. Position instances hold the coordinates of a position in a coordinate reference system (CRS) referenced by the related "crs" attribute or elsewhere. For an angular coordinate axis that is physically continuous for multiple revolutions, but whose recorded values can be discontinuous, special conditions apply when the bounding box is continuous across the value discontinuity: a) If the bounding box is continuous clear around this angular axis, then ordinate values of minus and plus infinity shall be used. b) If the bounding box is continuous across the value discontinuity but is not continuous clear around this angular axis, then some non-normal value can be used if specified for a specific OWS use of the BoundingBoxType. For more information, see Subclauses 10.2.5 and C.13. This type is adapted from DirectPositionType and doubleList of GML 3.1. The adaptations include omission of all the attributes, since the needed information is included in the BoundingBoxType. XML encoded minimum rectangular bounding box (or region) parameter, surrounding all the associated data. This box is specialized for use with the 2D WGS 84 coordinate reference system with decimal values of longitude and latitude. This type is adapted from the general BoundingBoxType, with modified contents and documentation for use with the 2D WGS 84 coordinate reference system. Position of the bounding box corner at which the values of longitude and latitude normally are the algebraic minimums within this bounding box. For more information, see Subclauses 10.4.5 and C.13. Position of the bounding box corner at which the values of longitude and latitude normally are the algebraic minimums within this bounding box. For more information, see Subclauses 10.4.5 and C.13. This attribute can be included when considered useful. When included, this attribute shall reference the 2D WGS 84 coordinate reference system with longitude before latitude and decimal values of longitude and latitude. The number of dimensions in this CRS (the length of a coordinate sequence in this use of the PositionType). This number is specified by the CRS definition, but can also be specified here. Two-dimensional position instances hold the longitude and latitude coordinates of a position in the 2D WGS 84 coordinate reference system. The longitude value shall be listed first, followed by the latitude value, both in decimal degrees. Latitude values shall range from -90 to +90 degrees, and longitude values shall normally range from -180 to +180 degrees. For the longitude axis, special conditions apply when the bounding box is continuous across the +/- 180 degrees meridian longitude value discontinuity: a) If the bounding box is continuous clear around the Earth, then longitude values of minus and plus infinity shall be used. b) If the bounding box is continuous across the value discontinuity but is not continuous clear around the Earth, then some non-normal value can be used if specified for a specific OWS use of the WGS84BoundingBoxType. For more information, see Subclauses 10.4.5 and C.13. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsContents.xsd ================================================ owsContents.xsd This XML Schema Document encodes the typical Contents section of an OWS service metadata (Capabilities) document. This Schema can be built upon to define the Contents section for a specific OWS. If the ContentsBaseType in this XML Schema cannot be restricted and extended to define the Contents section for a specific OWS, all other relevant parts defined in owsContents.xsd shall be used by the "ContentsType" in the wxsContents.xsd prepared for the specific OWS. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Contents of typical Contents section of an OWS service metadata (Capabilities) document. This type shall be extended and/or restricted if needed for specific OWS use to include the specific metadata needed. Unordered set of summary descriptions for the datasets available from this OWS server. This set shall be included unless another source is referenced and all this metadata is available from that source. Unordered set of references to other sources of metadata describing the coverage offerings available from this server. Reference to a source of metadata describing coverage offerings available from this server. This parameter can reference a catalogue server from which dataset metadata is available. This ability is expected to be used by servers with thousands or millions of datasets, for which searching a catalogue is more feasible than fetching a long Capabilities XML document. When no DatasetDescriptionSummaries are included, and one or more catalogue servers are referenced, this set of catalogues shall contain current metadata summaries for all the datasets currently available from this OWS server, with the metadata for each such dataset referencing this OWS server. Typical dataset metadata in typical Contents section of an OWS service metadata (Capabilities) document. This type shall be extended and/or restricted if needed for specific OWS use, to include the specific Dataset description metadata needed. Unordered list of zero or more minimum bounding rectangles surrounding coverage data, using the WGS 84 CRS with decimal degrees and longitude before latitude. If no WGS 84 bounding box is recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall apply to this coverage. If WGS 84 bounding box(es) are recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall be ignored. For each lowest-level coverage in a hierarchy, at least one applicable WGS84BoundingBox shall be either recorded or inherited, to simplify searching for datasets that might overlap a specified region. If multiple WGS 84 bounding boxes are included, this shall be interpreted as the union of the areas of these bounding boxes. Unambiguous identifier or name of this coverage, unique for this server. Unordered list of zero or more minimum bounding rectangles surrounding coverage data, in AvailableCRSs. Zero or more BoundingBoxes are allowed in addition to one or more WGS84BoundingBoxes to allow more precise specification of the Dataset area in AvailableCRSs. These Bounding Boxes shall not use any CRS not listed as an AvailableCRS. However, an AvailableCRS can be listed without a corresponding Bounding Box. If no such bounding box is recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall apply to this coverage. If such bounding box(es) are recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall be ignored. If multiple bounding boxes are included with the same CRS, this shall be interpreted as the union of the areas of these bounding boxes. Optional unordered list of additional metadata about this dataset. A list of optional metadata elements for this dataset description could be specified in the Implementation Specification for this service. Metadata describing zero or more unordered subsidiary datasets available from this server. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsDataIdentification.xsd ================================================ owsDataIdentification.xsd This XML Schema Document encodes the parts of the MD_DataIdentification class of ISO 19115 (OGC Abstract Specification Topic 11) which are expected to be used for most datasets. This Schema also encodes the parts of this class that are expected to be useful for other metadata. Both may be used within the Contents section of OWS service metadata (Capabilities) documents. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Human-readable descriptive information for the object it is included within. This type shall be extended if needed for specific OWS use to include additional metadata for each type of information. This type shall not be restricted for a specific OWS to change the multiplicity (or optionality) of some elements. If the xml:lang attribute is not included in a Title, Abstract or Keyword element, then no language is specified for that element unless specified by another means. All Title, Abstract and Keyword elements in the same Description that share the same xml:lang attribute value represent the description of the parent object in that language. Multiple Title or Abstract elements shall not exist in the same Description with the same xml:lang attribute value unless otherwise specified. Basic metadata identifying and describing a set of data. Optional unique identifier or name of this dataset. Optional unordered list of additional metadata about this data(set). A list of optional metadata elements for this data identification could be specified in the Implementation Specification for this service. Extended metadata identifying and describing a set of data. This type shall be extended if needed for each specific OWS to include additional metadata for each type of dataset. If needed, this type should first be restricted for each specific OWS to change the multiplicity (or optionality) of some elements. Unordered list of zero or more bounding boxes whose union describes the extent of this dataset. Unordered list of zero or more references to data formats supported for server outputs. Unordered list of zero or more available coordinate reference systems. Unique identifier or name of this dataset. Reference to a format in which this data can be encoded and transferred. More specific parameter names should be used by specific OWS specifications wherever applicable. More than one such parameter can be included for different purposes. Coordinate reference system in which data from this data(set) or resource is available or supported. More specific parameter names should be used by specific OWS specifications wherever applicable. More than one such parameter can be included for different purposes. Access constraint applied to assure the protection of privacy or intellectual property, or any other restrictions on retrieving or using data from or otherwise using this server. The reserved value NONE (case insensitive) shall be used to mean no access constraints are imposed. Fees and terms for retrieving data from or otherwise using this server, including the monetary units as specified in ISO 4217. The reserved value NONE (case insensitive) shall be used to mean no fees or terms. Identifier of a language used by the data(set) contents. This language identifier shall be as specified in IETF RFC 4646. When this element is omitted, the language used is not identified. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsDomainType.xsd ================================================ owsDomainType.xsd This XML Schema Document encodes the allowed values (or domain) of a quantity, often for an input or output parameter to an OWS. Such a parameter is sometimes called a variable, quantity, literal, or typed literal. Such a parameter can use one of many data types, including double, integer, boolean, string, or URI. The allowed values can also be encoded for a quantity that is not explicit or not transferred, but is constrained by a server implementation. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Valid domain (or allowed set of values) of one quantity, with its name or identifier. Name or identifier of this quantity. Valid domain (or allowed set of values) of one quantity, with needed metadata but without a quantity name or identifier. Optional default value for this quantity, which should be included when this quantity has a default value. Meaning metadata should be referenced or included for each quantity. This data type metadata should be referenced or included for each quantity. Unit of measure, which should be included when this set of PossibleValues has units or a more complete reference system. Optional unordered list of other metadata about this quantity. A list of required and optional other metadata elements for this quantity should be specified in the Implementation Specification for this service. Specifies the possible values of this quantity. Specifies that any value is allowed for this parameter. Specifies that no values are allowed for this parameter or quantity. Reference to externally specified list of all the valid values and/or ranges of values for this quantity. (Informative: This element was simplified from the metaDataProperty element in GML 3.0.) Human-readable name of the list of values provided by the referenced document. Can be empty string when this list has no name. Indicates that this quantity has units or a reference system, and identifies the unit or reference system used by the AllowedValues or ValuesReference. Identifier of unit of measure of this set of values. Should be included then this set of values has units (and not a more complete reference system). Identifier of reference system used by this set of values. Should be included then this set of values has a reference system (not just units). List of all the valid values and/or ranges of values for this quantity. For numeric quantities, signed values should be ordered from negative infinity to positive infinity. A single value, encoded as a string. This type can be used for one value, for a spacing between allowed values, or for the default value of a parameter. The default value for a quantity for which multiple values are allowed. A range of values of a numeric parameter. This range can be continuous or discrete, defined by a fixed spacing between adjacent valid values. If the MinimumValue or MaximumValue is not included, there is no value limit in that direction. Inclusion of the specified minimum and maximum values in the range shall be defined by the rangeClosure. Shall be included when the allowed values are NOT continuous in this range. Shall not be included when the allowed values are continuous in this range. Shall be included unless the default value applies. Minimum value of this numeric parameter. Maximum value of this numeric parameter. The regular distance or spacing between the allowed values in a range. Specifies which of the minimum and maximum values are included in the range. Note that plus and minus infinity are considered closed bounds. The specified minimum and maximum values are included in this range. The specified minimum and maximum values are NOT included in this range. The specified minimum value is NOT included in this range, and the specified maximum value IS included in this range. The specified minimum value IS included in this range, and the specified maximum value is NOT included in this range. References metadata about a quantity, and provides a name for this metadata. (Informative: This element was simplified from the metaDataProperty element in GML 3.0.) Human-readable name of the metadata described by associated referenced document. Reference to data or metadata recorded elsewhere, either external to this XML document or within it. Whenever practical, this attribute should be a URL from which this metadata can be electronically retrieved. Alternately, this attribute can reference a URN for well-known metadata. For example, such a URN could be a URN defined in the "ogc" URN namespace. Definition of the meaning or semantics of this set of values. This Meaning can provide more specific, complete, precise, machine accessible, and machine understandable semantics about this quantity, relative to other available semantic information. For example, other semantic information is often provided in "documentation" elements in XML Schemas or "description" elements in GML objects. Definition of the data type of this set of values. In this case, the xlink:href attribute can reference a URN for a well-known data type. For example, such a URN could be a data type identification URN defined in the "ogc" URN namespace. Definition of the reference system used by this set of values, including the unit of measure whenever applicable (as is normal). In this case, the xlink:href attribute can reference a URN for a well-known reference system, such as for a coordinate reference system (CRS). For example, such a URN could be a CRS identification URN defined in the "ogc" URN namespace. Definition of the unit of measure of this set of values. In this case, the xlink:href attribute can reference a URN for a well-known unit of measure (uom). For example, such a URN could be a UOM identification URN defined in the "ogc" URN namespace. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsExceptionReport.xsd ================================================ owsExceptionReport.xsd This XML Schema Document encodes the Exception Report response to all OWS operations. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Report message returned to the client that requested any OWS operation when the server detects an error while processing that operation request. Unordered list of one or more Exception elements that each describes an error. These Exception elements shall be interpreted by clients as being independent of one another (not hierarchical). Specification version for OWS operation. The string value shall contain one x.y.z "version" value (e.g., "2.1.3"). A version number shall contain three non-negative integers separated by decimal points, in the form "x.y.z". The integers y and z shall not exceed 99. Each version shall be for the Implementation Specification (document) and the associated XML Schemas to which requested operations will conform. An Implementation Specification version normally specifies XML Schemas against which an XML encoded operation response must conform and should be validated. See Version negotiation subclause for more information. Identifier of the language used by all included exception text values. These language identifiers shall be as specified in IETF RFC 4646. When this attribute is omitted, the language used is not identified. An Exception element describes one detected error that a server chooses to convey to the client. Ordered sequence of text strings that describe this specific exception or error. The contents of these strings are left open to definition by each server implementation. A server is strongly encouraged to include at least one ExceptionText value, to provide more information about the detected error than provided by the exceptionCode. When included, multiple ExceptionText values shall provide hierarchical information about one detected error, with the most significant information listed first. A code representing the type of this exception, which shall be selected from a set of exceptionCode values specified for the specific service operation and server. When included, this locator shall indicate to the client where an exception was encountered in servicing the client's operation request. This locator should be included whenever meaningful information can be provided by the server. The contents of this locator will depend on the specific exceptionCode and OWS service, and shall be specified in the OWS Implementation Specification. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsGetCapabilities.xsd ================================================ owsGetCapabilities.xsd This XML Schema Document defines the GetCapabilities operation request and response XML elements and types, which are common to all OWSs. This XML Schema shall be edited by each OWS, for example, to specify a specific value for the "service" attribute. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . XML encoded GetCapabilities operation response. This document provides clients with service metadata about a specific service instance, usually including metadata about the tightly-coupled data served. If the server does not implement the updateSequence parameter, the server shall always return the complete Capabilities document, without the updateSequence parameter. When the server implements the updateSequence parameter and the GetCapabilities operation request included the updateSequence parameter with the current value, the server shall return this element with only the "version" and "updateSequence" attributes. Otherwise, all optional elements shall be included or not depending on the actual value of the Contents parameter in the GetCapabilities operation request. This base type shall be extended by each specific OWS to include the additional contents needed. Service metadata document version, having values that are "increased" whenever any change is made in service metadata document. Values are selected by each server, and are always opaque to clients. When not supported by server, server shall not return this attribute. XML encoded GetCapabilities operation request. This operation allows clients to retrieve service metadata about a specific service instance. In this XML encoding, no "request" parameter is included, since the element name specifies the specific operation. This base type shall be extended by each specific OWS to include the additional required "service" attribute, with the correct value for that OWS. When omitted, server shall return latest supported version. When omitted or not supported by server, server shall return complete service metadata (Capabilities) document. When omitted or not supported by server, server shall return service metadata document using the MIME type "text/xml". When omitted or not supported by server, server shall return latest complete service metadata document. Service type identifier, where the string value is the OWS type abbreviation, such as "WMS" or "WFS". Prioritized sequence of one or more specification versions accepted by client, with preferred versions listed first. See Version negotiation subclause for more information. Unordered list of zero or more names of requested sections in complete service metadata document. Each Section value shall contain an allowed section name as specified by each OWS specification. See Sections parameter subclause for more information. Service metadata document version, having values that are "increased" whenever any change is made in service metadata document. Values are selected by each server, and are always opaque to clients. See updateSequence parameter use subclause for more information. Prioritized sequence of zero or more GetCapabilities operation response formats desired by client, with preferred formats listed first. Each response format shall be identified by its MIME type. See AcceptFormats parameter use subclause for more information. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsGetResourceByID.xsd ================================================ owsGetResourceByID.xsd This XML Schema Document encodes the GetResourceByID operation request message. This typical operation is specified as a base for profiling in specific OWS specifications. For information on the allowed changes and limitations in such profiling, see Subclause 9.4.1 of the OWS Common specification. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . XML encoded GetResourceByID operation response. The complexType used by this element shall be specified by each specific OWS. Request to a service to perform the GetResourceByID operation. This operation allows a client to retrieve one or more identified resources, including datasets and resources that describe datasets or parameters. In this XML encoding, no "request" parameter is included, since the element name specifies the specific operation. Unordered list of zero or more resource identifiers. These identifiers can be listed in the Contents section of the service metadata (Capabilities) document. For more information on this parameter, see Subclause 9.4.2.1 of the OWS Common specification. Optional reference to the data format to be used for response to this operation request. This element shall be included when multiple output formats are available for the selected resource(s), and the client desires a format other than the specified default, if any. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsInputOutputData.xsd ================================================ owsInputOutputData.xsd This XML Schema Document specifies types and elements for input and output of operation data, allowing including multiple data items with each data item either included or referenced. The contents of each type and element specified here can be restricted and/or extended for each use in a specific OWS specification. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Response from an OWS operation, allowing including multiple output data items with each item either included or referenced. This OperationResponse element, or an element using the ManifestType with a more specific element name, shall be used whenever applicable for responses from OWS operations. This element is specified for use where the ManifestType contents are needed for an operation response, but the Manifest element name is not fully applicable. This element or the ManifestType shall be used instead of using the ows:ReferenceType proposed in OGC 04-105. Input data in a XML-encoded OWS operation request, allowing including multiple data items with each data item either included or referenced. This InputData element, or an element using the ManifestType with a more-specific element name (TBR), shall be used whenever applicable within XML-encoded OWS operation requests. Complete reference to a remote resource that needs to be retrieved from an OWS using an XML-encoded operation request. This element shall be used, within an InputData or Manifest element that is used for input data, when that input data needs to be retrieved from another web service using a XML-encoded OWS operation request. This element shall not be used for local payload input data or for requesting the resource from a web server using HTTP Get. The XML-encoded operation request message to be sent to request this input data from another web server using HTTP Post. Reference to the XML-encoded operation request message to be sent to request this input data from another web server using HTTP Post. The referenced message shall be attached to the same message (using the cid scheme), or be accessible using a URL. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsManifest.xsd ================================================ owsManifest.xsd This XML Schema Document specifies types and elements for document or resource references and for package manifests that contain multiple references. The contents of each type and element specified here can be restricted and/or extended for each use in a specific OWS specification. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Base for a reference to a remote or local resource. This type contains only a restricted and annotated set of the attributes from the xlink:simpleAttrs attributeGroup. Reference to a remote resource or local payload. A remote resource is typically addressed by a URL. For a local payload (such as a multipart mime message), the xlink:href must start with the prefix cid:. Reference to a resource that describes the role of this reference. When no value is supplied, no particular role value is to be inferred. Although allowed, this attribute is not expected to be useful in this application of xlink:simpleAttrs. Describes the meaning of the referenced resource in a human-readable fashion. Although allowed, this attribute is not expected to be useful in this application of xlink:simpleAttrs. Although allowed, this attribute is not expected to be useful in this application of xlink:simpleAttrs. Complete reference to a remote or local resource, allowing including metadata about that resource. Optional unique identifier of the referenced resource. The format of the referenced resource. This element is omitted when the mime type is indicated in the http header of the reference. Optional unordered list of additional metadata about this resource. A list of optional metadata elements for this ReferenceType could be specified in the Implementation Specification for each use of this type in a specific OWS. Logical group of one or more references to remote and/or local resources, allowing including metadata about that group. A Group can be used instead of a Manifest that can only contain one group. Unordered list of one or more groups of references to remote and/or local resources. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsOperationsMetadata.xsd ================================================ owsOperationsMetadata.xsd This XML Schema Document encodes the basic contents of the "OperationsMetadata" section of the GetCapabilities operation response, also known as the Capabilities XML document. OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Metadata about the operations and related abilities specified by this service and implemented by this server, including the URLs for operation requests. The basic contents of this section shall be the same for all OWS types, but individual services can add elements and/or change the optionality of optional elements. Metadata for unordered list of all the (requests for) operations that this server interface implements. The list of required and optional operations implemented shall be specified in the Implementation Specification for this service. Optional unordered list of parameter valid domains that each apply to one or more operations which this server interface implements. The list of required and optional parameter domain limitations shall be specified in the Implementation Specification for this service. Optional unordered list of valid domain constraints on non-parameter quantities that each apply to this server. The list of required and optional constraints shall be specified in the Implementation Specification for this service. Individual software vendors and servers can use this element to provide metadata about any additional server abilities. Metadata for one operation that this server implements. Unordered list of Distributed Computing Platforms (DCPs) supported for this operation. At present, only the HTTP DCP is defined, so this element will appear only once. Optional unordered list of parameter domains that each apply to this operation which this server implements. If one of these Parameter elements has the same "name" attribute as a Parameter element in the OperationsMetadata element, this Parameter element shall override the other one for this operation. The list of required and optional parameter domain limitations for this operation shall be specified in the Implementation Specification for this service. Optional unordered list of valid domain constraints on non-parameter quantities that each apply to this operation. If one of these Constraint elements has the same "name" attribute as a Constraint element in the OperationsMetadata element, this Constraint element shall override the other one for this operation. The list of required and optional constraints for this operation shall be specified in the Implementation Specification for this service. Optional unordered list of additional metadata about this operation and its' implementation. A list of required and optional metadata elements for this operation should be specified in the Implementation Specification for this service. (Informative: This metadata might specify the operation request parameters or provide the XML Schemas for the operation request.) Name or identifier of this operation (request) (for example, GetCapabilities). The list of required and optional operations implemented shall be specified in the Implementation Specification for this service. Information for one distributed Computing Platform (DCP) supported for this operation. At present, only the HTTP DCP is defined, so this element only includes the HTTP element. Connect point URLs for the HTTP Distributed Computing Platform (DCP). Normally, only one Get and/or one Post is included in this element. More than one Get and/or Post is allowed to support including alternative URLs for uses such as load balancing or backup. Connect point URL prefix and any constraints for the HTTP "Get" request method for this operation request. Connect point URL and any constraints for the HTTP "Post" request method for this operation request. Connect point URL and any constraints for this HTTP request method for this operation request. In the OnlineResourceType, the xlink:href attribute in the xlink:simpleAttrs attribute group shall be used to contain this URL. The other attributes in the xlink:simpleAttrs attribute group should not be used. Optional unordered list of valid domain constraints on non-parameter quantities that each apply to this request method for this operation. If one of these Constraint elements has the same "name" attribute as a Constraint element in the OperationsMetadata or Operation element, this Constraint element shall override the other one for this operation. The list of required and optional constraints for this request method for this operation shall be specified in the Implementation Specification for this service. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsServiceIdentification.xsd ================================================ owsServiceIdentification.xsd This XML Schema Document encodes the common "ServiceIdentification" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceIdentification class of ISO 19119 (OGC Abstract Specification Topic 12). OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . General metadata for this specific server. This XML Schema of this section shall be the same for all OWS. A service type name from a registry of services. For example, the values of the codeSpace URI and name and code string may be "OGC" and "catalogue." This type name is normally used for machine-to-machine communication. Unordered list of one or more versions of this service type implemented by this server. This information is not adequate for version negotiation, and shall not be used for that purpose. Unordered list of identifiers of Application Profiles that are implemented by this server. This element should be included for each specified application profile implemented by this server. The identifier value should be specified by each Application Profile. If this element is omitted, no meaning is implied. If this element is omitted, no meaning is implied. Unordered list of access constraints applied to assure the protection of privacy or intellectual property, and any other restrictions on retrieving or using data from or otherwise using this server. The reserved value NONE (case insensitive) shall be used to mean no access constraints are imposed. When this element is omitted, no meaning is implied. ================================================ FILE: pycsw/core/schemas/ogc/ows/1.1.0/owsServiceProvider.xsd ================================================ owsServiceProvider.xsd This XML Schema Document encodes the common "ServiceProvider" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceProvider class of ISO 19119 (OGC Abstract Specification Topic 12). OWS is an OGC Standard. Copyright (c) 2006,2010 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Metadata about the organization that provides this specific service instance or server. A unique identifier for the service provider organization. Reference to the most relevant web site of the service provider. Information for contacting the service provider. The OnlineResource element within this ServiceContact element should not be used to reference a web site of the service provider. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/ows19115subset.xsd ================================================ ows19115subset.xsd This XML Schema Document encodes the parts of ISO 19115 used by the common "ServiceIdentification" and "ServiceProvider" sections of the GetCapabilities operation response, known as the service metadata XML document. The parts encoded here are the MD_Keywords, CI_ResponsibleParty, and related classes. The UML package prefixes were omitted from XML names, and the XML element names were all capitalized, for consistency with other OWS Schemas. This document also provides a simple coding of text in multiple languages, simplified from Annex J of ISO 19115. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Text string with the language of the string identified as recommended in the XML 1.0 W3C Recommendation, section 2.12. Title of this resource, normally used for display to humans. Brief narrative description of this resource, normally used for display to humans. Unordered list of one or more commonly used or formalised word(s) or phrase(s) used to describe the subject. When needed, the optional "type" can name the type of the associated list of keywords that shall all have the same type. Also when needed, the codeSpace attribute of that "type" can reference the type name authority and/or thesaurus. If the xml:lang attribute is not included in a Keyword element, then no language is specified for that element unless specified by another means. All Keyword elements in the same Keywords element that share the same xml:lang attribute value represent different keywords in that language. For OWS use, the optional thesaurusName element was omitted as being complex information that could be referenced by the codeSpace attribute of the Type element. Name or code with an (optional) authority. If the codeSpace attribute is present, its value shall reference a dictionary, thesaurus, or authority for the name or code, such as the organisation who assigned the value, or the dictionary from which it is taken. Type copied from basicTypes.xsd of GML 3 with documentation edited, for possible use outside the ServiceIdentification section of a service metadata document. Identification of, and means of communication with, person(s) responsible for the resource(s). For OWS use in the ServiceProvider section of a service metadata document, the optional organizationName element was removed, since this type is always used with the ProviderName element which provides that information. The optional individualName element was made mandatory, since either the organizationName or individualName element is mandatory. The mandatory "role" element was changed to optional, since no clear use of this information is known in the ServiceProvider section. Identification of, and means of communication with, person responsible for the server. At least one of IndividualName, OrganisationName, or PositionName shall be included. Identification of, and means of communication with, person responsible for the server. For OWS use in the ServiceProvider section of a service metadata document, the optional organizationName element was removed, since this type is always used with the ProviderName element which provides that information. The mandatory "role" element was changed to optional, since no clear use of this information is known in the ServiceProvider section. Name of the responsible person: surname, given name, title separated by a delimiter. Name of the responsible organization. Role or position of the responsible person. Function performed by the responsible party. Possible values of this Role shall include the values and the meanings listed in Subclause B.5.5 of ISO 19115:2003. Address of the responsible party. Information required to enable contact with the responsible person and/or organization. For OWS use in the service metadata document, the optional hoursOfService and contactInstructions elements were retained, as possibly being useful in the ServiceProvider section. Telephone numbers at which the organization or individual may be contacted. Physical and email address at which the organization or individual may be contacted. On-line information that can be used to contact the individual or organization. OWS specifics: The xlink:href attribute in the xlink:simpleAttrs attribute group shall be used to reference this resource. Whenever practical, the xlink:href attribute with type anyURI should be a URL from which more contact information can be electronically retrieved. The xlink:title attribute with type "string" can be used to name this set of information. The other attributes in the xlink:simpleAttrs attribute group should not be used. Time period (including time zone) when individuals can contact the organization or individual. Supplemental instructions on how or when to contact the individual or organization. Reference to on-line resource from which data can be obtained. For OWS use in the service metadata document, the CI_OnlineResource class was XML encoded as the attributeGroup "xlink:simpleAttrs", as used in GML. Telephone numbers for contacting the responsible individual or organization. Telephone number by which individuals can speak to the responsible organization or individual. Telephone number of a facsimile machine for the responsible organization or individual. Location of the responsible individual or organization. Address line for the location. City of the location. State or province of the location. ZIP or other postal code. Country of the physical address. Address of the electronic mailbox of the responsible organization or individual. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsAdditionalParameters.xsd ================================================ owsAdditionalParameters.xsd This XML Schema Document encodes a new AdditionalParameters element that contains one or more AdditionalParameter elements, which each contain a specific parameter name and one or more values of that parameter. This AdditionalParameters element is substitutable for ows:Metadata, anywhere that element is allowed. The document also encodes a new nilValue element of a newly defined NilValue type that allows the specification of a nilReason attribute. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Unordered list of one or more AdditionalParameters. One additional metadata parameter. Name or identifier of this AdditionalParameter, unique for this OGC Web Service. Unordered list of one or more values of this AdditionalParameter. The value used (e.g. -255) to represent a nil value with optional nilReason and codeSpace attributes. An anyURI value which refers to a resource that describes the reason for the nil value ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsAll.xsd ================================================ owsAll.xsd This XML Schema Document includes and imports, directly or indirectly, all the XML Schemas defined by the OWS Common Implemetation Specification. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsCommon.xsd ================================================ owsCommon.xsd This XML Schema Document encodes various parameters and parameter types that can be used in OWS operation requests and responses. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ XML encoded identifier of a standard MIME type, possibly a parameterized MIME type. Specification version for OWS operation. The string value shall contain one x.y.z "version" value (e.g., "2.1.3"). A version number shall contain three non-negative integers separated by decimal points, in the form "x.y.z". The integers y and z shall not exceed 99. Each version shall be for the Implementation Specification (document) and the associated XML Schemas to which requested operations will conform. An Implementation Specification version normally specifies XML Schemas against which an XML encoded operation response must conform and should be validated. See Version negotiation subclause for more information. This element either references or contains more metadata about the element that includes this element. To reference metadata stored remotely, at least the xlinks:href attribute in xlink:simpleAttrs shall be included. Either at least one of the attributes in xlink:simpleAttrs or a substitute for the AbstractMetaData element shall be included, but not both. An Implementation Specification can restrict the contents of this element to always be a reference or always contain metadata. (Informative: This element was adapted from the metaDataProperty element in GML 3.0.) Reference to metadata recorded elsewhere, either external to this XML document or within it. Whenever practical, the xlink:href attribute with type anyURI should include a URL from which this metadata can be electronically retrieved. Optional reference to the aspect of the element which includes this "metadata" element that this metadata provides more information about. Abstract element containing more metadata about the element that includes the containing "metadata" element. A specific server implementation, or an Implementation Specification, can define concrete elements in the AbstractMetaData substitution group. XML encoded minimum rectangular bounding box (or region) parameter, surrounding all the associated data. This type is adapted from the EnvelopeType of GML 3.1, with modified contents and documentation for encoding a MINIMUM size box SURROUNDING all associated data. Position of the bounding box corner at which the value of each coordinate normally is the algebraic minimum within this bounding box. In some cases, this position is normally displayed at the top, such as the top left for some image coordinates. For more information, see Subclauses 10.2.5 and C.13. Position of the bounding box corner at which the value of each coordinate normally is the algebraic maximum within this bounding box. In some cases, this position is normally displayed at the bottom, such as the bottom right for some image coordinates. For more information, see Subclauses 10.2.5 and C.13. Usually references the definition of a CRS, as specified in [OGC Topic 2]. Such a CRS definition can be XML encoded using the gml:CoordinateReferenceSystemType in [GML 3.1]. For well known references, it is not required that a CRS definition exist at the location the URI points to. If no anyURI value is included, the applicable CRS must be either: a) Specified outside the bounding box, but inside a data structure that includes this bounding box, as specified for a specific OWS use of this bounding box type. b) Fixed and specified in the Implementation Specification for a specific OWS use of the bounding box type. The number of dimensions in this CRS (the length of a coordinate sequence in this use of the PositionType). This number is specified by the CRS definition, but can also be specified here. Position instances hold the coordinates of a position in a coordinate reference system (CRS) referenced by the related "crs" attribute or elsewhere. For an angular coordinate axis that is physically continuous for multiple revolutions, but whose recorded values can be discontinuous, special conditions apply when the bounding box is continuous across the value discontinuity: a) If the bounding box is continuous clear around this angular axis, then ordinate values of minus and plus infinity shall be used. b) If the bounding box is continuous across the value discontinuity but is not continuous clear around this angular axis, then some non-normal value can be used if specified for a specific OWS use of the BoundingBoxType. For more information, see Subclauses 10.2.5 and C.13. This type is adapted from DirectPositionType and doubleList of GML 3.1. The adaptations include omission of all the attributes, since the needed information is included in the BoundingBoxType. XML encoded minimum rectangular bounding box (or region) parameter, surrounding all the associated data. This box is specialized for use with the 2D WGS 84 coordinate reference system with decimal values of longitude and latitude. This type is adapted from the general BoundingBoxType, with modified contents and documentation for use with the 2D WGS 84 coordinate reference system. Position of the bounding box corner at which the values of longitude and latitude normally are the algebraic minimums within this bounding box. For more information, see Subclauses 10.4.5 and C.13. Position of the bounding box corner at which the values of longitude and latitude normally are the algebraic minimums within this bounding box. For more information, see Subclauses 10.4.5 and C.13. This attribute can be included when considered useful. When included, this attribute shall reference the 2D WGS 84 coordinate reference system with longitude before latitude and decimal values of longitude and latitude. The number of dimensions in this CRS (the length of a coordinate sequence in this use of the PositionType). This number is specified by the CRS definition, but can also be specified here. Two-dimensional position instances hold the longitude and latitude coordinates of a position in the 2D WGS 84 coordinate reference system. The longitude value shall be listed first, followed by the latitude value, both in decimal degrees. Latitude values shall range from -90 to +90 degrees, and longitude values shall normally range from -180 to +180 degrees. For the longitude axis, special conditions apply when the bounding box is continuous across the +/- 180 degrees meridian longitude value discontinuity: a) If the bounding box is continuous clear around the Earth, then longitude values of minus and plus infinity shall be used. b) If the bounding box is continuous across the value discontinuity but is not continuous clear around the Earth, then some non-normal value can be used if specified for a specific OWS use of the WGS84BoundingBoxType. For more information, see Subclauses 10.4.5 and C.13. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsContents.xsd ================================================ owsContents.xsd This XML Schema Document encodes the typical Contents section of an OWS service metadata (Capabilities) document. This Schema can be built upon to define the Contents section for a specific OWS. If the ContentsBaseType in this XML Schema cannot be restricted and extended to define the Contents section for a specific OWS, all other relevant parts defined in owsContents.xsd shall be used by the "ContentsType" in the wxsContents.xsd prepared for the specific OWS. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ Contents of typical Contents section of an OWS service metadata (Capabilities) document. This type shall be extended and/or restricted if needed for specific OWS use to include the specific metadata needed. Unordered set of summary descriptions for the datasets available from this OWS server. This set shall be included unless another source is referenced and all this metadata is available from that source. Unordered set of references to other sources of metadata describing the coverage offerings available from this server. Reference to a source of metadata describing coverage offerings available from this server. This parameter can reference a catalogue server from which dataset metadata is available. This ability is expected to be used by servers with thousands or millions of datasets, for which searching a catalogue is more feasible than fetching a long Capabilities XML document. When no DatasetDescriptionSummaries are included, and one or more catalogue servers are referenced, this set of catalogues shall contain current metadata summaries for all the datasets currently available from this OWS server, with the metadata for each such dataset referencing this OWS server. Typical dataset metadata in typical Contents section of an OWS service metadata (Capabilities) document. This type shall be extended and/or restricted if needed for specific OWS use, to include the specific Dataset description metadata needed. Unordered list of zero or more minimum bounding rectangles surrounding coverage data, using the WGS 84 CRS with decimal degrees and longitude before latitude. If no WGS 84 bounding box is recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall apply to this coverage. If WGS 84 bounding box(es) are recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall be ignored. For each lowest-level coverage in a hierarchy, at least one applicable WGS84BoundingBox shall be either recorded or inherited, to simplify searching for datasets that might overlap a specified region. If multiple WGS 84 bounding boxes are included, this shall be interpreted as the union of the areas of these bounding boxes. Unambiguous identifier or name of this coverage, unique for this server. Unordered list of zero or more minimum bounding rectangles surrounding coverage data, in AvailableCRSs. Zero or more BoundingBoxes are allowed in addition to one or more WGS84BoundingBoxes to allow more precise specification of the Dataset area in AvailableCRSs. These Bounding Boxes shall not use any CRS not listed as an AvailableCRS. However, an AvailableCRS can be listed without a corresponding Bounding Box. If no such bounding box is recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall apply to this coverage. If such bounding box(es) are recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall be ignored. If multiple bounding boxes are included with the same CRS, this shall be interpreted as the union of the areas of these bounding boxes. Optional unordered list of additional metadata about this dataset. A list of optional metadata elements for this dataset description could be specified in the Implementation Specification for this service. Metadata describing zero or more unordered subsidiary datasets available from this server. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsDataIdentification.xsd ================================================ owsDataIdentification.xsd This XML Schema Document encodes the parts of the MD_DataIdentification class of ISO 19115 (OGC Abstract Specification Topic 11) which are expected to be used for most datasets. This Schema also encodes the parts of this class that are expected to be useful for other metadata. Both may be used within the Contents section of OWS service metadata (Capabilities) documents. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ Human-readable descriptive information for the object it is included within. This type shall be extended if needed for specific OWS use to include additional metadata for each type of information. This type shall not be restricted for a specific OWS to change the multiplicity (or optionality) of some elements. If the xml:lang attribute is not included in a Title, Abstract or Keyword element, then no language is specified for that element unless specified by another means. All Title, Abstract and Keyword elements in the same Description that share the same xml:lang attribute value represent the description of the parent object in that language. Multiple Title or Abstract elements shall not exist in the same Description with the same xml:lang attribute value unless otherwise specified. Basic metadata identifying and describing a set of data. Optional unique identifier or name of this dataset. Optional unordered list of additional metadata about this data(set). A list of optional metadata elements for this data identification could be specified in the Implementation Specification for this service. Extended metadata identifying and describing a set of data. This type shall be extended if needed for each specific OWS to include additional metadata for each type of dataset. If needed, this type should first be restricted for each specific OWS to change the multiplicity (or optionality) of some elements. Unordered list of zero or more bounding boxes whose union describes the extent of this dataset. Unordered list of zero or more references to data formats supported for server outputs. Unordered list of zero or more available coordinate reference systems. Unique identifier or name of this dataset. Reference to a format in which this data can be encoded and transferred. More specific parameter names should be used by specific OWS specifications wherever applicable. More than one such parameter can be included for different purposes. Coordinate reference system in which data from this data(set) or resource is available or supported. More specific parameter names should be used by specific OWS specifications wherever applicable. More than one such parameter can be included for different purposes. Access constraint applied to assure the protection of privacy or intellectual property, or any other restrictions on retrieving or using data from or otherwise using this server. The reserved value NONE (case insensitive) shall be used to mean no access constraints are imposed. Fees and terms for retrieving data from or otherwise using this server, including the monetary units as specified in ISO 4217. The reserved value NONE (case insensitive) shall be used to mean no fees or terms. Identifier of a language used by the data(set) contents. This language identifier shall be as specified in IETF RFC 4646. The language tags shall be either complete 5 character codes (e.g. "en-CA"), or abbreviated 2 character codes (e.g. "en"). In addition to the RFC 4646 codes, the server shall support the single special value "*" which is used to indicate "any language". ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsDomainType.xsd ================================================ owsDomainType.xsd This XML Schema Document encodes the allowed values (or domain) of a quantity, often for an input or output parameter to an OWS. Such a parameter is sometimes called a variable, quantity, literal, or typed literal. Such a parameter can use one of many data types, including double, integer, boolean, string, or URI. The allowed values can also be encoded for a quantity that is not explicit or not transferred, but is constrained by a server implementation. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ Valid domain (or allowed set of values) of one quantity, with its name or identifier. Name or identifier of this quantity. Valid domain (or allowed set of values) of one quantity, with needed metadata but without a quantity name or identifier. Optional default value for this quantity, which should be included when this quantity has a default value. Meaning metadata should be referenced or included for each quantity. This data type metadata should be referenced or included for each quantity. Unit of measure, which should be included when this set of PossibleValues has units or a more complete reference system. Optional unordered list of other metadata about this quantity. A list of required and optional other metadata elements for this quantity should be specified in the Implementation Specification for this service. Specifies the possible values of this quantity. Specifies that any value is allowed for this parameter. Specifies that no values are allowed for this parameter or quantity. Reference to externally specified list of all the valid values and/or ranges of values for this quantity. (Informative: This element was simplified from the metaDataProperty element in GML 3.0.) Human-readable name of the list of values provided by the referenced document. Can be empty string when this list has no name. Indicates that this quantity has units or a reference system, and identifies the unit or reference system used by the AllowedValues or ValuesReference. Identifier of unit of measure of this set of values. Should be included then this set of values has units (and not a more complete reference system). Identifier of reference system used by this set of values. Should be included then this set of values has a reference system (not just units). List of all the valid values and/or ranges of values for this quantity. For numeric quantities, signed values should be ordered from negative infinity to positive infinity. A single value, encoded as a string. This type can be used for one value, for a spacing between allowed values, or for the default value of a parameter. The default value for a quantity for which multiple values are allowed. A range of values of a numeric parameter. This range can be continuous or discrete, defined by a fixed spacing between adjacent valid values. If the MinimumValue or MaximumValue is not included, there is no value limit in that direction. Inclusion of the specified minimum and maximum values in the range shall be defined by the rangeClosure. Shall be included when the allowed values are NOT continuous in this range. Shall not be included when the allowed values are continuous in this range. Shall be included unless the default value applies. Minimum value of this numeric parameter. Maximum value of this numeric parameter. The regular distance or spacing between the allowed values in a range. Specifies which of the minimum and maximum values are included in the range. Note that plus and minus infinity are considered closed bounds. The specified minimum and maximum values are included in this range. The specified minimum and maximum values are NOT included in this range. The specified minimum value is NOT included in this range, and the specified maximum value IS included in this range. The specified minimum value IS included in this range, and the specified maximum value is NOT included in this range. References metadata about a quantity, and provides a name for this metadata. (Informative: This element was simplified from the metaDataProperty element in GML 3.0.) Human-readable name of the metadata described by associated referenced document. Reference to data or metadata recorded elsewhere, either external to this XML document or within it. Whenever practical, this attribute should be a URL from which this metadata can be electronically retrieved. Alternately, this attribute can reference a URN for well-known metadata. For example, such a URN could be a URN defined in the "ogc" URN namespace. Definition of the meaning or semantics of this set of values. This Meaning can provide more specific, complete, precise, machine accessible, and machine understandable semantics about this quantity, relative to other available semantic information. For example, other semantic information is often provided in "documentation" elements in XML Schemas or "description" elements in GML objects. Definition of the data type of this set of values. In this case, the xlink:href attribute can reference a URN for a well-known data type. For example, such a URN could be a data type identification URN defined in the "ogc" URN namespace. Definition of the reference system used by this set of values, including the unit of measure whenever applicable (as is normal). In this case, the xlink:href attribute can reference a URN for a well-known reference system, such as for a coordinate reference system (CRS). For example, such a URN could be a CRS identification URN defined in the "ogc" URN namespace. Definition of the unit of measure of this set of values. In this case, the xlink:href attribute can reference a URN for a well-known unit of measure (uom). For example, such a URN could be a UOM identification URN defined in the "ogc" URN namespace. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsExceptionReport.xsd ================================================ owsExceptionReport.xsd This XML Schema Document encodes the Exception Report response to all OWS operations. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Report message returned to the client that requested any OWS operation when the server detects an error while processing that operation request. Unordered list of one or more Exception elements that each describes an error. These Exception elements shall be interpreted by clients as being independent of one another (not hierarchical). Specification version for OWS operation. The string value shall contain one x.y.z "version" value (e.g., "2.1.3"). A version number shall contain three non-negative integers separated by decimal points, in the form "x.y.z". The integers y and z shall not exceed 99. Each version shall be for the Implementation Specification (document) and the associated XML Schemas to which requested operations will conform. An Implementation Specification version normally specifies XML Schemas against which an XML encoded operation response must conform and should be validated. See Version negotiation subclause for more information. Identifier of the language used by all included exception text values. These language identifiers shall be as specified in IETF RFC 4646. When this attribute is omitted, the language used is not identified. An Exception element describes one detected error that a server chooses to convey to the client. Ordered sequence of text strings that describe this specific exception or error. The contents of these strings are left open to definition by each server implementation. A server is strongly encouraged to include at least one ExceptionText value, to provide more information about the detected error than provided by the exceptionCode. When included, multiple ExceptionText values shall provide hierarchical information about one detected error, with the most significant information listed first. A code representing the type of this exception, which shall be selected from a set of exceptionCode values specified for the specific service operation and server. When included, this locator shall indicate to the client where an exception was encountered in servicing the client's operation request. This locator should be included whenever meaningful information can be provided by the server. The contents of this locator will depend on the specific exceptionCode and OWS service, and shall be specified in the OWS Implementation Specification. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsGetCapabilities.xsd ================================================ owsGetCapabilities.xsd This XML Schema Document defines the GetCapabilities operation request and response XML elements and types, which are common to all OWSs. This XML Schema shall be edited by each OWS, for example, to specify a specific value for the "service" attribute. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . XML encoded GetCapabilities operation response. This document provides clients with service metadata about a specific service instance, usually including metadata about the tightly-coupled data served. If the server does not implement the updateSequence parameter, the server shall always return the complete Capabilities document, without the updateSequence parameter. When the server implements the updateSequence parameter and the GetCapabilities operation request included the updateSequence parameter with the current value, the server shall return this element with only the "version" and "updateSequence" attributes. Otherwise, all optional elements shall be included or not depending on the actual value of the Contents parameter in the GetCapabilities operation request. This base type shall be extended by each specific OWS to include the additional contents needed. The list of languages that this service is able to fully support. That is, if one of the listed languages is requested using the AcceptLanguages parameter in future requests to the server, all text strings contained in the response are guaranteed to be in that language. This list does not necessarily constitute a complete list of all languages that may be (at least partially) supported by the server. It only states the languages that are fully supported. If a server cannot guarantee full support of any particular language, it shall omit it from the list of supported languages in the capabilities document. Service metadata document version, having values that are "increased" whenever any change is made in service metadata document. Values are selected by each server, and are always opaque to clients. When not supported by server, server shall not return this attribute. XML encoded GetCapabilities operation request. This operation allows clients to retrieve service metadata about a specific service instance. In this XML encoding, no "request" parameter is included, since the element name specifies the specific operation. This base type shall be extended by each specific OWS to include the additional required "service" attribute, with the correct value for that OWS. When omitted, server shall return latest supported version. When omitted or not supported by server, server shall return complete service metadata (Capabilities) document. When omitted or not supported by server, server shall return service metadata document using the MIME type "text/xml". Ordered list of languages desired by the client for all human readable text in the response, in order of preference. For every element, the first matching language available from the server shall be present in the response. When omitted or not supported by server, server shall return latest complete service metadata document. Service type identifier, where the string value is the OWS type abbreviation, such as "WMS" or "WFS". Prioritized sequence of one or more specification versions accepted by client, with preferred versions listed first. See Version negotiation subclause for more information. Unordered list of zero or more names of requested sections in complete service metadata document. Each Section value shall contain an allowed section name as specified by each OWS specification. See Sections parameter subclause for more information. Service metadata document version, having values that are "increased" whenever any change is made in service metadata document. Values are selected by each server, and are always opaque to clients. See updateSequence parameter use subclause for more information. Prioritized sequence of zero or more GetCapabilities operation response formats desired by client, with preferred formats listed first. Each response format shall be identified by its MIME type. See AcceptFormats parameter use subclause for more information. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsGetResourceByID.xsd ================================================ owsGetResourceByID.xsd This XML Schema Document encodes the GetResourceByID operation request message. This typical operation is specified as a base for profiling in specific OWS specifications. For information on the allowed changes and limitations in such profiling, see Subclause 9.4.1 of the OWS Common specification. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . XML encoded GetResourceByID operation response. The complexType used by this element shall be specified by each specific OWS. Request to a service to perform the GetResourceByID operation. This operation allows a client to retrieve one or more identified resources, including datasets and resources that describe datasets or parameters. In this XML encoding, no "request" parameter is included, since the element name specifies the specific operation. Unordered list of zero or more resource identifiers. These identifiers can be listed in the Contents section of the service metadata (Capabilities) document. For more information on this parameter, see Subclause 9.4.2.1 of the OWS Common specification. Optional reference to the data format to be used for response to this operation request. This element shall be included when multiple output formats are available for the selected resource(s), and the client desires a format other than the specified default, if any. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsInputOutputData.xsd ================================================ owsInputOutputData.xsd This XML Schema Document specifies types and elements for input and output of operation data, allowing including multiple data items with each data item either included or referenced. The contents of each type and element specified here can be restricted and/or extended for each use in a specific OWS specification. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Response from an OWS operation, allowing including multiple output data items with each item either included or referenced. This OperationResponse element, or an element using the ManifestType with a more specific element name, shall be used whenever applicable for responses from OWS operations. This element is specified for use where the ManifestType contents are needed for an operation response, but the Manifest element name is not fully applicable. This element or the ManifestType shall be used instead of using the ows:ReferenceType proposed in OGC 04-105. Input data in a XML-encoded OWS operation request, allowing including multiple data items with each data item either included or referenced. This InputData element, or an element using the ManifestType with a more-specific element name (TBR), shall be used whenever applicable within XML-encoded OWS operation requests. Complete reference to a remote resource that needs to be retrieved from an OWS using an XML-encoded operation request. This element shall be used, within an InputData or Manifest element that is used for input data, when that input data needs to be retrieved from another web service using a XML-encoded OWS operation request. This element shall not be used for local payload input data or for requesting the resource from a web server using HTTP Get. The XML-encoded operation request message to be sent to request this input data from another web server using HTTP Post. Reference to the XML-encoded operation request message to be sent to request this input data from another web server using HTTP Post. The referenced message shall be attached to the same message (using the cid scheme), or be accessible using a URL. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsManifest.xsd ================================================ owsManifest.xsd This XML Schema Document specifies types and elements for document or resource references and for package manifests that contain multiple references. The contents of each type and element specified here can be restricted and/or extended for each use in a specific OWS specification. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Base for a reference to a remote or local resource. This type contains only a restricted and annotated set of the attributes from the xlink:simpleAttrs attributeGroup. Reference to a remote resource or local payload. A remote resource is typically addressed by a URL. For a local payload (such as a multipart mime message), the xlink:href must start with the prefix cid:. Reference to a resource that describes the role of this reference. When no value is supplied, no particular role value is to be inferred. Although allowed, this attribute is not expected to be useful in this application of xlink:simpleAttrs. Describes the meaning of the referenced resource in a human-readable fashion. Although allowed, this attribute is not expected to be useful in this application of xlink:simpleAttrs. Although allowed, this attribute is not expected to be useful in this application of xlink:simpleAttrs. Complete reference to a remote or local resource, allowing including metadata about that resource. Optional unique identifier of the referenced resource. The format of the referenced resource. This element is omitted when the mime type is indicated in the http header of the reference. Optional unordered list of additional metadata about this resource. A list of optional metadata elements for this ReferenceType could be specified in the Implementation Specification for each use of this type in a specific OWS. Logical group of one or more references to remote and/or local resources, allowing including metadata about that group. A Group can be used instead of a Manifest that can only contain one group. Unordered list of one or more groups of references to remote and/or local resources. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsOperationsMetadata.xsd ================================================ owsOperationsMetadata.xsd This XML Schema Document encodes the basic contents of the "OperationsMetadata" section of the GetCapabilities operation response, also known as the Capabilities XML document. OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Metadata about the operations and related abilities specified by this service and implemented by this server, including the URLs for operation requests. The basic contents of this section shall be the same for all OWS types, but individual services can add elements and/or change the optionality of optional elements. Metadata for unordered list of all the (requests for) operations that this server interface implements. The list of required and optional operations implemented shall be specified in the Implementation Specification for this service. Optional unordered list of parameter valid domains that each apply to one or more operations which this server interface implements. The list of required and optional parameter domain limitations shall be specified in the Implementation Specification for this service. Optional unordered list of valid domain constraints on non-parameter quantities that each apply to this server. The list of required and optional constraints shall be specified in the Implementation Specification for this service. Individual software vendors and servers can use this element to provide metadata about any additional server abilities. Metadata for one operation that this server implements. Unordered list of Distributed Computing Platforms (DCPs) supported for this operation. At present, only the HTTP DCP is defined, so this element will appear only once. Optional unordered list of parameter domains that each apply to this operation which this server implements. If one of these Parameter elements has the same "name" attribute as a Parameter element in the OperationsMetadata element, this Parameter element shall override the other one for this operation. The list of required and optional parameter domain limitations for this operation shall be specified in the Implementation Specification for this service. Optional unordered list of valid domain constraints on non-parameter quantities that each apply to this operation. If one of these Constraint elements has the same "name" attribute as a Constraint element in the OperationsMetadata element, this Constraint element shall override the other one for this operation. The list of required and optional constraints for this operation shall be specified in the Implementation Specification for this service. Optional unordered list of additional metadata about this operation and its' implementation. A list of required and optional metadata elements for this operation should be specified in the Implementation Specification for this service. (Informative: This metadata might specify the operation request parameters or provide the XML Schemas for the operation request.) Name or identifier of this operation (request) (for example, GetCapabilities). The list of required and optional operations implemented shall be specified in the Implementation Specification for this service. Information for one distributed Computing Platform (DCP) supported for this operation. At present, only the HTTP DCP is defined, so this element only includes the HTTP element. Connect point URLs for the HTTP Distributed Computing Platform (DCP). Normally, only one Get and/or one Post is included in this element. More than one Get and/or Post is allowed to support including alternative URLs for uses such as load balancing or backup. Connect point URL prefix and any constraints for the HTTP "Get" request method for this operation request. Connect point URL and any constraints for the HTTP "Post" request method for this operation request. Connect point URL and any constraints for this HTTP request method for this operation request. In the OnlineResourceType, the xlink:href attribute in the xlink:simpleAttrs attribute group shall be used to contain this URL. The other attributes in the xlink:simpleAttrs attribute group should not be used. Optional unordered list of valid domain constraints on non-parameter quantities that each apply to this request method for this operation. If one of these Constraint elements has the same "name" attribute as a Constraint element in the OperationsMetadata or Operation element, this Constraint element shall override the other one for this operation. The list of required and optional constraints for this request method for this operation shall be specified in the Implementation Specification for this service. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsServiceIdentification.xsd ================================================ owsServiceIdentification.xsd This XML Schema Document encodes the common "ServiceIdentification" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceIdentification class of ISO 19119 (OGC Abstract Specification Topic 12). OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . General metadata for this specific server. This XML Schema of this section shall be the same for all OWS. A service type name from a registry of services. For example, the values of the codeSpace URI and name and code string may be "OGC" and "catalogue." This type name is normally used for machine-to-machine communication. Unordered list of one or more versions of this service type implemented by this server. This information is not adequate for version negotiation, and shall not be used for that purpose. Unordered list of identifiers of Application Profiles that are implemented by this server. This element should be included for each specified application profile implemented by this server. The identifier value should be specified by each Application Profile. If this element is omitted, no meaning is implied. If this element is omitted, no meaning is implied. Unordered list of access constraints applied to assure the protection of privacy or intellectual property, and any other restrictions on retrieving or using data from or otherwise using this server. The reserved value NONE (case insensitive) shall be used to mean no access constraints are imposed. When this element is omitted, no meaning is implied. ================================================ FILE: pycsw/core/schemas/ogc/ows/2.0/owsServiceProvider.xsd ================================================ owsServiceProvider.xsd This XML Schema Document encodes the common "ServiceProvider" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceProvider class of ISO 19119 (OGC Abstract Specification Topic 12). OWS is an OGC Standard. Copyright (c) 2009 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . Metadata about the organization that provides this specific service instance or server. A unique identifier for the service provider organization. Reference to the most relevant web site of the service provider. Information for contacting the service provider. The OnlineResource element within this ServiceContact element should not be used to reference a web site of the service provider. ================================================ FILE: pycsw/core/schemas/w3c/1999/xlink.xsd ================================================ This schema document provides attribute declarations and attribute group, complex type and simple type definitions which can be used in the construction of user schemas to define the structure of particular linking constructs, e.g. ... ... ... ]]> Intended for use as the type of user-declared elements to make them simple links. Intended for use as the type of user-declared elements to make them extended links. Note that the elements referenced in the content model are all abstract. The intention is that by simply declaring elements with these as their substitutionGroup, all the right things will happen. xml:lang is not required, but provides much of the motivation for title elements in addition to attributes, and so is provided here for convenience. label is not required, but locators have no particular XLink function if they are not labeled. from and to have default behavior when values are missing ================================================ FILE: pycsw/core/schemas/w3c/2001/xml.xsd ================================================

About the XML namespace

This schema document describes the XML namespace, in a form suitable for import by other schema documents.

See http://www.w3.org/XML/1998/namespace.html and http://www.w3.org/TR/REC-xml for information about this namespace.

Note that local names in this namespace are intended to be defined only by the World Wide Web Consortium or its subgroups. The names currently defined in this namespace are listed below. They should not be used with conflicting semantics by any Working Group, specification, or document instance.

See further below in this document for more information about how to refer to this schema document from your own XSD schema documents and about the namespace-versioning policy governing this schema document.

lang (as an attribute name)

denotes an attribute whose value is a language code for the natural language of the content of any element; its value is inherited. This name is reserved by virtue of its definition in the XML specification.

Notes

Attempting to install the relevant ISO 2- and 3-letter codes as the enumerated possible values is probably never going to be a realistic possibility.

See BCP 47 at http://www.rfc-editor.org/rfc/bcp/bcp47.txt and the IANA language subtag registry at http://www.iana.org/assignments/language-subtag-registry for further information.

The union allows for the 'un-declaration' of xml:lang with the empty string.

space (as an attribute name)

denotes an attribute whose value is a keyword indicating what whitespace processing discipline is intended for the content of the element; its value is inherited. This name is reserved by virtue of its definition in the XML specification.

base (as an attribute name)

denotes an attribute whose value provides a URI to be used as the base for interpreting any relative URIs in the scope of the element on which it appears; its value is inherited. This name is reserved by virtue of its definition in the XML Base specification.

See http://www.w3.org/TR/xmlbase/ for information about this attribute.

id (as an attribute name)

denotes an attribute whose value should be interpreted as if declared to be of type ID. This name is reserved by virtue of its definition in the xml:id specification.

See http://www.w3.org/TR/xml-id/ for information about this attribute.

Father (in any context at all)

denotes Jon Bosak, the chair of the original XML Working Group. This name is reserved by the following decision of the W3C XML Plenary and XML Coordination groups:

In appreciation for his vision, leadership and dedication the W3C XML Plenary on this 10th day of February, 2000, reserves for Jon Bosak in perpetuity the XML name "xml:Father".

About this schema document

This schema defines attributes and an attribute group suitable for use by schemas wishing to allow xml:base, xml:lang, xml:space or xml:id attributes on elements they define.

To enable this, such a schema must import this schema for the XML namespace, e.g. as follows:

          <schema . . .>
           . . .
           <import namespace="http://www.w3.org/XML/1998/namespace"
                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
     

or

           <import namespace="http://www.w3.org/XML/1998/namespace"
                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
     

Subsequently, qualified reference to any of the attributes or the group defined below will have the desired effect, e.g.

          <type . . .>
           . . .
           <attributeGroup ref="xml:specialAttrs"/>
     

will define a type which will schema-validate an instance element with any of those attributes.

Versioning policy for this schema document

In keeping with the XML Schema WG's standard versioning policy, this schema document will persist at http://www.w3.org/2009/01/xml.xsd.

At the date of issue it can also be found at http://www.w3.org/2001/xml.xsd.

The schema document at that URI may however change in the future, in order to remain compatible with the latest version of XML Schema itself, or with the XML namespace itself. In other words, if the XML Schema or XML namespaces change, the version of this document at http://www.w3.org/2001/xml.xsd will change accordingly; the version at http://www.w3.org/2009/01/xml.xsd will not change.

Previous dated (and unchanging) versions of this schema document are at:

================================================ FILE: pycsw/core/util.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # Ricardo Garcia Silva # # Copyright (c) 2025 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from configparser import BasicInterpolation, ConfigParser from pathlib import Path import importlib import importlib.util import json import os import re import datetime import logging import sys import time import typing from urllib.request import Request, urlopen from urllib.parse import urlparse from shapely.geometry import shape from shapely.wkt import loads from owslib.util import http_post from pycsw.core.etree import etree, PARSER LOGGER = logging.getLogger(__name__) # Global variables for spatial ranking algorithm ranking_enabled = False ranking_pass = False ranking_query_geometry = '' # Lookups for the secure_filename function # https://github.com/pallets/werkzeug/blob/778f482d1ac0c9e8e98f774d2595e9074e6984d7/werkzeug/utils.py#L30-L31 _filename_ascii_strip_re = re.compile(r'[^A-Za-z0-9_.-]') _windows_device_files = ('CON', 'AUX', 'COM1', 'COM2', 'COM3', 'COM4', 'LPT1', 'LPT2', 'LPT3', 'PRN', 'NUL') def get_today_and_now(): """Get the date, right now, in ISO8601""" return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime()) def datetime2iso8601(value): """Return a datetime value as ISO8601 Parameters ---------- value: datetime.date or datetime.datetime The temporal value to be converted Returns ------- str A string with the temporal value in ISO8601 format. """ if isinstance(value, datetime.datetime): if value == value.replace(hour=0, minute=0, second=0, microsecond=0): result = value.strftime("%Y-%m-%d") else: result = value.strftime("%Y-%m-%dT%H:%M:%SZ") else: # value is a datetime.date result = value.strftime('%Y-%m-%d') return result def get_time_iso2unix(isotime): """Convert ISO8601 to UNIX timestamp""" return int(time.mktime(time.strptime( isotime, '%Y-%m-%dT%H:%M:%SZ'))) - time.timezone def get_version_integer(version): """Get an integer of the OGC version value x.y.z In case of an invalid version string this returns -1. Parameters ---------- version: str The version string that is to be transformed into an integer Returns ------- int The transformed version Raises ------ RuntimeError When the input version is neither a string or None """ try: xyz = version.split('.') if len(xyz) == 3: result = int(xyz[0]) * 10000 + int(xyz[1]) * 100 + int(xyz[2]) else: result = -1 except AttributeError as err: raise RuntimeError('%s' % str(err)) from err return result def nspath_eval(xpath, nsmap): """Return an etree friendly xpath. This function converts XPath expressions that use prefixes into their full namespace. This is the form expected by lxml [1]_. Parameters ---------- xpath: str The XPath expression to be converted nsmap: dict Returns ------- str The XPath expression using namespaces instead of prefixes. References ---------- .. [1] http://lxml.de/tutorial.html#namespaces """ out = [] for node in xpath.split('/'): chunks = node.split(":") if len(chunks) == 2: prefix, element = node.split(':') out.append('{%s}%s' % (nsmap[prefix], element)) elif len(chunks) == 1: out.append(node) else: raise RuntimeError(f"Invalid XPath expression: {xpath}") return '/'.join(out) def wktenvelope2bbox(envelope): """returns bbox string of WKT ENVELOPE definition""" tmparr = [x.strip() for x in envelope.split('(')[1].split(')')[0].split(',')] bbox = '%s,%s,%s,%s' % (tmparr[0], tmparr[3], tmparr[1], tmparr[2]) return bbox def geojson_geometry2bbox(geometry): """returns bbox string of GeoJSON geometry""" bounds = shape(geometry).bounds return ','.join([str(b) for b in bounds]) def wkt2geom(ewkt, bounds=True): """Return Shapely geometry object based on WKT/EWKT Parameters ---------- ewkt: str The geometry to convert, in Extended Well-Known Text format. More info on this format at [1]_ bounds: bool Whether to return only the bounding box of the geometry as a tuple or the full shapely geometry instance Returns ------- shapely.geometry.base.BaseGeometry or tuple Depending on the value of the ``bounds`` parameter, returns either the shapely geometry instance or a tuple with the bounding box. References ---------- .. [1] http://postgis.net/docs/ST_GeomFromEWKT.html """ wkt = ewkt.split(";")[-1] if ewkt.find("SRID") != -1 else ewkt if wkt.startswith('ENVELOPE'): wkt = bbox2wktpolygon(wktenvelope2bbox(wkt)) geometry = loads(wkt) return geometry.envelope.bounds if bounds else geometry def bbox2wktpolygon(bbox): """Return OGC WKT Polygon of a simple bbox string Parameters ---------- bbox: str The bounding box to convert to WKT. Returns ------- str The bounding box's Well-Known Text representation. """ precision = int(os.environ.get('COORDINATE_PRECISION', 2)) if bbox.startswith('ENVELOPE'): bbox = wktenvelope2bbox(bbox) minx, miny, maxx, maxy = [f"{float(coord):.{precision}f}" for coord in bbox.split(",")] wktGeometry = 'POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' \ % (minx, miny, minx, maxy, maxx, maxy, maxx, miny, minx, miny) return wktGeometry def transform_mappings(queryables, typename): """Transform metadata model mappings Parameters ---------- queryables: dict typename: dict """ for item in queryables: try: matching_typename = [key for key, value in typename.items() if value == item][0] queryable_value = queryables[matching_typename] queryables[item] = { "xpath": queryable_value["xpath"], "dbcol": queryable_value["dbcol"], } except IndexError: pass def getqattr(obj, name): """Get value of an object, safely""" result = None try: item = getattr(obj, name) value = item() if "link" in name: # create link format links = [] for link in value: links.append(','.join(list(link))) result = '^'.join(links) else: result = value except TypeError: # item is not callable try: result = datetime2iso8601(item) except AttributeError: # item is not date(time) result = item except AttributeError: # obj does not have a name property pass return result def http_request(method, url, request=None, timeout=30): """Perform HTTP request""" if method == 'POST': return http_post(url, request, timeout=timeout) else: # GET request = Request(url) request.add_header('User-Agent', 'pycsw (https://pycsw.org/)') return urlopen(request, timeout=timeout).read() def bind_url(url): """binds an HTTP GET query string endpoint""" parsed_url = urlparse(url) if parsed_url.query == "": binder = "?" elif parsed_url.query.endswith("&"): binder = "" else: binder = "&" return "".join((parsed_url.geturl(), binder)) def ip_in_network_cidr(ip, net): """decipher whether IP is within CIDR range""" ipaddr = int( ''.join(['%02x' % int(x) for x in ip.split('.')]), 16 ) netstr, bits = net.split('/') netaddr = int( ''.join(['%02x' % int(x) for x in netstr.split('.')]), 16 ) mask = (0xffffffff << (32 - int(bits))) & 0xffffffff return (ipaddr & mask) == (netaddr & mask) def ipaddress_in_whitelist(ipaddress, whitelist): """decipher whether IP is in IP whitelist IP whitelist is a list supporting: - single IP address (e.g. 192.168.0.1) - IP range using CIDR (e.g. 192.168.0/22) - IP range using subnet wildcard (e.g. 192.168.0.*, 192.168.*) """ if ipaddress in whitelist: return True else: for white in whitelist: if white.find('/') != -1: # CIDR if ip_in_network_cidr(ipaddress, white): return True elif white.find('*') != -1: # subnet wildcard if ipaddress.startswith(white.split('*')[0]): return True return False def get_anytext(bag): """ generate bag of text for free text searches accepts list of words, string of XML, or etree.Element """ if isinstance(bag, list): # list of words return ' '.join([_f for _f in bag if _f]).strip() else: # xml if isinstance(bag, bytes) or isinstance(bag, str): # serialize to lxml bag = etree.fromstring(bag, PARSER) # get all XML element content return ' '.join([value.strip() for value in bag.xpath('//text()')]) # https://stackoverflow.com/a/39234154 def get_anytext_from_obj(obj): """ generate bag of text for free text searches accepts dict, list or string """ if isinstance(obj, dict): for key, value in obj.items(): if isinstance(value, (list, dict)): yield from get_anytext_from_obj(value) else: yield value elif isinstance(obj, list): for value in obj: if isinstance(value, (list, dict)): yield from get_anytext_from_obj(value) else: yield value # https://github.com/pallets/werkzeug/blob/778f482d1ac0c9e8e98f774d2595e9074e6984d7/werkzeug/utils.py#L253 def secure_filename(filename): r"""Pass it a filename and it will return a secure version of it. This filename can then safely be stored on a regular file system and passed to :func:`os.path.join`. The filename returned is an ASCII only string for maximum portability. On windows systems the function also makes sure that the file is not named after one of the special device files. >>> secure_filename("My cool movie.mov") 'My_cool_movie.mov' >>> secure_filename("../../../etc/passwd") 'etc_passwd' >>> secure_filename(u'i contain cool \xfcml\xe4uts.txt') 'i_contain_cool_umlauts.txt' The function might return an empty filename. It's your responsibility to ensure that the filename is unique and that you abort or generate a random filename if the function returned an empty one. .. versionadded:: 0.5 :param filename: the filename to secure """ if isinstance(filename, str): from unicodedata import normalize filename = normalize('NFKD', filename).encode('ascii', 'ignore') filename = filename.decode('ascii') for sep in os.path.sep, os.path.altsep: if sep: filename = filename.replace(sep, ' ') filename = str(_filename_ascii_strip_re.sub('', '_'.join( filename.split()))).strip('._') # on nt a couple of special files are present in each folder. We # have to ensure that the target file is not such a filename. In # this case we prepend an underline if os.name == 'nt' and filename and \ filename.split('.')[0].upper() in _windows_device_files: filename = '_' + filename return filename def jsonify_links(links): """ pycsw:Links column data handler. casts old or new style links into JSON objects """ try: LOGGER.debug('JSON link') linkset = json.loads(links) return linkset except json.decoder.JSONDecodeError: # try CSV parsing LOGGER.debug('old style CSV link') json_links = [] for link in links.split('^'): tokens = link.split(',') json_links.append({ 'name': tokens[0] or None, 'description': tokens[1] or None, 'protocol': tokens[2] or None, 'url': tokens[3] or None }) return json_links class EnvInterpolation(BasicInterpolation): """ Interpolation which expands environment variables in values. from: https://stackoverflow.com/a/49529659 """ def before_get(self, parser, section, option, value, defaults): value = super().before_get(parser, section, option, value, defaults) return os.path.expandvars(value) def parse_ini_config(config_path) -> ConfigParser: """ Helper function to parse a .ini configuration file :param config_path: filepath :returns: ConfigParser object """ config = ConfigParser(interpolation=EnvInterpolation()) with open(config_path, encoding='utf-8') as scp: config.read_file(scp) return config def is_none_or_empty(value): """ Helper function to detect if value is None or empty :param value: value to evaluate :returns: bool of whether the value is None or empty """ if value is None or len(value.strip()) == 0: return True return False def programmatic_import(target_module: str) -> typing.Optional[typing.Any]: result = None target_module_path = Path(target_module) if target_module_path.is_file(): module_name = target_module_path.stem # this is an adaptation of the Python docs on using importlib to import a # filepath: # https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly spec = importlib.util.spec_from_file_location( module_name, target_module_path) if spec is not None: module = importlib.util.module_from_spec(spec) sys.modules[module_name] = module spec.loader.exec_module(module) result = module else: try: result = importlib.import_module(target_module) except ModuleNotFoundError: pass return result def load_custom_repo_mappings(repository_mappings: str) -> typing.Optional[typing.Dict]: imported_mappings_module = programmatic_import(repository_mappings) result = None if imported_mappings_module is not None: result = getattr(imported_mappings_module, "MD_CORE_MODEL", None) return result def sanitize_db_connect (url): """ helper function to remove user:pw from db connect for logging purposes :param url: value to be sanitized :returns: `str` sanitized """ if '@' in url: return url.split('://')[0] + '://***:***@' + url.split('@').pop() else: return url def str2bool(value: typing.Union[bool, str]) -> bool: """ helper function to return Python boolean type (source: https://stackoverflow.com/a/715468) :param value: value to be evaluated :returns: `bool` of whether the value is boolean-ish """ value2 = False if isinstance(value, bool): value2 = value else: value2 = value.lower() in ('yes', 'true', 't', '1', 'on') return value2 def remove_url_auth(url: str) -> str: """ Provide a RFC1738 URL without embedded authentication :param url: RFC1738 URL :returns: RFC1738 URL without authentication """ u = urlparse(url) auth = f'{u.username}:{u.password}@' return url.replace(auth, '') ================================================ FILE: pycsw/oaipmh.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from pycsw.core import util from pycsw.core.etree import etree LOGGER = logging.getLogger(__name__) class OAIPMH(object): """OAI-PMH wrapper class""" def __init__(self, context, config): LOGGER.debug('Initializing OAI-PMH constants') self.oaipmh_version = '2.0' self.namespaces = { 'oai': 'http://www.openarchives.org/OAI/2.0/', 'oai_dc': 'http://www.openarchives.org/OAI/2.0/oai_dc/', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance' } self.request_model = { 'Identify': [], 'ListSets': ['resumptiontoken'], 'ListMetadataFormats': ['identifier'], 'GetRecord': ['identifier', 'metadataprefix'], 'ListRecords': ['from', 'until', 'set', 'resumptiontoken', 'metadataprefix'], 'ListIdentifiers': ['from', 'until', 'set', 'resumptiontoken', 'metadataprefix'], } self.metadata_formats = { 'iso19139': { 'namespace': 'http://www.isotc211.org/2005/gmd', 'schema': 'http://www.isotc211.org/2005/gmd/gmd.xsd', 'identifier': './/gmd:fileIdentifier/gco:CharacterString', 'datestamp': './/gmd:dateStamp/gco:DateTime|.//gmd:dateStamp/gco:Date', 'setSpec': './/gmd:hierarchyLevel/gmd:MD_ScopeCode' }, 'csw-record': { 'namespace': 'http://www.opengis.net/cat/csw/2.0.2', 'schema': 'http://schemas.opengis.net/csw/2.0.2/record.xsd', 'identifier': './/dc:identifier', 'datestamp': './/dct:modified', 'setSpec': './/dc:type' }, 'fgdc-std': { 'namespace': 'http://www.opengis.net/cat/csw/csdgm', 'schema': 'http://www.fgdc.gov/metadata/fgdc-std-001-1998.xsd', 'identifier': './/idinfo/datasetid', 'datestamp': './/metainfo/metd', 'setSpec': './/dataset' }, 'oai_dc': { 'namespace': '%soai_dc/' % self.namespaces['oai'], 'schema': 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd', 'identifier': './/dc:identifier', 'datestamp': './/dct:modified', 'setSpec': './/dc:type' }, 'dif': { 'namespace': 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/', 'schema': 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/dif.xsd', 'identifier': './/dif:Entry_ID', 'datestamp': './/dif:Last_DIF_Revision_Date', 'setSpec': '//dataset' }, 'gm03': { 'namespace': 'http://www.interlis.ch/INTERLIS2.3', 'schema': 'http://www.geocat.ch/internet/geocat/en/home/documentation/gm03.parsys.50316.downloadList.86742.DownloadFile.tmp/gm0321.zip', 'identifier': './/gm03:DATASECTION//gm03:fileIdentifer', 'datestamp': './/gm03:DATASECTION//gm03:dateStamp', 'setSpec': './/dataset' }, 'datacite': { 'namespace': 'http://datacite.org/schema/kernel-4', 'schema': 'http://schema.datacite.org/meta/kernel-4.3/metadata.xsd', 'identifier': '//identifier', 'datestamp': '//dates/date', 'setSpec': '' } } self.metadata_sets = { 'datasets': ('Datasets', 'dataset'), 'interactiveResources': ('Interactive Resources', 'service') } self.error_codes = { 'badArgument': 'InvalidParameterValue', 'badVerb': 'OperationNotSupported', 'idDoesNotExist': None, 'noRecordsMatch': None, } self.context = context self.context.namespaces.update(self.namespaces) self.context.namespaces.update({'gco': 'http://www.isotc211.org/2005/gco'}) self.config = config def request(self, kvp): """process OAI-PMH request""" kvpout = {'service': 'CSW', 'version': '2.0.2', 'mode': 'oaipmh'} LOGGER.debug('Incoming kvp: %s', kvp) if 'verb' in kvp: if 'metadataprefix' in kvp: self.metadata_prefix = kvp['metadataprefix'] try: kvpout['outputschema'] = self._get_metadata_prefix(kvp['metadataprefix']) except KeyError: kvpout['outputschema'] = kvp['metadataprefix'] else: self.metadata_prefix = 'csw-record' LOGGER.debug('metadataPrefix: %s', self.metadata_prefix) if kvp['verb'] in ['ListRecords', 'ListIdentifiers', 'GetRecord']: kvpout['request'] = 'GetRecords' kvpout['resulttype'] = 'results' kvpout['typenames'] = 'csw:Record' kvpout['elementsetname'] = 'full' if kvp['verb'] in ['Identify', 'ListMetadataFormats', 'ListSets']: kvpout['request'] = 'GetCapabilities' elif kvp['verb'] == 'GetRecord': kvpout['request'] = 'GetRecordById' if 'identifier' in kvp: kvpout['id'] = kvp['identifier'] if ('outputschema' in kvpout and kvp['metadataprefix'] == 'oai_dc'): # just use default DC del kvpout['outputschema'] elif kvp['verb'] in ['ListRecords', 'ListIdentifiers']: if 'resumptiontoken' in kvp: kvpout['startposition'] = kvp['resumptiontoken'] if ('outputschema' in kvpout and kvp['verb'] == 'ListIdentifiers'): # simple output only pass #del kvpout['outputschema'] if ('outputschema' in kvpout and kvp['metadataprefix'] in ['dc', 'oai_dc']): # just use default DC del kvpout['outputschema'] start = end = None LOGGER.debug('Scanning temporal parameters') if 'from' in kvp: start = 'dc:date >= %s' % kvp['from'] if 'until' in kvp: end = 'dc:date <= %s' % kvp['until'] if any([start is not None, end is not None]): if all([start is not None, end is not None]): time_query = '%s and %s' % (start, end) elif end is None: time_query = start elif start is None: time_query = end kvpout['constraintlanguage'] = 'CQL_TEXT' kvpout['constraint'] = time_query LOGGER.debug('Resulting parameters: %s', kvpout) return kvpout def response(self, response, kvp, repository, server_url): """process OAI-PMH request""" mode = kvp.pop('mode', None) if 'config' in kvp: config_val = kvp.pop('config') url = '%smode=oaipmh' % util.bind_url(server_url) node = etree.Element(util.nspath_eval('oai:OAI-PMH', self.namespaces), nsmap=self.namespaces) node.set(util.nspath_eval('xsi:schemaLocation', self.namespaces), '%s http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd' % self.namespaces['oai']) LOGGER.debug(etree.tostring(node)) etree.SubElement(node, util.nspath_eval('oai:responseDate', self.namespaces)).text = util.get_today_and_now() kvp2 = dict(kvp) if 'metadataprefix' in kvp2: kvp2['metadataPrefix'] = kvp2.pop('metadataprefix') etree.SubElement(node, util.nspath_eval('oai:request', self.namespaces), attrib=kvp2).text = url if 'verb' not in kvp: etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = 'Missing \'verb\' parameter' return node if kvp['verb'] not in self.request_model.keys(): etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = 'Unknown verb \'%s\'' % kvp['verb'] return node if etree.QName(response).localname == 'ExceptionReport': etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = response.xpath('//ows:ExceptionText|//ows20:ExceptionText', namespaces=self.context.namespaces)[0].text return node verb = kvp.pop('verb') if verb in ['GetRecord', 'ListIdentifiers', 'ListRecords']: if 'metadataprefix' not in kvp: etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = 'Missing metadataPrefix parameter' return node elif kvp['metadataprefix'] not in self.metadata_formats.keys(): etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = 'Invalid metadataPrefix parameter' return node for key, value in kvp.items(): if key != 'mode' and key not in self.request_model[verb]: etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = 'Illegal parameter \'%s\'' % key return node verbnode = etree.SubElement(node, util.nspath_eval('oai:%s' % verb, self.namespaces)) if verb == 'Identify': etree.SubElement(verbnode, util.nspath_eval('oai:repositoryName', self.namespaces)).text = self.config['metadata']['identification']['title'] etree.SubElement(verbnode, util.nspath_eval('oai:baseURL', self.namespaces)).text = url etree.SubElement(verbnode, util.nspath_eval('oai:protocolVersion', self.namespaces)).text = '2.0' etree.SubElement(verbnode, util.nspath_eval('oai:adminEmail', self.namespaces)).text = self.config['metadata']['contact']['email'] etree.SubElement(verbnode, util.nspath_eval('oai:earliestDatestamp', self.namespaces)).text = repository.query_insert('min') etree.SubElement(verbnode, util.nspath_eval('oai:deletedRecord', self.namespaces)).text = 'no' etree.SubElement(verbnode, util.nspath_eval('oai:granularity', self.namespaces)).text = 'YYYY-MM-DDThh:mm:ssZ' elif verb == 'ListSets': for key, value in sorted(self.metadata_sets.items()): setnode = etree.SubElement(verbnode, util.nspath_eval('oai:set', self.namespaces)) etree.SubElement(setnode, util.nspath_eval('oai:setSpec', self.namespaces)).text = key etree.SubElement(setnode, util.nspath_eval('oai:setName', self.namespaces)).text = value[0] elif verb == 'ListMetadataFormats': for key, value in sorted(self.metadata_formats.items()): mdfnode = etree.SubElement(verbnode, util.nspath_eval('oai:metadataFormat', self.namespaces)) etree.SubElement(mdfnode, util.nspath_eval('oai:metadataPrefix', self.namespaces)).text = key etree.SubElement(mdfnode, util.nspath_eval('oai:schema', self.namespaces)).text = value['schema'] etree.SubElement(mdfnode, util.nspath_eval('oai:metadataNamespace', self.namespaces)).text = value['namespace'] elif verb in ['GetRecord', 'ListIdentifiers', 'ListRecords']: if verb == 'GetRecord': # GetRecordById records = response.getchildren() else: # GetRecords & ListIdentifiers records = response.getchildren()[1].getchildren() for child in records: if verb == 'ListIdentifiers': header = etree.SubElement(verbnode, util.nspath_eval('oai:header', self.namespaces)) recnode = header else: recnode = etree.SubElement(verbnode, util.nspath_eval('oai:record', self.namespaces)) header = etree.SubElement(recnode, util.nspath_eval('oai:header', self.namespaces)) self._transform_element(header, child, 'oai:identifier') self._transform_element(header, child, 'oai:datestamp') self._transform_element(header, child, 'oai:setSpec') if verb in ['GetRecord', 'ListRecords']: metadata = etree.SubElement(recnode, util.nspath_eval('oai:metadata', self.namespaces)) if 'metadataprefix' in kvp and kvp['metadataprefix'] == 'oai_dc': child.tag = util.nspath_eval('oai_dc:dc', self.namespaces) metadata.append(child) if verb != 'GetRecord': complete_list_size = response.xpath('//@numberOfRecordsMatched')[0] next_record = response.xpath('//@nextRecord')[0] cursor = str(int(complete_list_size) - int(next_record) - 1) resumption_token = etree.SubElement(verbnode, util.nspath_eval('oai:resumptionToken', self.namespaces), completeListSize=complete_list_size, cursor=cursor) if int(next_record) > 0: resumption_token.text = next_record return node def _get_metadata_prefix(self, prefix): """Convenience function to return metadataPrefix as CSW outputschema""" try: outputschema = self.metadata_formats[prefix]['namespace'] except KeyError: outputschema = prefix return outputschema def _transform_element(self, parent, element, elname): """tests for existence of a given xpath, writes out text if exists""" xpath = self.metadata_formats[self.metadata_prefix][elname.split(':')[1]] if xpath.startswith(('.//', '//')): value = element.xpath(xpath, namespaces=self.context.namespaces) if value: value = value[0].text else: # bare string literal value = xpath el = etree.SubElement(parent, util.nspath_eval(elname, self.context.namespaces)) if value: if elname == 'oai:setSpec': value = None for k, v in self.metadata_sets.items(): if v[1] == elname: value = k break el.text = value ================================================ FILE: pycsw/ogc/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/ogc/api/__init__.py ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2021 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/ogc/api/oapi.py ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from copy import deepcopy import logging from pycsw import __version__ from pycsw.core.util import str2bool from pycsw.ogc.api.util import yaml_load LOGGER = logging.getLogger(__name__) def gen_oapi(config, oapi_filepath, mode='ogcapi-records'): """ Genrate OpenAPI document :param config: configuration :param oapi_filepath: path to base OpenAPI records schema :returns: `dict` of OpenAPI document """ oapi = {} with open(oapi_filepath, encoding='utf8') as fh: oapi = yaml_load(fh) LOGGER.debug('Adding tags') oapi['tags'] = [{ 'name': 'Capabilities', 'description': 'essential characteristics of this API' }, { 'name': 'Metadata', 'description': 'access to metadata (records)' }] LOGGER.debug('Adding response components') oapi['components']['responses']['Queryables'] = { 'content': { 'application/json': { 'schema': { '$ref': '#/components/schemas/queryables' } } }, 'description': 'successful queryables operation' } oapi['components']['schemas']['queryable'] = { 'properties': { 'description': { 'description': 'a human-readable narrative describing the queryable', # noqa 'type': 'string' }, 'language': { 'default': [ 'en' ], 'description': 'the language used for the title and description', # noqa 'type': 'string' }, 'queryable': { 'description': 'the token that may be used in a CQL predicate', 'type': 'string' }, 'title': { 'description': 'a human readable title for the queryable', 'type': 'string' }, 'type': { 'description': 'the data type of the queryable', 'type': 'string' }, 'type-ref': { 'description': 'a reference to the formal definition of the type', # noqa 'format': 'url', 'type': 'string' } }, 'required': [ 'queryable', 'type' ], 'type': 'object' } oapi['components']['schemas']['queryables'] = { 'properties': { 'queryables': { 'items': { '$ref': '#/components/schemas/queryable' }, 'type': 'array' } }, 'required': [ 'queryables' ], 'type': 'object' } LOGGER.debug('Adding parameter components') oapi['components']['parameters']['f'] = { 'name': 'f', 'in': 'query', 'description': 'Optional output formats', 'required': False, 'schema': { 'type': 'string', 'enum': ['json', 'html'], 'default': 'json' }, 'style': 'form', 'explode': False } oapi['components']['parameters']['offset'] = { 'name': 'offset', 'in': 'query', 'description': 'The optional offset parameter indicates the index within the result set from which the server shall begin presenting results in the response document. The first element has an index of 0 (default).', # noqa 'required': False, 'schema': { 'type': 'integer', 'minimum': 0, 'default': 0 }, 'style': 'form', 'explode': False } oapi['components']['parameters']['filter'] = { 'name': 'filter', 'in': 'query', 'description': 'The optional filter parameter specifies a CQL2 expression to be used for enhanced filtering', # noqa 'required': False, 'schema': { 'type': 'object' }, 'style': 'form', 'explode': False } oapi['components']['parameters']['filter-lang'] = { 'name': 'filter-lang', 'in': 'query', 'description': 'The optional filter-lang parameter specifies the predicate language of the filter being applied', # noqa 'required': False, 'schema': { 'type': 'string', 'enum': [ 'cql2-json', 'cql2-text' ], 'default': 'cql2-text' }, 'style': 'form', 'explode': False } oapi['components']['parameters']['vendorSpecificParameters'] = { 'name': 'vendorSpecificParameters', 'in': 'query', 'description': 'Additional "free-form" parameters that are not explicitly defined', # noqa 'schema': { 'type': 'object', 'additionalProperties': True }, 'style': 'form' } oapi['components']['parameters']['facets'] = { 'name': 'facets', 'in': 'query', 'description': 'Whether to include facets in results', 'schema': { 'type': 'boolean', 'default': False }, 'style': 'form', 'explode': False } oapi['components']['parameters']['distributedSearch'] = { 'name': 'distributedSearch', 'in': 'query', 'description': 'Whether to invoke distributed search', 'schema': { 'type': 'boolean', 'default': False }, 'style': 'form', 'explode': False } # TODO: remove local definition of ids once implemented # in OGC API - Records oapi['components']['parameters']['ids'] = { 'name': 'ids', 'in': 'query', 'description': 'Comma-separated list of identifiers', 'required': False, 'schema': { 'type': 'array', 'items': { 'type': 'string' } }, 'style': 'form', 'explode': False } if mode == 'stac-api': oapi['components']['parameters']['collections'] = { 'name': 'collections', 'in': 'query', 'description': 'Comma-separated list of collection identifiers', 'required': False, 'schema': { 'type': 'array', 'items': { 'type': 'string' } }, 'style': 'form', 'explode': False } LOGGER.debug('Adding server info') oapi['info'] = { 'contact': { 'email': config['metadata']['contact']['email'], 'name': config['metadata']['contact']['name'], 'url': config['metadata']['contact']['url'] }, 'version': __version__, 'title': config['metadata']['identification']['title'], 'description': config['metadata']['identification']['description'] } oapi['servers'] = [{ 'url': config['server'].get('url'), 'description': config['metadata']['identification']['description'] }] LOGGER.debug('Adding paths') oapi['paths'] = {} path = { 'get': { 'tags': ['Capabilities'], 'summary': 'Landing page', 'description': 'Landing page', 'operationId': 'getLandingPage', 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { '200': { '$ref': '#/components/responses/Queryables' }, '500': { '$ref': '#/components/responses/ServerError' } } } } oapi['paths']['/'] = path path = { 'get': { 'tags': ['Capabilities'], 'summary': 'Conformance page', 'description': 'Conformance page', 'operationId': 'getConformanceDeclaration', 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { '200': { '$ref': '#/components/responses/ConformanceDeclaration' }, '500': { '$ref': '#/components/responses/ServerError' } } } } oapi['paths']['/conformance'] = path path = { 'get': { 'tags': ['Capabilities'], 'summary': 'Collections page', 'description': 'Collections page', 'operationId': 'getCollections', 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { '200': { '$ref': '#/components/responses/Collections' }, '500': { '$ref': '#/components/responses/ServerError' } } } } oapi['paths']['/collections'] = path path = { 'get': { 'tags': ['Capabilities'], 'summary': 'Collection page', 'description': 'Collection page', 'operationId': 'getCollectionId', 'parameters': [ {'$ref': '#/components/parameters/collectionId'}, {'$ref': '#/components/parameters/f'} ], 'responses': { '200': { '$ref': '#/components/responses/Collection' }, '404': { '$ref': '#/components/responses/NotFound' }, '500': { '$ref': '#/components/responses/ServerError' } } } } oapi['paths']['/collections/{collectionId}'] = path path = { 'get': { 'tags': ['Queryables'], 'summary': 'Queryables page', 'description': 'Queryables page', 'operationId': 'getQueryables', 'parameters': [ {'$ref': '#/components/parameters/f'} ], 'responses': { '200': { '$ref': '#/components/responses/Queryables' }, '500': { '$ref': '#/components/responses/ServerError' } } } } oapi['paths']['/queryables'] = path path2 = deepcopy(path) path2['get']['operationId'] = 'getCollectionQueryables' path2['get']['parameters'].append( {'$ref': '#/components/parameters/collectionId'}) path2['get']['responses']['404'] = { '$ref': '#/components/responses/NotFound' } oapi['paths']['/collections/{collectionId}/queryables'] = path2 oapi['components']['parameters']['collectionId']['default'] = 'metadata:main' # noqa path = { 'get': { 'tags': ['Federated catalogs'], 'summary': 'Federated catalogs page', 'description': 'Federated catalogs page', 'operationId': 'getFederatedCatalogs', 'parameters': [ {'$ref': '#/components/parameters/collectionId'}, {'$ref': '#/components/parameters/f'} ], 'responses': { '200': { '$ref': '#/components/responses/FederatedCatalogs' }, '500': { '$ref': '#/components/responses/ServerError' } } } } oapi['paths']['/collections/{collectionId}/federatedCatalogs'] = path path = { 'get': { 'tags': ['Federated catalogs'], 'summary': 'Federated catalogs page', 'description': 'Federated catalogs page', 'operationId': 'getFederatedCatalog', 'parameters': [ {'$ref': '#/components/parameters/collectionId'}, {'name': 'catalogId', 'in': 'path', 'description': 'catalog ID', 'required': True, 'schema': { 'type': 'string' } }, {'$ref': '#/components/parameters/f'} ], 'responses': { '200': { '$ref': '#/components/responses/FederatedCatalog' }, '500': { '$ref': '#/components/responses/ServerError' } } } } oapi['paths']['/collections/{collectionId}/federatedCatalogs/{catalogId}'] = path path = { 'get': { 'tags': ['metadata'], 'summary': 'Records search items page', 'description': 'Records search items page', 'operationId': 'getRecords', 'parameters': [ {'$ref': '#/components/parameters/collectionId'}, {'$ref': '#/components/parameters/bbox'}, {'$ref': '#/components/parameters/ids'}, {'$ref': '#/components/parameters/datetime'}, {'$ref': '#/components/parameters/limit'}, {'$ref': '#/components/parameters/q'}, {'$ref': '#/components/parameters/type'}, {'$ref': '#/components/parameters/externalId'}, {'$ref': '#/components/parameters/sortby'}, {'$ref': '#/components/parameters/filter'}, {'$ref': '#/components/parameters/filter-lang'}, {'$ref': '#/components/parameters/f'}, {'$ref': '#/components/parameters/offset'}, {'$ref': '#/components/parameters/facets'}, {'$ref': '#/components/parameters/distributedSearch'}, {'$ref': '#/components/parameters/vendorSpecificParameters'} ], 'responses': { '200': { '$ref': '#/components/responses/Records' }, '400': { '$ref': '#/components/responses/InvalidParameter' }, '404': { '$ref': '#/components/responses/NotFound' }, '500': { '$ref': '#/components/responses/ServerError' } } } } if str2bool(config['manager'].get('transactions', False)): LOGGER.debug('Transactions enabled; adding post') path['post'] = { 'summary': 'Adds Records items', 'description': 'Adds Records items', 'tags': ['metadata'], 'operationId': 'addRecord', 'consumes': [ 'application/geo+json', 'application/json', 'application/xml' ], 'produces': ['application/geo+json'], 'requestBody': { 'content': { 'application/geo+json': { 'schema': {} } } }, 'parameters': [ {'$ref': '#/components/parameters/collectionId'} ], 'responses': { '201': {'description': 'Successful creation'}, '400': { '$ref': '#/components/responses/InvalidParameter' }, '500': { '$ref': '#/components/responses/ServerError' } } } oapi['paths']['/collections/{collectionId}/items'] = path if mode == 'stac-api': LOGGER.debug('Adding /stac/search') path2 = deepcopy(path) path2['get']['operationId'] = 'searchRecords' oapi['paths']['/search'] = path2 oapi['paths']['/search']['get']['parameters'].append({ '$ref': '#/components/parameters/collections' }) f = deepcopy(oapi['components']['parameters']['f']) f['schema']['enum'].append('xml') path = { 'get': { 'tags': ['metadata'], 'summary': 'Records item page', 'description': 'Records item page', 'operationId': 'getRecord', 'parameters': [ {'$ref': '#/components/parameters/collectionId'}, {'$ref': '#/components/parameters/recordId'}, {'$ref': '#/components/parameters/distributedSearch'}, f ], 'responses': { '200': { '$ref': '#/components/responses/Record' }, '404': { '$ref': '#/components/responses/NotFound' }, '500': { '$ref': '#/components/responses/ServerError' } } } } if str2bool(config['manager'].get('transactions', False)): LOGGER.debug('Transactions enabled; adding put/delete') path['put'] = { 'summary': 'Updates Records items', 'description': 'Updates Records items', 'tags': ['metadata'], 'operationId': 'updateRecord', 'consumes': [ 'application/geo+json', 'application/json', 'application/xml' ], 'produces': ['application/json'], 'requestBody': { 'content': { 'application/geo+json': { 'schema': {} } } }, 'parameters': [ {'$ref': '#/components/parameters/collectionId'}, {'$ref': '#/components/parameters/recordId'} ], 'responses': { '204': {'description': 'Successful update'}, '400': { '$ref': '#/components/responses/InvalidParameter' }, '500': { '$ref': '#/components/responses/ServerError' } } } path['delete'] = { 'summary': 'Deletes Records items', 'description': 'Deletes Records items', 'tags': ['metadata'], 'operationId': 'deleteRecord', 'produces': ['application/json'], 'parameters': [ {'$ref': '#/components/parameters/collectionId'}, {'$ref': '#/components/parameters/recordId'}, ], 'responses': { '204': {'description': 'Successful delete'}, '400': { '$ref': '#/components/responses/InvalidParameter' }, '500': { '$ref': '#/components/responses/ServerError' } } } oapi['paths']['/collections/{collectionId}/items/{recordId}'] = path return oapi ================================================ FILE: pycsw/ogc/api/records.py ================================================ # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2021 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from datetime import datetime, UTC import json import logging from operator import itemgetter import os from typing import List, Union from urllib.parse import urlencode, quote from owslib.ogcapi.records import Records from pygeofilter.parsers.ecql import parse as parse_ecql from pygeofilter.parsers.cql2_json import parse as parse_cql2_json from pycsw import __version__ from pycsw.broker import load_client from pycsw.core import log from pycsw.core.config import StaticContext from pycsw.core.metadata import parse_record from pycsw.core.pygeofilter_evaluate import to_filter from pycsw.core.util import bind_url, get_today_and_now, jsonify_links, load_custom_repo_mappings, str2bool, wkt2geom from pycsw.ogc.api.oapi import gen_oapi from pycsw.ogc.api.util import match_env_var, render_j2_template, to_json, to_rfc3339 from pycsw.ogc.pubsub import publish_message LOGGER = logging.getLogger(__name__) #: Return headers for requests (e.g:X-Powered-By) HEADERS = { 'Content-Type': 'application/json', 'X-Powered-By': f'pycsw {__version__}' } THISDIR = os.path.dirname(os.path.realpath(__file__)) CONFORMANCE_CLASSES = [ 'http://www.opengis.net/spec/ogcapi-common-1/1.0/conf/core', 'http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/collections', 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core', 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables', 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables-query-parameters', # noqa 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/filter', 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/features-filter', 'http://www.opengis.net/spec/ogcapi-features-4/1.0/conf/create-replace-delete', # noqa 'http://www.opengis.net/spec/ogcapi-records-1/1.0/conf/core', 'http://www.opengis.net/spec/ogcapi-records-1/1.0/conf/sorting', 'http://www.opengis.net/spec/ogcapi-records-1/1.0/conf/json', 'http://www.opengis.net/spec/ogcapi-records-1/1.0/conf/html', 'http://www.opengis.net/spec/cql2/1.0/conf/cql2-json', 'http://www.opengis.net/spec/cql2/1.0/conf/cql2-text' ] class API: """API object""" def __init__(self, config: dict): """ constructor :param config: pycsw configuration dict :returns: `pycsw.ogc.api.API` instance """ self.mode = 'ogcapi-records' self.config = config self.pubsub_client = None log.setup_logger(self.config.get('logging', {})) if self.config['server']['url'].startswith('${'): LOGGER.debug(f"Server URL is an environment variable: {self.config['server']['url']}") url_ = match_env_var(self.config['server']['url']) else: url_ = self.config['server']['url'] LOGGER.debug(f'Server URL: {url_}') self.config['server']['url'] = url_.rstrip('/') self.facets = self.config['repository'].get('facets', ['type']) self.context = StaticContext() LOGGER.debug('Setting limit') try: self.limit = int(self.config['server']['maxrecords']) except KeyError: self.limit = 10 LOGGER.debug(f'limit: {self.limit}') repo_filter = self.config['repository'].get('filter') custom_mappings_path = self.config['repository'].get('mappings') if custom_mappings_path is not None: md_core_model = load_custom_repo_mappings(custom_mappings_path) if md_core_model is not None: self.context.md_core_model = md_core_model else: LOGGER.exception( 'Could not load custom mappings: %s', custom_mappings_path) self.orm = 'sqlalchemy' from pycsw.core import repository try: LOGGER.info('Loading default repository') self.repository = repository.Repository( self.config['repository']['database'], self.context, table=self.config['repository']['table'], repo_filter=repo_filter, stable_sort=self.config['repository'].get('stable_sort', False) ) LOGGER.debug(f'Repository loaded {self.repository.dbtype}') except Exception as err: msg = f'Could not load repository {err}' LOGGER.exception(msg) raise if self.config.get('pubsub') is not None: LOGGER.debug('Loading PubSub client') self.pubsub_client = load_client(self.config['pubsub']['broker']) def get_content_type(self, headers, args): """ Decipher content type requested :param headers: `dict` of HTTP request headers :param args: `dict` of query arguments :returns: `str` of response content type """ content_type = 'application/json' format_ = args.get('f') if headers and 'Accept' in headers: if 'text/html' in headers['Accept']: content_type = 'text/html' elif 'application/xml' in headers['Accept']: content_type = 'application/xml' if format_ is not None: if format_ == 'json': content_type = 'application/json' elif format_ == 'xml': content_type = 'application/xml' elif format_ == 'html': content_type = 'text/html' return content_type def get_response(self, status, headers, data, template=None): """ Provide response :param status: `int` of HTTP status :param headers: `dict` of HTTP request headers :param data: `dict` of response data :param template: template filename (default is `None`) :returns: tuple of headers, status code, content """ if headers.get('Content-Type') == 'text/html' and template is not None: content = render_j2_template(self.config, template, data) else: pretty_print = str2bool(self.config['server'].get('pretty_print', False)) content = to_json(data, pretty_print) headers['Content-Length'] = len(content.encode('utf-8')) return headers, status, content def landing_page(self, headers_, args): """ Provide API landing page :param headers_: copy of HEADERS object :param args: request parameters :returns: tuple of headers, status code, content """ headers_['Content-Type'] = self.get_content_type(headers_, args) response = { 'id': 'pycsw-catalogue', 'links': [], 'title': self.config['metadata']['identification']['title'], 'description': self.config['metadata']['identification']['description'], 'keywords': self.config['metadata']['identification']['keywords'] } LOGGER.debug('Creating links') response['links'] = [{ 'rel': 'self', 'type': 'application/json', 'title': 'This document as JSON', 'href': f"{self.config['server']['url']}?f=json", 'hreflang': self.config['server']['language'] }, { 'rel': 'conformance', 'type': 'application/json', 'title': 'Conformance as JSON', 'href': f"{self.config['server']['url']}/conformance?f=json" }, { 'rel': 'service-doc', 'type': 'text/html', 'title': 'The OpenAPI definition as HTML', 'href': f"{self.config['server']['url']}/openapi?f=html" }, { 'rel': 'service-desc', 'type': 'application/vnd.oai.openapi+json;version=3.0', 'title': 'The OpenAPI definition as JSON', 'href': f"{self.config['server']['url']}/openapi?f=json" }, { 'rel': 'data', 'type': 'application/json', 'title': 'Collections as JSON', 'href': f"{self.config['server']['url']}/collections?f=json" }, { 'rel': 'search', 'type': 'application/json', 'title': 'Search collections', 'href': f"{self.config['server']['url']}/search" }, { 'rel': 'child', 'type': 'application/json', 'title': 'Main metadata collection', 'href': f"{self.config['server']['url']}/collections/metadata:main?f=json" }, { 'rel': 'service', 'type': 'application/xml', 'title': 'CSW 3.0.0 endpoint', 'href': f"{self.config['server']['url']}/csw" }, { 'rel': 'service', 'type': 'application/xml', 'title': 'CSW 2.0.2 endpoint', 'href': f"{self.config['server']['url']}/csw?service=CSW&version=2.0.2&request=GetCapabilities" }, { 'rel': 'service', 'type': 'application/xml', 'title': 'OpenSearch endpoint', 'href': f"{self.config['server']['url']}/opensearch" }, { 'rel': 'service', 'type': 'application/xml', 'title': 'OAI-PMH endpoint', 'href': f"{self.config['server']['url']}/oaipmh" }, { 'rel': 'service', 'type': 'application/xml', 'title': 'SRU endpoint', 'href': f"{self.config['server']['url']}/sru" }, { 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables', 'type': 'application/schema+json', 'title': 'Queryables', 'href': f"{self.config['server']['url']}/queryables" }, { 'rel': 'child', 'type': 'application/json', 'title': 'Main collection', 'href': f"{self.config['server']['url']}/collections/metadata:main" }, { 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/ogc-catalog', 'type': 'application/json', 'title': 'Record catalogue collection', 'href': f"{self.config['server']['url']}/collections/metadata:main" } ] if self.pubsub_client is not None and self.pubsub_client.show_link: LOGGER.debug('Adding PubSub broker link') pubsub_link = { 'rel': 'hub', 'type': 'application/json', 'title': 'Pub/Sub broker', 'href': self.pubsub_client.broker_safe_url } response['links'].append(pubsub_link) return self.get_response(200, headers_, response, 'landing_page.html') def openapi(self, headers_, args): """ Provide OpenAPI document / Swagger :param headers_: copy of HEADERS object :param args: request parameters :returns: tuple of headers, status code, content """ headers_['Content-Type'] = self.get_content_type(headers_, args) if headers_['Content-Type'] == 'application/json': headers_['Content-Type'] = 'application/vnd.oai.openapi+json;version=3.0' filepath = f"{THISDIR}/../../core/schemas/ogc/ogcapi/records/part1/1.0/ogcapi-records-1.yaml" response = gen_oapi(self.config, filepath) return self.get_response(200, headers_, response, 'openapi.html') def conformance(self, headers_, args): """ Provide API conformance :param headers_: copy of HEADERS object :param args: request parameters :returns: tuple of headers, status code, content """ headers_['Content-Type'] = self.get_content_type(headers_, args) response = { 'conformsTo': CONFORMANCE_CLASSES } if self.pubsub_client is not None: LOGGER.debug('Adding conformance classes for OGC API - Publish-Subscribe') # noqa pubsub_conformance_classes = [ 'https://www.opengis.net/spec/ogcapi-pubsub-1/1.0/conf/message-payload-cloudevents-json', # noqa 'https://www.opengis.net/spec/ogcapi-pubsub-1/1.0/conf/discovery' # noqa ] response['conformsTo'] += pubsub_conformance_classes return self.get_response(200, headers_, response, 'conformance.html') def collections(self, headers_, args): """ Provide API collections :param headers_: copy of HEADERS object :param args: request parameters :returns: tuple of headers, status code, content """ headers_['Content-Type'] = self.get_content_type(headers_, args) collections = [] LOGGER.debug('Generating default metadata:main collection') collection_info = self.get_collection_info() collections.append(collection_info) LOGGER.debug('Generating virtual collections') limit = int(args.get('limit', self.config['server'].get('maxrecords', 10))) virtual_collections = self.repository.query_collections(limit=limit) for virtual_collection in virtual_collections: virtual_collection_info = self.get_collection_info( virtual_collection.identifier, dict(title=virtual_collection.title, description=virtual_collection.abstract)) collections.append(virtual_collection_info) response = { 'collections': collections } url_base = f"{self.config['server']['url']}/collections" is_html = headers_['Content-Type'] == 'text/html' response['links'] = [{ 'rel': 'self' if not is_html else 'alternate', 'type': 'application/json', 'title': 'This document as JSON', 'href': f"{url_base}?f=json", 'hreflang': self.config['server']['language'] }, { 'rel': 'self' if is_html else 'alternate', 'type': 'text/html', 'title': 'This document as HTML', 'href': f"{url_base}?f=html", 'hreflang': self.config['server']['language'] }] return self.get_response(200, headers_, response, 'collections.html') def collection(self, headers_, args, collection='metadata:main'): """ Provide API collections :param headers_: copy of HEADERS object :param args: request parameters :param collection: collection name :returns: tuple of headers, status code, content """ headers_['Content-Type'] = self.get_content_type(headers_, args) LOGGER.debug(f'Generating {collection} collection') if collection == 'metadata:main': collection_info = self.get_collection_info() else: virtual_collection = self.repository.query_ids([collection])[0] collection_info = self.get_collection_info( virtual_collection.identifier, dict(title=virtual_collection.title, description=virtual_collection.abstract)) response = collection_info url_base = f"{self.config['server']['url']}/collections/{collection}" is_html = headers_['Content-Type'] == 'text/html' response['links'] = [{ 'rel': 'self' if not is_html else 'alternate', 'type': 'application/json', 'title': 'This document as JSON', 'href': f"{url_base}?f=json", 'hreflang': self.config['server']['language'] }, { 'rel': 'self' if is_html else 'alternate', 'type': 'text/html', 'title': 'This document as HTML', 'href': f"{url_base}?f=html", 'hreflang': self.config['server']['language'] }, { 'rel': 'items', 'type': 'application/geo+json', 'title': 'items as GeoJSON', 'href': f"{url_base}/items?f=json", 'hreflang': self.config['server']['language'] }, { 'rel': 'items', 'type': 'text/html', 'title': 'items as HTML', 'href': f"{url_base}/items?f=html", 'hreflang': self.config['server']['language'] }, { 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables', 'type': 'application/schema+json', 'title': 'Queryables as JSON', 'href': f"{url_base}/queryables?f=json", 'hreflang': self.config['server']['language'] }, { 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables', 'type': 'text/html', 'title': 'Queryables as HTML', 'href': f"{url_base}/queryables?f=html", 'hreflang': self.config['server']['language'] }] if collection == 'metadata:main' and 'federatedcatalogues' in self.config: LOGGER.debug('Adding federated catalogues') response['links'].append({ 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/federatedCatalogues', 'type': 'application/json', 'title': 'Federated catalogs as JSON', 'href': f"{url_base}/federatedCatalogs?f=json", 'hreflang': self.config['server']['language'] }) response['links'].append({ 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/federatedCatalogues', 'type': 'text/html', 'title': 'Federated catalogs as HTML', 'href': f"{url_base}/federatedCatalogs?f=html", 'hreflang': self.config['server']['language'] }) return self.get_response(200, headers_, response, 'collection.html') def queryables(self, headers_, args, collection='metadata:main'): """ Provide collection queryables :param headers_: copy of HEADERS object :param args: request parameters :param collection: name of collection :returns: tuple of headers, status code, content """ headers_['Content-Type'] = self.get_content_type(headers_, args) if 'json' in headers_['Content-Type']: headers_['Content-Type'] = 'application/schema+json' if collection not in self.get_all_collections(): msg = 'Invalid collection' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) properties = self.repository.describe() properties2 = {} for key, value in properties.items(): if key in self.repository.query_mappings or key == 'geometry': properties2[key] = value if collection == 'metadata:main': title = self.config['metadata']['identification']['title'] else: title = self.config['metadata']['identification']['title'] virtual_collection = self.repository.query_ids([collection])[0] title = virtual_collection.title response = { 'id': collection, 'type': 'object', 'title': title, 'properties': properties2, '$schema': 'http://json-schema.org/draft/2019-09/schema', '$id': f"{self.config['server']['url']}/collections/{collection}/queryables" } return self.get_response(200, headers_, response, 'queryables.html') def items(self, headers_, json_post_data, args, collection='metadata:main'): """ Provide collection items :param headers_: copy of HEADERS object :param args: request parameters :param collection: collection name :returns: tuple of headers, status code, content """ LOGGER.debug(f'Request args: {args.keys()}') LOGGER.debug('converting request argument names to lower case') args = {k.lower(): v for k, v in args.items()} LOGGER.debug(f'Request args (lower case): {args.keys()}') headers_['Content-Type'] = self.get_content_type(headers_, args) reserved_query_params = [ 'distributedsearch', 'f', 'facets', 'filter', 'filter-lang', 'limit', 'sortby', 'offset' ] filter_langs = [ 'cql2-json', 'cql2-text' ] response = { 'type': 'FeatureCollection', 'facets': [], 'features': [], 'links': [] } cql_query = None query_parser = None sortby = None limit = None ids = [] bbox = [] facets_requested = False collections = [] cql_ops_list = [] if collection not in self.get_all_collections(): msg = 'Invalid collection' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) if json_post_data is not None: LOGGER.debug(f'JSON POST data: {json_post_data}') LOGGER.debug('Transforming JSON POST data into request args') for p in ['limit', 'bbox', 'datetime', 'collections']: if p in json_post_data: if p in ['bbox', 'collections']: args[p] = ','.join(map(str, json_post_data.get(p))) else: args[p] = json_post_data.get(p) if 'sortby' in json_post_data: LOGGER.debug('Detected sortby') args['sortby'] = json_post_data['sortby'] LOGGER.debug(f'Transformed args: {args}') if args.get('filter', {}): LOGGER.debug(f'CQL query specified {args["filter"]}') cql_query = args['filter'] filter_lang = args.get('filter-lang') if filter_lang is not None and filter_lang not in filter_langs: msg = f'Invalid filter-lang, available: {", ".join(filter_langs)}' LOGGER.exception(f'{msg} Used: {filter_lang}') return self.get_exception(400, headers_, 'InvalidParameterValue', msg) LOGGER.debug('Transforming property filters into CQL') query_args = [] for k, v in args.items(): if k in reserved_query_params: continue if k not in reserved_query_params: if k == 'ids': ids = ','.join(f'"{x}"' for x in v.split(',')) query_args.append(f"identifier IN ({ids})") elif k == 'collections': if isinstance(v, str): collections = ','.join(f'"{x}"' for x in v.split(',')) else: collections = ','.join(f'"{x}"' for x in v) query_args.append(f"parentidentifier IN ({collections})") elif k == 'anytext': query_args.append(build_anytext(k, v)) elif k == 'bbox': query_args.append(f'BBOX(geometry, {v})') elif k == 'keywords': query_args.append(f"keywords ILIKE '%{v}%'") elif k == 'datetime': if '/' not in v: query_args.append(f'date = "{v}"') else: begin, end = v.split('/') if begin != '..': query_args.append(f'time_begin >= "{begin}"') if end != '..': query_args.append(f'time_end <= "{end}"') elif k == 'q': if v not in [None, '']: query_args.append(build_anytext('anytext', v)) else: query_args.append(f'{k} = "{v}"') facets_requested = str2bool(args.get('facets', False)) if collection != 'metadata:main': LOGGER.debug('Adding virtual collection filter') query_args.append(f'parentidentifier = "{collection}"') LOGGER.debug('Evaluating CQL and other specified filtering parameters') if cql_query is not None and query_args: LOGGER.debug('Combining CQL and other specified filtering parameters') cql_query += ' AND ' + ' AND '.join(query_args) elif cql_query is not None and not query_args: LOGGER.debug('Just CQL detected') elif cql_query is None and query_args: LOGGER.debug('Just other specified filtering parameters detected') cql_query = ' AND '.join(query_args) LOGGER.debug(f'CQL query: {cql_query}') if cql_query is not None: LOGGER.debug('Detected CQL text') query_parser = parse_ecql elif json_post_data is not None: if 'limit' in json_post_data: limit = json_post_data.pop('limit') if 'sortby' in json_post_data: sortby = json_post_data.pop('sortby') if 'collections' in json_post_data: collections = json_post_data.pop('collections') if 'bbox' in json_post_data: bbox = json_post_data.pop('bbox') if 'ids' in json_post_data: ids = json_post_data.pop('ids') if not json_post_data: LOGGER.debug('No CQL specified, only query parameters') json_post_data = {} if not json_post_data and collections and collections != ['metadata:main']: cql_ops_list.append({'op': 'eq', 'args': [{'property': 'parentidentifier'}, collections[0]]}) if bbox: cql_ops_list.append({ 'op': 's_intersects', 'args': [ {'property': 'geometry'}, {'bbox': [bbox]} ]} ) if ids: cql_ops_list.append({ 'op': 'in', 'args': [{'property': 'identifier'}, ids] }) if len(cql_ops_list) > 1: json_post_data = { 'op': 'and', 'args': cql_ops_list } elif len(cql_ops_list) == 1: json_post_data = cql_ops_list[0] cql_query = json_post_data LOGGER.debug('Detected CQL JSON; ignoring all other query predicates') query_parser = parse_cql2_json LOGGER.debug(f'query parser: {query_parser}') if query_parser is not None and cql_query != {}: LOGGER.debug('Parsing CQL into AST') LOGGER.debug(json_post_data) LOGGER.debug(cql_query) try: ast = query_parser(cql_query) LOGGER.debug(f'Abstract syntax tree: {ast}') except Exception as err: msg = f'CQL parsing error: {str(err)}' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) LOGGER.debug('Transforming AST into filters') try: filters = to_filter(ast, self.repository.dbtype, self.repository.query_mappings) LOGGER.debug(f'Filter: {filters}') except Exception as err: msg = f'CQL evaluator error: {str(err)}' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) query = self.repository.session.query(self.repository.dataset).filter(filters) if facets_requested: LOGGER.debug('Running facet query') facets_results = self.get_facets(filters) else: query = self.repository.session.query(self.repository.dataset) facets_results = self.get_facets() if facets_requested: response['facets'] = facets_results else: response.pop('facets') if 'sortby' in args: LOGGER.debug('sortby specified') sortby = args['sortby'] if sortby is not None: sortbys = sortby_to_order_by(sortby, self.repository.query_mappings) query = query.order_by(*sortbys) if self.repository.stable_sort: LOGGER.debug('Adding additional stable sort on identifier') query = query.order_by(self.repository.query_mappings['identifier'].asc()) if limit is None and 'limit' in args: limit = int(args['limit']) LOGGER.debug('limit specified') if limit < 1: msg = 'Limit must be a positive integer' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) if limit > self.limit: limit = self.limit elif limit is not None: pass else: limit = self.limit offset = int(args.get('offset', 0)) LOGGER.debug(f'Query: {query}') LOGGER.debug('Querying repository') count = query.count() LOGGER.debug(f'count: {count}') LOGGER.debug(f'limit: {limit}') LOGGER.debug(f'offset: {offset}') records = query.limit(limit).offset(offset).all() returned = len(records) response['numberMatched'] = count response['numberReturned'] = returned for record in records: response['features'].append(record2json(record, self.config['server']['url'], collection, self.mode)) response['federatedSearchResults'] = {} distributed = str2bool(args.get('distributedsearch', False)) if distributed: for fc in self.config.get('federatedcatalogues', []): if fc['type'] != 'OARec': LOGGER.debug(f"Federated catalogue type {fc['type']} not supported; skipping") continue LOGGER.debug(f"Running distributed search against {fc['url']}") fc_url, _, fc_collection = fc['url'].rsplit('/', 2) response['federatedSearchResults'][fc['id']] = { 'type': 'FeatureCollection', 'features': [] } try: w = Records(fc_url) args.pop('distributedsearch') fc_results = w.collection_items(fc_collection, **args) for feature in fc_results['features']: response['federatedSearchResults'][fc['id']]['features'].append(feature) except Exception as err: LOGGER.warning(err) LOGGER.debug('Creating links') link_args = {**args} link_args.pop('f', None) fragment = f'collections/{collection}/items' if link_args: url_base = f"{self.config['server']['url']}/{fragment}?{urlencode(link_args)}" else: url_base = f"{self.config['server']['url']}/{fragment}" is_html = headers_['Content-Type'] == 'text/html' response['links'].extend([{ 'rel': 'self' if not is_html else 'alternate', 'type': 'application/geo+json', 'title': 'This document as GeoJSON', 'href': f"{bind_url(url_base)}f=json", 'hreflang': self.config['server']['language'] }, { 'rel': 'self' if is_html else 'alternate', 'type': 'text/html', 'title': 'This document as HTML', 'href': f"{bind_url(url_base)}f=html", 'hreflang': self.config['server']['language'] }, { 'rel': 'collection', 'type': 'application/json', 'title': 'Collection URL', 'href': f"{self.config['server']['url']}/collections/{collection}", 'hreflang': self.config['server']['language'] }]) if count > 0: if offset > 0: link_args.pop('offset', None) prev = max(0, offset - limit) url_ = f"{self.config['server']['url']}/{fragment}?{urlencode(link_args)}" response['links'].append( { 'type': 'application/geo+json', 'rel': 'prev', 'title': 'items (prev)', 'href': f'{bind_url(url_)}offset={prev}', 'hreflang': self.config['server']['language'] }) else: link_args.pop('offset', None) url_ = f"{self.config['server']['url']}/{fragment}?{urlencode(link_args)}" response['links'].append( { 'type': 'application/geo+json', 'rel': 'first', 'title': 'items (first)', 'href': f'{bind_url(url_)}', 'hreflang': self.config['server']['language'] }) if (offset + returned) < count: link_args.pop('offset', None) next_ = offset + returned url_ = f"{self.config['server']['url']}/{fragment}?{urlencode(link_args)}" response['links'].append({ 'rel': 'next', 'type': 'application/geo+json', 'title': 'items (next)', 'href': f"{bind_url(url_)}offset={next_}", 'hreflang': self.config['server']['language'] }) elif (offset + returned) >= count: link_args.pop('offset', None) last = offset + returned url_ = f"{self.config['server']['url']}/{fragment}?{urlencode(link_args)}" response['links'].append({ 'rel': 'last', 'type': 'application/geo+json', 'title': 'items (last)', 'href': f"{bind_url(url_)}offset={last}", 'hreflang': self.config['server']['language'] }) response['timeStamp'] = datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%S.%fZ') if headers_['Content-Type'] == 'text/html': response['title'] = self.config['metadata']['identification']['title'] response['collection'] = collection template = 'items.html' return self.get_response(200, headers_, response, template) def item(self, headers_, args, collection, item): """ Provide collection item :param headers_: copy of HEADERS object :param args: request parameters :param collection: name of collection :param item: record identifier :returns: tuple of headers, status code, content """ record = None headers_['Content-Type'] = self.get_content_type(headers_, args) if collection not in self.get_all_collections(): msg = 'Invalid collection' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) LOGGER.debug(f'Querying repository for item {item}') try: record = self.repository.query_ids([item])[0] response = record2json(record, self.config['server']['url'], collection, self.mode) except IndexError: distributed = str2bool(args.get('distributed', False)) if distributed: for fc in self.config.get('federatedcatalogues', []): if fc['type'] != 'OARec': LOGGER.debug(f"Federated catalogue type {fc['type']} not supported; skipping") continue LOGGER.debug(f"Running distributed item search against {fc['url']}") fc_url, _, fc_collection = fc.rsplit('/', 2) try: w = Records(fc_url) response = record = w.collection_item(fc_collection, item) LOGGER.debug(f'Found item from {fc}') break except RuntimeError: continue if record is None: return self.get_exception( 404, headers_, 'InvalidParameterValue', 'item not found') if headers_['Content-Type'] == 'application/xml': return headers_, 200, record.xml if headers_['Content-Type'] == 'text/html': response['title'] = self.config['metadata']['identification']['title'] response['collection'] = collection if 'json' in headers_['Content-Type']: headers_['Content-Type'] = 'application/geo+json' return self.get_response(200, headers_, response, 'item.html') def manage_collection_item(self, headers_, action='create', collection=None, item=None, data=None): """ :param action: action (create, update, delete) :param collection: collection identifier :param item: record identifier :param data: raw data / payload :returns: tuple of headers, status code, content """ if not str2bool(self.config['manager'].get('transactions', False)): return self.get_exception( 405, headers_, 'InvalidParameterValue', 'transactions not allowed') if action in ['create', 'update'] and data is None: msg = 'No data found' LOGGER.error(msg) return self.get_exception( 400, headers_, 'InvalidParameterValue', msg) if action in ['create', 'update']: try: record = parse_record(self.context, data, self.repository)[0] except Exception as err: msg = f'Failed to parse data: {err}' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) if not hasattr(record, 'identifier'): msg = 'Record requires an identifier' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) if action == 'create': LOGGER.debug('Creating new record') LOGGER.debug(f'Querying repository for item {item}') try: _ = self.repository.query_ids([record.identifier])[0] return self.get_exception( 400, headers_, 'InvalidParameterValue', 'item exists') except Exception: LOGGER.debug('Identifier does not exist') # insert new record try: self.repository.insert(record, 'local', get_today_and_now()) except Exception as err: msg = 'Record creation failed' LOGGER.exception(f'{msg}: {err}') return self.get_exception(400, headers_, 'InvalidParameterValue', msg) code = 201 response = {} elif action == 'update': LOGGER.debug(f'Querying repository for item {item}') try: _ = self.repository.query_ids([record.identifier])[0] except Exception: msg = 'Identifier does not exist' LOGGER.debug(msg) return self.get_exception(404, headers_, 'InvalidParameterValue', msg) _ = self.repository.update(record) code = 204 response = {} elif action == 'delete': constraint = { 'where': 'identifier = \'%s\'' % item, 'values': [item] } _ = self.repository.delete(constraint) code = 200 response = {} if self.pubsub_client is not None: LOGGER.debug('Publishing message') publish_message(self.pubsub_client, self.config['server']['url'], action, collection, item, data) return self.get_response(code, headers_, response) def get_exception(self, status, headers, code, description): """ Provide exception report :param status: `int` of HTTP status code :param headers_: copy of HEADERS object :param code: exception code :param description: exception description :returns: tuple of headers, status code, content """ exception = { 'code': code, 'description': description } return self.get_response(status, headers, exception, 'exception.html') def get_collection_info(self, collection_name: str = 'metadata:main', collection_info: dict = {}) -> dict: """ Generate collection metadata :param collection_name: name of collection default is 'metadata:main' main collection :param collection_info: `dict` of collecton info :returns: `dict` of collection """ if collection_name == 'metadata:main': id_ = collection_name title = self.config['metadata']['identification']['title'] description = self.config['metadata']['identification']['description'] else: id_ = collection_name title = collection_info.get('title') description = collection_info.get('description') collection_info = { 'id': id_, 'type': 'catalog', 'title': title, 'description': description, 'itemType': 'record', 'crs': 'http://www.opengis.net/def/crs/OGC/1.3/CRS84', 'links': [{ 'rel': 'collection', 'type': 'application/json', 'title': 'Collection URL', 'href': f"{self.config['server']['url']}/collections/{collection_name}", 'hreflang': self.config['server']['language'] }, { 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/ogc-catalog', 'type': 'application/json', 'title': 'Record catalog collection', 'href': f"{self.config['server']['url']}/collections/{collection_name}", 'hreflang': self.config['server']['language'] }, { 'rel': 'queryables', 'type': 'application/json', 'title': 'Collection queryables', 'href': f"{self.config['server']['url']}/collections/{collection_name}/queryables", 'hreflang': self.config['server']['language'] }, { 'rel': 'items', 'type': 'application/geo+json', 'title': 'Collection items as GeoJSON', 'href': f"{self.config['server']['url']}/collections/{collection_name}/items", 'hreflang': self.config['server']['language'] }] } return collection_info def federated_catalogues(self, headers_, args, collection): """ Provide federated catalogues :param headers_: copy of HEADERS object :param args: request parameters :param collection: name of collection :returns: tuple of headers, status code, content """ headers_['Content-Type'] = self.get_content_type(headers_, args) response = {} fedcats = [] if collection == 'metadata:main': for fedcat_ in self.config.get('federatedcatalogues', []): if fedcat_['type'] == 'OARec': fedcats.append(fedcat_) if headers_['Content-Type'] == 'text/html': response['title'] = self.config['metadata']['identification']['title'] response['collection'] = collection response['fedcats'] = fedcats else: response = fedcats template = 'federatedcatalogs.html' return self.get_response(200, headers_, response, template) def federated_catalogue(self, headers_, args, collection, catalogue): """ Provide federated catalogue :param headers_: copy of HEADERS object :param args: request parameters :param collection: name of collection :param catalogue: id of catalogue :returns: tuple of headers, status code, content """ headers_['Content-Type'] = self.get_content_type(headers_, args) response = {} fedcat = None if collection == 'metadata:main': fedcats = self.config.get('federatedcatalogues') for fedcat_ in fedcats: if fedcat_['id'] == catalogue and fedcat_['type'] == 'OARec': fedcat = fedcat_ break if fedcat is None: msg = 'Federated catalogue does not exist' LOGGER.exception(msg) return self.get_exception(404, headers_, 'InvalidParameterValue', msg) if headers_['Content-Type'] == 'text/html': response['title'] = self.config['metadata']['identification']['title'] response['collection'] = collection response['fedcat'] = fedcat else: response = fedcat template = 'federatedcatalog.html' return self.get_response(200, headers_, response, template) def get_all_collections(self) -> list: """ Get all collections :returns: `list` of collection identifiers """ default_collection = 'metadata:main' virtual_collections = self.repository.query_collections(limit=self.limit) return [default_collection] + [vc.identifier for vc in virtual_collections] def get_facets(self, filters=None) -> dict: """ Gets all facets for a given query :returns: `dict` of facets """ facets_results = {} for facet in self.facets: LOGGER.debug(f'Running facet for {facet}') facetq = self.repository.session.query(self.repository.query_mappings[facet], self.repository.func.count(facet)).group_by(facet) if filters is not None: facetq = facetq.filter(filters) LOGGER.debug('Writing facet query results') facets_results[facet] = { 'type': 'terms', 'property': facet, 'buckets': [] } for fq in facetq.all(): facets_results[facet]['buckets'].append({ 'value': fq[0], 'count': fq[1] }) facets_results[facet]['buckets'].sort(key=itemgetter('count'), reverse=True) return facets_results def record2json(record, url, collection, mode='ogcapi-records'): """ OGC API - Records record generator from core pycsw record model :param record: pycsw record object :param url: server URL :param collection: collection id :param mode: `str` of API mode :returns: `dict` of record GeoJSON """ if record.metadata_type in ['application/json', 'application/geo+json']: rec = json.loads(record.metadata) if rec.get('stac_version') is not None and rec['type'] == 'Feature' and mode == 'stac-api': collection_ = rec.get('collection', collection) LOGGER.debug('Returning native STAC representation') rec['links'].extend([{ 'rel': 'self', 'type': 'application/geo+json', 'href': f"{url}/collections/{collection_}/items/{rec['id']}" }, { 'rel': 'root', 'type': 'application/json', 'href': url }, { 'rel': 'parent', 'type': 'application/json', 'href': f"{url}/collections/{collection_}" }, { 'rel': 'collection', 'type': 'application/json', 'href': f"{url}/collections/{collection_}" } ]) return rec LOGGER.debug('Removing STAC version') _ = rec.pop('stac_version', None) _ = rec.pop('stac_extensions', None) LOGGER.debug('Transforming assets to enclosure links') assets = rec.pop('assets', {}) for key, value in assets.items(): value['rel'] = 'enclosure' value['name'] = key if 'links' not in rec: rec['links'] = [] rec['links'].append(value) return rec record_dict = { 'id': record.identifier, 'type': 'Feature', 'geometry': None, 'properties': {}, 'links': [] } # todo; for keywords with a scheme use the theme property if record.topicategory: tctheme = { 'concepts': [], 'scheme': 'https://standards.iso.org/iso/19139/resources/gmxCodelists.xml#MD_TopicCategoryCode' } if isinstance(record.topicategory, list): for rtp in record.topicategory: tctheme['concepts'].append({'id': rtp}) elif isinstance(record.topicategory, str): tctheme['concepts'].append({'id': record.topicategory}) record_dict['properties']['themes'] = [tctheme] if record.otherconstraints: if isinstance(record.otherconstraints, str) and record.otherconstraints not in [None, 'None']: record.otherconstraints = [record.otherconstraints] record_dict['properties']['license'] = ", ".join(record.otherconstraints) if record.conditionapplyingtoaccessanduse: if isinstance(record.conditionapplyingtoaccessanduse, str) and record.conditionapplyingtoaccessanduse not in [None, 'None']: record_dict['properties']['rights'] = record.conditionapplyingtoaccessanduse record_dict['properties']['updated'] = record.insert_date if record.type: record_dict['properties']['type'] = record.type if record.date_creation: record_dict['properties']['created'] = record.date_creation if record.date_modified: record_dict['properties']['updated'] = record.date_modified if record.language: record_dict['properties']['language'] = record.language if record.source: record_dict['properties']['externalIds'] = [{'value': record.source}] if record.title: record_dict['properties']['title'] = record.title if record.abstract: record_dict['properties']['description'] = record.abstract if record.format: record_dict['properties']['formats'] = [{'name': f} for f in record.format.split(',') if len(f) > 1] if record.keywords: record_dict['properties']['keywords'] = [x for x in record.keywords.split(',')] if record.contacts not in [None, '', 'null']: rcnt = [] roles = [] try: for cnt in json.loads(record.contacts): try: roles.append(cnt.get('role', '').lower()) rcnt.append({ 'name': cnt['name'], 'organization': cnt.get('organization', ''), 'position': cnt.get('position', ''), 'roles': [cnt.get('role', '')], 'phones': [{ 'value': cnt.get('phone', '') }], 'emails': [{ 'value': cnt.get('email', '') }], 'addresses': [{ 'deliveryPoint': [cnt.get('address', '')], 'city': cnt.get('city', ''), 'administrativeArea': cnt.get('region', ''), 'postalCode': cnt.get('postcode', ''), 'country': cnt.get('country', '') }], 'links': [{ 'href': cnt.get('onlineresource') }] }) except Exception as err: LOGGER.exception(f"failed to parse contact of {record.identifier}: {err}") for r2 in "creator,publisher,contributor".split(","): # match role-fields with contacts if r2 not in roles and hasattr(record, r2) and record[r2] not in [None, '']: rcnt.append({ 'organization': record[r2], 'roles': [r2] }) except Exception as err: LOGGER.warning(f"failed to parse contacts json of {record.identifier}: {err}") record_dict['properties']['contacts'] = rcnt if record.themes not in [None, '', 'null']: ogcapi_themes = record_dict['properties'].get('themes', []) # For a scheme, prefer uri over label # OWSlib currently uses .keywords_object for keywords with url, see https://github.com/geopython/OWSLib/pull/765 try: for theme in json.loads(record.themes): try: theme_ = { 'concepts': [{'id': c.get('name', '')} for c in theme.get('keywords', []) if 'name' in c and c['name'] not in [None, '']] } if 'thesaurus' in theme: theme_['scheme'] = theme['thesaurus'].get('url') or theme['thesaurus'].get('title') elif 'scheme' in theme: theme_['scheme'] = theme['scheme'] ogcapi_themes.append(theme_) except Exception as err: LOGGER.exception(f"failed to parse theme of {record.identifier}: {err}") except Exception as err: LOGGER.exception(f"failed to parse themes json of {record.identifier}: {err}") record_dict['properties']['themes'] = ogcapi_themes if record.links: rdl = record_dict['links'] for link in jsonify_links(record.links): if link['url'] in [None, 'None']: LOGGER.debug(f'Skipping null link: {link}') continue link2 = { 'href': link['url'] } if link.get('name') not in [None, 'None']: link2['name'] = link['name'] if link.get('description') not in [None, 'None']: link2['description'] = link['description'] if link.get('protocol') not in [None, 'None']: link2['protocol'] = link['protocol'] if link['protocol'] == 'WWW:LINK-1.0-http--image-thumbnail': link2['rel'] = 'preview' if 'rel' in link: link2['rel'] = link['rel'] elif 'function' in link: link2['rel'] = link['function'] rdl.append(link2) for lnk in [record.parentidentifier, record.relation]: if lnk and len(lnk.strip()) > 0: if not lnk.startswith('http'): lnk = f"{url}/collections/{collection}/items/{quote(lnk)}" record_dict['links'].append({ 'rel': 'related', 'href': lnk, 'name': 'related record', 'description': 'related record', 'type': 'application/json' }) record_dict['links'].append({ 'rel': 'self', 'type': 'application/geo+json', 'title': record.identifier, 'name': 'item', 'description': record.identifier, 'href': f'{url}/collections/{collection}/items/{record.identifier}' }) record_dict['links'].append({ 'rel': 'collection', 'type': 'application/json', 'title': 'Collection', 'name': 'collection', 'description': 'Collection', 'href': f'{url}/collections/{collection}' }) if record.wkt_geometry: minx, miny, maxx, maxy = wkt2geom(record.wkt_geometry) geometry = { 'type': 'Polygon', 'coordinates': [[ [minx, miny], [minx, maxy], [maxx, maxy], [maxx, miny], [minx, miny] ]] } record_dict['geometry'] = geometry record_dict['time'] = None if record.time_begin or record.time_end: LOGGER.debug('One of time_begin / time_end exists') if record.time_end not in [None, '']: if record.time_begin not in [None, '']: LOGGER.debug('Start and end defined') begin, _ = to_rfc3339(record.time_begin) end, _ = to_rfc3339(record.time_end) record_dict['time'] = { 'interval': [begin, end] } else: LOGGER.debug('End only defined') end, _ = to_rfc3339(record.time_end) record_dict['time'] = { 'interval': ['..', end] } else: LOGGER.debug('Start only defined') begin, _ = to_rfc3339(record.time_begin) record_dict['time'] = { 'interval': [begin, '..'] } if mode == 'stac-api': date_, date_type = to_rfc3339(record.date) record_dict['properties']['datetime'] = date_ if None not in [record.time_begin, record.time_end]: start_date, start_date_type = to_rfc3339(record.time_begin) end_date, end_date_type = to_rfc3339(record.time_end) record_dict['properties']['start_datetime'] = start_date record_dict['properties']['end_datetime'] = end_date return record_dict def build_anytext(name, value): """ deconstructs free-text search into CQL predicate(s) :param name: property name :param name: property value :returns: string of CQL predicate(s) """ LOGGER.debug(f'Name: {name}') LOGGER.debug(f'Value: {value}') predicates = [] tokens = value.split(',') if len(tokens) == 1 and ' ' not in value: # single term LOGGER.debug('Single term with no spaces') return f"{name} ILIKE '%{value}%'" for token in tokens: if ' ' in token: tokens2 = token.split() predicates2 = [] for token2 in tokens2: predicates2.append(f"{name} ILIKE '%{token2}%'") predicates.append('(' + ' AND '.join(predicates2) + ')') else: predicates.append(f"{name} ILIKE '%{token}%'") return f"({' OR '.join(predicates)})" def sortby_to_order_by(sortby: Union[str, List[dict]], mappings: dict) -> list: sortby_ = [] value_list = [] if isinstance(sortby, str): LOGGER.debug('Normalizing sortby into list of dicts') for s in sortby.split(','): s2 = s.lstrip('-') if s.startswith('-'): s2dir = 'desc' else: s2dir = 'asc' sortby_.append({ 'field': s2, 'direction': s2dir }) else: sortby_ = sortby for sb in sortby_: if sb['field'] not in list(mappings.keys()): msg = 'Invalid sortby property' LOGGER.exception(msg) raise ValueError(msg) if sb['direction'] == 'desc': value_list.append(mappings[sb['field']].desc()) else: value_list.append(mappings[sb['field']].asc()) return value_list ================================================ FILE: pycsw/ogc/api/util.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2025 Tom Kralidis # Copyright (c) 2021 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import base64 from datetime import date, datetime, time from decimal import Decimal import json import logging import mimetypes import os import pathlib import re from typing import Union from dateutil.parser import parse as dparse from jinja2 import Environment, FileSystemLoader from jinja2.exceptions import TemplateNotFound import yaml from pycsw import __version__ LOGGER = logging.getLogger(__name__) DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' TEMPLATES = pathlib.Path(__file__).resolve().parent.parent.parent / 'templates' STATIC = TEMPLATES / 'static' mimetypes.add_type('text/plain', '.yaml') mimetypes.add_type('text/plain', '.yml') def get_typed_value(value): """ Derive true type from data value :param value: value :returns: value as a native Python data type """ try: if '.' in value: # float? value2 = float(value) elif len(value) > 1 and value.startswith('0'): value2 = value else: # int? value2 = int(value) except ValueError: # string (default)? value2 = value return value2 def json_serial(obj): """ helper function to convert to JSON non-default types (source: https://stackoverflow.com/a/22238613) :param obj: `object` to be evaluated :returns: JSON non-default type to `str` """ if isinstance(obj, (datetime, date, time)): if isinstance(obj, (datetime, time)): return obj.strftime('%Y-%m-%dT%H:%M:%SZ') else: # date return obj.strftime('%Y-%m-%d') elif isinstance(obj, bytes): try: LOGGER.debug('Returning as UTF-8 decoded bytes') return obj.decode('utf-8') except UnicodeDecodeError: LOGGER.debug('Returning as base64 encoded JSON object') return base64.b64encode(obj) elif isinstance(obj, Decimal): return float(obj) msg = f'{obj} type {type(obj)} not serializable' LOGGER.error(msg) raise TypeError(msg) def match_env_var(value): path_matcher = re.compile(r'.*\$\{([^}^{]+)\}.*') env_var = path_matcher.match(value).group(1) if env_var not in os.environ: raise EnvironmentError('Undefined environment variable in config') return env_var def yaml_load(fh): """ serializes a YAML files into a pyyaml object :param fh: file handle :returns: `dict` representation of YAML """ # support environment variables in config # https://stackoverflow.com/a/55301129 path_matcher = re.compile(r'.*\$\{([^}^{]+)\}.*') def path_constructor(loader, node): env_var = path_matcher.match(node.value).group(1) if env_var not in os.environ: raise EnvironmentError('Undefined environment variable in config') return get_typed_value(os.path.expandvars(node.value)) class EnvVarLoader(yaml.SafeLoader): pass EnvVarLoader.add_implicit_resolver('!path', path_matcher, None) EnvVarLoader.add_constructor('!path', path_constructor) return yaml.load(fh, Loader=EnvVarLoader) def yaml_dump(dict_: dict, destfile: str) -> bool: """ Dump dict to YAML file :param dict_: `dict` to dump :param destfile: destination filepath :returns: `bool` """ def path_representer(dumper, data): return dumper.represent_scalar(u'tag:yaml.org,2002:str', str(data)) yaml.add_multi_representer(pathlib.PurePath, path_representer) LOGGER.debug('Dumping YAML document') with open(destfile, 'wb') as fh: yaml.dump(dict_, fh, sort_keys=False, encoding='utf8', indent=4, default_flow_style=False) return True def to_json(dict_, pretty=False): """ Serialize dict to json :param dict_: `dict` of JSON representation :param pretty: `bool` of whether to prettify JSON (default is `False`) :returns: JSON string representation """ if pretty: indent = 4 else: indent = None return json.dumps(dict_, default=json_serial, indent=indent) def render_j2_template(config, template, data): """ render Jinja2 template :param config: dict of configuration :param template: template (relative path) :param data: dict of data :returns: string of rendered template """ custom_templates = False try: templates_path = config['server']['templates']['path'] env = Environment(loader=FileSystemLoader(templates_path)) custom_templates = True LOGGER.debug(f'using custom templates: {templates_path}') except (KeyError, TypeError): env = Environment(loader=FileSystemLoader(TEMPLATES)) LOGGER.debug(f'using default templates: {TEMPLATES}') env.filters['to_json'] = to_json env.globals.update(to_json=to_json) try: template = env.get_template(template) except TemplateNotFound as err: if custom_templates: LOGGER.debug(err) LOGGER.debug('Custom template not found; using default') env = Environment(loader=FileSystemLoader(TEMPLATES)) template = env.get_template(template) else: raise return template.render(config=config, data=data, version=__version__) def to_rfc3339(value: str) -> Union[tuple, None]: """ Helper function to convert a date/datetime into RFC3339 :param value: `str` of date/datetime value :returns: `tuple` of `datetime` of RFC3339 value and date type """ try: dt = dparse(value) # TODO TIMEZONE) except Exception as err: msg = f'Parse error: {err}' LOGGER.error(msg) return 'date', None if len(value) < 11: dt_type = 'date' else: dt_type = 'date-time' return dt, dt_type ================================================ FILE: pycsw/ogc/csw/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/ogc/csw/cql.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2016 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from pycsw.core.etree import etree from pycsw.core import util from pycsw.ogc.fes.fes1 import MODEL as fes1_model from pycsw.ogc.fes.fes2 import MODEL as fes2_model LOGGER = logging.getLogger(__name__) def cql2fes(cql, namespaces, fes_version='1.0'): """transforms Common Query Language (CQL) query into OGC fes1 syntax""" filters = [] tmp_list = [] logical_op = None LOGGER.debug('CQL: %s', cql) if fes_version.startswith('1.0'): element_or = 'ogc:Or' element_and = 'ogc:And' element_filter = 'ogc:Filter' element_propertyname = 'ogc:PropertyName' element_literal = 'ogc:Literal' elif fes_version.startswith('2.0'): element_or = 'fes20:Or' element_and = 'fes20:And' element_filter = 'fes20:Filter' element_propertyname = 'fes20:Literal' if ' or ' in cql: logical_op = etree.Element(util.nspath_eval(element_or, namespaces)) tmp_list = cql.split(' or ') elif ' OR ' in cql: logical_op = etree.Element(util.nspath_eval(element_or, namespaces)) tmp_list = cql.split(' OR ') elif ' and ' in cql: logical_op = etree.Element(util.nspath_eval(element_and, namespaces)) tmp_list = cql.split(' and ') elif ' AND ' in cql: logical_op = etree.Element(util.nspath_eval(element_and, namespaces)) tmp_list = cql.split(' AND ') if tmp_list: LOGGER.debug('Logical operator found (AND/OR)') else: tmp_list.append(cql) for t in tmp_list: filters.append(_parse_condition(t, fes_version)) root = etree.Element(util.nspath_eval(element_filter, namespaces)) if logical_op is not None: root.append(logical_op) for flt in filters: condition = etree.Element(util.nspath_eval(flt[0], namespaces)) etree.SubElement( condition, util.nspath_eval(element_propertyname, namespaces)).text = flt[1] etree.SubElement( condition, util.nspath_eval(element_literal, namespaces)).text = flt[2] if logical_op is not None: logical_op.append(condition) else: root.append(condition) LOGGER.debug('Resulting OGC Filter: %s', etree.tostring(root, pretty_print=1)) return root def _parse_condition(condition, fes_version='1.0'): """parses a single condition""" LOGGER.debug('condition: %s', condition) # split at the most 2 times to take into account literals with # spaces in them property_name, operator, literal = condition.split(None, 2) literal = literal.replace('"', '').replace('\'', '') if fes_version.startswith('1.0'): fes_model = fes1_model elif fes_version.startswith('2.0'): fes_model = fes2_model for k, v in fes_model['ComparisonOperators'].items(): if v['opvalue'] == operator: fes_predicate = k LOGGER.debug('parsed condition: %s %s %s', property_name, fes_predicate, literal) return (fes_predicate, property_name, literal) ================================================ FILE: pycsw/ogc/csw/csw2.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import os from pycsw.core.etree import etree from pycsw import opensearch from pycsw.ogc.csw.cql import cql2fes from pycsw.core import metadata, util from pycsw.core.formats.fmt_json import xml2dict from pycsw.ogc.fes import fes1 import logging LOGGER = logging.getLogger(__name__) class Csw2(object): ''' CSW 2.x server ''' def __init__(self, server_csw): ''' Initialize CSW2 ''' self.parent = server_csw self.version = '2.0.2' def getcapabilities(self): ''' Handle GetCapabilities request ''' serviceidentification = True serviceprovider = True operationsmetadata = True if 'sections' in self.parent.kvp: serviceidentification = False serviceprovider = False operationsmetadata = False for section in self.parent.kvp['sections'].split(','): if section == 'ServiceIdentification': serviceidentification = True if section == 'ServiceProvider': serviceprovider = True if section == 'OperationsMetadata': operationsmetadata = True # check extra parameters that may be def'd by profiles if self.parent.profiles is not None: for prof in self.parent.profiles['loaded'].keys(): result = \ self.parent.profiles['loaded'][prof].check_parameters(self.parent.kvp) if result is not None: return self.exceptionreport(result['code'], result['locator'], result['text']) # @updateSequence: get latest update to repository try: updatesequence = \ util.get_time_iso2unix(self.parent.repository.query_insert()) except Exception as err: LOGGER.debug('Could not derive updateSequence: %s' % err) updatesequence = None node = etree.Element(util.nspath_eval('csw:Capabilities', self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='2.0.2', updateSequence=str(updatesequence)) if 'updatesequence' in self.parent.kvp: if int(self.parent.kvp['updatesequence']) == updatesequence: return node elif int(self.parent.kvp['updatesequence']) > updatesequence: return self.exceptionreport('InvalidUpdateSequence', 'updatesequence', 'outputsequence specified (%s) is higher than server\'s \ updatesequence (%s)' % (self.parent.kvp['updatesequence'], updatesequence)) node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = '%s %s/csw/2.0.2/CSW-discovery.xsd' % \ (self.parent.context.namespaces['csw'], self.parent.config['server'].get('ogc_schemas_base')) metadata_main = self.parent.config['metadata'] if serviceidentification: LOGGER.info('Writing section ServiceIdentification') serviceidentification = etree.SubElement(node, \ util.nspath_eval('ows:ServiceIdentification', self.parent.context.namespaces)) etree.SubElement(serviceidentification, util.nspath_eval('ows:Title', self.parent.context.namespaces)).text = \ metadata_main['identification'].get('title', 'missing') etree.SubElement(serviceidentification, util.nspath_eval('ows:Abstract', self.parent.context.namespaces)).text = \ metadata_main['identification'].get('description', 'missing') keywords = etree.SubElement(serviceidentification, util.nspath_eval('ows:Keywords', self.parent.context.namespaces)) for k in metadata_main['identification']['keywords']: etree.SubElement( keywords, util.nspath_eval('ows:Keyword', self.parent.context.namespaces)).text = k etree.SubElement(keywords, util.nspath_eval('ows:Type', self.parent.context.namespaces), codeSpace='ISOTC211/19115').text = \ metadata_main['identification'].get('keywords_type', 'missing') etree.SubElement(serviceidentification, util.nspath_eval('ows:ServiceType', self.parent.context.namespaces), codeSpace='OGC').text = 'CSW' for stv in self.parent.context.model['parameters']['version']['values']: etree.SubElement(serviceidentification, util.nspath_eval('ows:ServiceTypeVersion', self.parent.context.namespaces)).text = stv etree.SubElement(serviceidentification, util.nspath_eval('ows:Fees', self.parent.context.namespaces)).text = \ metadata_main['identification'].get('fees', 'missing') etree.SubElement(serviceidentification, util.nspath_eval('ows:AccessConstraints', self.parent.context.namespaces)).text = \ metadata_main['identification'].get('accessconstraints', 'missing') if serviceprovider: LOGGER.info('Writing section ServiceProvider') serviceprovider = etree.SubElement(node, util.nspath_eval('ows:ServiceProvider', self.parent.context.namespaces)) etree.SubElement(serviceprovider, util.nspath_eval('ows:ProviderName', self.parent.context.namespaces)).text = \ metadata_main['provider'].get('name', 'missing') providersite = etree.SubElement(serviceprovider, util.nspath_eval('ows:ProviderSite', self.parent.context.namespaces)) providersite.attrib[util.nspath_eval('xlink:type', self.parent.context.namespaces)] = 'simple' providersite.attrib[util.nspath_eval('xlink:href', self.parent.context.namespaces)] = \ metadata_main['provider'].get('url', 'missing') servicecontact = etree.SubElement(serviceprovider, util.nspath_eval('ows:ServiceContact', self.parent.context.namespaces)) etree.SubElement(servicecontact, util.nspath_eval('ows:IndividualName', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('name', 'missing') etree.SubElement(servicecontact, util.nspath_eval('ows:PositionName', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('position', 'missing') contactinfo = etree.SubElement(servicecontact, util.nspath_eval('ows:ContactInfo', self.parent.context.namespaces)) phone = etree.SubElement(contactinfo, util.nspath_eval('ows:Phone', self.parent.context.namespaces)) etree.SubElement(phone, util.nspath_eval('ows:Voice', self.parent.context.namespaces)).text = \ str(metadata_main['contact'].get('phone', 'missing')) etree.SubElement(phone, util.nspath_eval('ows:Facsimile', self.parent.context.namespaces)).text = \ str(metadata_main['contact'].get('fax', 'missing')) address = etree.SubElement(contactinfo, util.nspath_eval('ows:Address', self.parent.context.namespaces)) etree.SubElement(address, util.nspath_eval('ows:DeliveryPoint', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('address', 'missing') etree.SubElement(address, util.nspath_eval('ows:City', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('city', 'missing') etree.SubElement(address, util.nspath_eval('ows:AdministrativeArea', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('stateorprovince', 'missing') etree.SubElement(address, util.nspath_eval('ows:PostalCode', self.parent.context.namespaces)).text = \ str(metadata_main['contact'].get('postalcode', 'missing')) etree.SubElement(address, util.nspath_eval('ows:Country', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('country', 'missing') etree.SubElement(address, util.nspath_eval('ows:ElectronicMailAddress', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('email', 'missing') url = etree.SubElement(contactinfo, util.nspath_eval('ows:OnlineResource', self.parent.context.namespaces)) url.attrib[util.nspath_eval('xlink:type', self.parent.context.namespaces)] = 'simple' url.attrib[util.nspath_eval('xlink:href', self.parent.context.namespaces)] = \ metadata_main['contact'].get('url', 'missing') etree.SubElement(contactinfo, util.nspath_eval('ows:HoursOfService', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('hours', 'missing') etree.SubElement(contactinfo, util.nspath_eval('ows:ContactInstructions', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('instructions', 'missing') etree.SubElement(servicecontact, util.nspath_eval('ows:Role', self.parent.context.namespaces), codeSpace='ISOTC211/19115').text = \ metadata_main['contact'].get('role', 'missing222') if operationsmetadata: LOGGER.info('Writing section OperationsMetadata') operationsmetadata = etree.SubElement(node, util.nspath_eval('ows:OperationsMetadata', self.parent.context.namespaces)) for operation in self.parent.context.model['operations_order']: oper = etree.SubElement(operationsmetadata, util.nspath_eval('ows:Operation', self.parent.context.namespaces), name=operation) dcp = etree.SubElement(oper, util.nspath_eval('ows:DCP', self.parent.context.namespaces)) http = etree.SubElement(dcp, util.nspath_eval('ows:HTTP', self.parent.context.namespaces)) if self.parent.context.model['operations'][operation]['methods']['get']: get = etree.SubElement(http, util.nspath_eval('ows:Get', self.parent.context.namespaces)) get.attrib[util.nspath_eval('xlink:type',\ self.parent.context.namespaces)] = 'simple' get.attrib[util.nspath_eval('xlink:href',\ self.parent.context.namespaces)] = self.parent.config['server'].get('url') if self.parent.context.model['operations'][operation]['methods']['post']: post = etree.SubElement(http, util.nspath_eval('ows:Post', self.parent.context.namespaces)) post.attrib[util.nspath_eval('xlink:type', self.parent.context.namespaces)] = 'simple' post.attrib[util.nspath_eval('xlink:href', self.parent.context.namespaces)] = \ self.parent.config['server'].get('url') for parameter in \ sorted(self.parent.context.model['operations'][operation]['parameters']): param = etree.SubElement(oper, util.nspath_eval('ows:Parameter', self.parent.context.namespaces), name=parameter) for val in \ sorted(self.parent.context.model['operations'][operation]\ ['parameters'][parameter]['values']): etree.SubElement(param, util.nspath_eval('ows:Value', self.parent.context.namespaces)).text = val if operation == 'GetRecords': # advertise queryables for qbl in sorted(self.parent.repository.queryables.keys()): if qbl != '_all': param = etree.SubElement(oper, util.nspath_eval('ows:Constraint', self.parent.context.namespaces), name=qbl) for qbl2 in sorted(self.parent.repository.queryables[qbl]): etree.SubElement(param, util.nspath_eval('ows:Value', self.parent.context.namespaces)).text = qbl2 if self.parent.profiles is not None: for con in sorted(self.parent.context.model[\ 'operations']['GetRecords']['constraints'].keys()): param = etree.SubElement(oper, util.nspath_eval('ows:Constraint', self.parent.context.namespaces), name = con) for val in self.parent.context.model['operations']\ ['GetRecords']['constraints'][con]['values']: etree.SubElement(param, util.nspath_eval('ows:Value', self.parent.context.namespaces)).text = val for parameter in sorted(self.parent.context.model['parameters'].keys()): param = etree.SubElement(operationsmetadata, util.nspath_eval('ows:Parameter', self.parent.context.namespaces), name=parameter) for val in self.parent.context.model['parameters'][parameter]['values']: etree.SubElement(param, util.nspath_eval('ows:Value', self.parent.context.namespaces)).text = val for constraint in sorted(self.parent.context.model['constraints'].keys()): param = etree.SubElement(operationsmetadata, util.nspath_eval('ows:Constraint', self.parent.context.namespaces), name=constraint) for val in self.parent.context.model['constraints'][constraint]['values']: etree.SubElement(param, util.nspath_eval('ows:Value', self.parent.context.namespaces)).text = str(val) if self.parent.profiles is not None: for prof in self.parent.profiles['loaded'].keys(): ecnode = \ self.parent.profiles['loaded'][prof].get_extendedcapabilities() if ecnode is not None: operationsmetadata.append(ecnode) # always write out Filter_Capabilities LOGGER.info('Writing section Filter_Capabilities') fltcaps = etree.SubElement(node, util.nspath_eval('ogc:Filter_Capabilities', self.parent.context.namespaces)) spatialcaps = etree.SubElement(fltcaps, util.nspath_eval('ogc:Spatial_Capabilities', self.parent.context.namespaces)) geomops = etree.SubElement(spatialcaps, util.nspath_eval('ogc:GeometryOperands', self.parent.context.namespaces)) for geomtype in \ fes1.MODEL['GeometryOperands']['values']: etree.SubElement(geomops, util.nspath_eval('ogc:GeometryOperand', self.parent.context.namespaces)).text = geomtype spatialops = etree.SubElement(spatialcaps, util.nspath_eval('ogc:SpatialOperators', self.parent.context.namespaces)) for spatial_comparison in \ fes1.MODEL['SpatialOperators']['values']: etree.SubElement(spatialops, util.nspath_eval('ogc:SpatialOperator', self.parent.context.namespaces), name=spatial_comparison) scalarcaps = etree.SubElement(fltcaps, util.nspath_eval('ogc:Scalar_Capabilities', self.parent.context.namespaces)) etree.SubElement(scalarcaps, util.nspath_eval('ogc:LogicalOperators', self.parent.context.namespaces)) cmpops = etree.SubElement(scalarcaps, util.nspath_eval('ogc:ComparisonOperators', self.parent.context.namespaces)) for cmpop in sorted(fes1.MODEL['ComparisonOperators'].keys()): etree.SubElement(cmpops, util.nspath_eval('ogc:ComparisonOperator', self.parent.context.namespaces)).text = \ fes1.MODEL['ComparisonOperators'][cmpop]['opname'] arithops = etree.SubElement(scalarcaps, util.nspath_eval('ogc:ArithmeticOperators', self.parent.context.namespaces)) functions = etree.SubElement(arithops, util.nspath_eval('ogc:Functions', self.parent.context.namespaces)) functionames = etree.SubElement(functions, util.nspath_eval('ogc:FunctionNames', self.parent.context.namespaces)) for fnop in sorted(fes1.MODEL['Functions'].keys()): etree.SubElement(functionames, util.nspath_eval('ogc:FunctionName', self.parent.context.namespaces), nArgs=fes1.MODEL['Functions'][fnop]['args']).text = fnop idcaps = etree.SubElement(fltcaps, util.nspath_eval('ogc:Id_Capabilities', self.parent.context.namespaces)) for idcap in fes1.MODEL['Ids']['values']: etree.SubElement(idcaps, util.nspath_eval('ogc:%s' % idcap, self.parent.context.namespaces)) return node def describerecord(self): ''' Handle DescribeRecord request ''' if 'typename' not in self.parent.kvp or \ len(self.parent.kvp['typename']) == 0: # missing typename # set to return all typenames self.parent.kvp['typename'] = ['csw:Record'] if self.parent.profiles is not None: for prof in self.parent.profiles['loaded'].keys(): self.parent.kvp['typename'].append( self.parent.profiles['loaded'][prof].typename) elif self.parent.requesttype == 'GET': # pass via GET self.parent.kvp['typename'] = self.parent.kvp['typename'].split(',') if ('outputformat' in self.parent.kvp and self.parent.kvp['outputformat'] not in self.parent.context.model['operations']['DescribeRecord'] ['parameters']['outputFormat']['values']): # bad outputformat return self.exceptionreport('InvalidParameterValue', 'outputformat', 'Invalid value for outputformat: %s' % self.parent.kvp['outputformat']) if ('schemalanguage' in self.parent.kvp and self.parent.kvp['schemalanguage'] not in self.parent.context.model['operations']['DescribeRecord']['parameters'] ['schemaLanguage']['values']): # bad schemalanguage return self.exceptionreport('InvalidParameterValue', 'schemalanguage', 'Invalid value for schemalanguage: %s' % self.parent.kvp['schemalanguage']) node = etree.Element(util.nspath_eval('csw:DescribeRecordResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces) node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = \ '%s %s/csw/2.0.2/CSW-discovery.xsd' % (self.parent.context.namespaces['csw'], self.parent.config['server'].get('ogc_schemas_base')) for typename in self.parent.kvp['typename']: if typename.find(':') == -1: # unqualified typename return self.exceptionreport('InvalidParameterValue', 'typename', 'Typename not qualified: %s' % typename) if typename == 'csw:Record': # load core schema LOGGER.info('Writing csw:Record schema') schemacomponent = etree.SubElement(node, util.nspath_eval('csw:SchemaComponent', self.parent.context.namespaces), schemaLanguage='XMLSCHEMA', targetNamespace=self.parent.context.namespaces['csw']) path = os.path.join(self.parent.config['server'].get('home'), 'core', 'schemas', 'ogc', 'csw', '2.0.2', 'record.xsd') dublincore = etree.parse(path, self.parent.context.parser).getroot() schemacomponent.append(dublincore) if self.parent.profiles is not None: for prof in self.parent.profiles['loaded'].keys(): if self.parent.profiles['loaded'][prof].typename == typename: scnodes = \ self.parent.profiles['loaded'][prof].get_schemacomponents() if scnodes: for scn in scnodes: node.append(scn) return node def getdomain(self): ''' Handle GetDomain request ''' if ('parametername' not in self.parent.kvp and 'propertyname' not in self.parent.kvp): return self.exceptionreport('MissingParameterValue', 'parametername', 'Missing value. \ One of propertyname or parametername must be specified') node = etree.Element(util.nspath_eval('csw:GetDomainResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces) node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = '%s %s/csw/2.0.2/CSW-discovery.xsd' % \ (self.parent.context.namespaces['csw'], self.parent.config['server'].get('ogc_schemas_base')) if 'parametername' in self.parent.kvp: for pname in self.parent.kvp['parametername'].split(','): LOGGER.info('Parsing parametername %s', pname) domainvalue = etree.SubElement(node, util.nspath_eval('csw:DomainValues', self.parent.context.namespaces), type='csw:Record') etree.SubElement(domainvalue, util.nspath_eval('csw:ParameterName', self.parent.context.namespaces)).text = pname try: operation, parameter = pname.split('.') except Exception as err: LOGGER.debug(f'Cannot split pname: {err}') return node if (operation in self.parent.context.model['operations'].keys() and parameter in self.parent.context.model['operations'][operation]['parameters'].keys()): listofvalues = etree.SubElement(domainvalue, util.nspath_eval('csw:ListOfValues', self.parent.context.namespaces)) for val in \ sorted(self.parent.context.model['operations'][operation]\ ['parameters'][parameter]['values']): etree.SubElement(listofvalues, util.nspath_eval('csw:Value', self.parent.context.namespaces)).text = val if 'propertyname' in self.parent.kvp: for pname in self.parent.kvp['propertyname'].split(','): LOGGER.info('Parsing propertyname %s', pname) if pname.find('/') == 0: # it's an XPath pname2 = pname else: # it's a core queryable, map to internal typename model try: pname2 = self.parent.repository.queryables['_all'][pname]['dbcol'] except Exception as err: LOGGER.debug(f'pname2 not found: {err}') pname2 = pname # decipher typename dvtype = None if self.parent.profiles is not None: for prof in self.parent.profiles['loaded'].keys(): for prefix in self.parent.profiles['loaded'][prof].prefixes: if pname2.find(prefix) != -1: dvtype = self.parent.profiles['loaded'][prof].typename break if not dvtype: dvtype = 'csw:Record' domainvalue = etree.SubElement(node, util.nspath_eval('csw:DomainValues', self.parent.context.namespaces), type=dvtype) etree.SubElement(domainvalue, util.nspath_eval('csw:PropertyName', self.parent.context.namespaces)).text = pname try: LOGGER.info( 'Querying repository property %s, typename %s, \ domainquerytype %s', pname2, dvtype, self.parent.domainquerytype) count = False if self.parent.config['server'].get('domaincounts', False): count = True results = self.parent.repository.query_domain( pname2, dvtype, self.parent.domainquerytype, count) LOGGER.debug('Results: %d', len(results)) if self.parent.domainquerytype == 'range': rangeofvalues = etree.SubElement(domainvalue, util.nspath_eval('csw:RangeOfValues', self.parent.context.namespaces)) etree.SubElement(rangeofvalues, util.nspath_eval('csw:MinValue', self.parent.context.namespaces)).text = results[0][0] etree.SubElement(rangeofvalues, util.nspath_eval('csw:MaxValue', self.parent.context.namespaces)).text = results[0][1] else: listofvalues = etree.SubElement(domainvalue, util.nspath_eval('csw:ListOfValues', self.parent.context.namespaces)) for result in results: LOGGER.debug(str(result)) if (result is not None and result[0] is not None): # drop null values if count: # show counts val = '%s (%s)' % (result[0], result[1]) else: val = result[0] etree.SubElement(listofvalues, util.nspath_eval('csw:Value', self.parent.context.namespaces)).text = val except Exception as err: # here we fail silently back to the client because # CSW tells us to LOGGER.exception('No results for propertynames') return node def getrecords(self): ''' Handle GetRecords request ''' timestamp = util.get_today_and_now() if ('elementsetname' not in self.parent.kvp and 'elementname' not in self.parent.kvp): # mutually exclusive required return self.exceptionreport('MissingParameterValue', 'elementsetname', 'Missing one of ElementSetName or ElementName parameter(s)') if 'outputschema' not in self.parent.kvp: self.parent.kvp['outputschema'] = self.parent.context.namespaces['csw'] if (self.parent.kvp['outputschema'] not in self.parent.context.model['operations'] ['GetRecords']['parameters']['outputSchema']['values']): return self.exceptionreport('InvalidParameterValue', 'outputschema', 'Invalid outputSchema parameter value: %s' % self.parent.kvp['outputschema']) if 'outputformat' not in self.parent.kvp: self.parent.kvp['outputformat'] = 'application/xml' if (self.parent.kvp['outputformat'] not in self.parent.context.model['operations'] ['GetRecords']['parameters']['outputFormat']['values']): return self.exceptionreport('InvalidParameterValue', 'outputformat', 'Invalid outputFormat parameter value: %s' % self.parent.kvp['outputformat']) if 'resulttype' not in self.parent.kvp: self.parent.kvp['resulttype'] = 'hits' if self.parent.kvp['resulttype'] is not None: if (self.parent.kvp['resulttype'] not in self.parent.context.model['operations'] ['GetRecords']['parameters']['resultType']['values']): return self.exceptionreport('InvalidParameterValue', 'resulttype', 'Invalid resultType parameter value: %s' % self.parent.kvp['resulttype']) if (('elementname' not in self.parent.kvp or len(self.parent.kvp['elementname']) == 0) and self.parent.kvp['elementsetname'] not in self.parent.context.model['operations']['GetRecords']['parameters'] ['ElementSetName']['values']): return self.exceptionreport('InvalidParameterValue', 'elementsetname', 'Invalid ElementSetName parameter value: %s' % self.parent.kvp['elementsetname']) if ('elementname' in self.parent.kvp and self.parent.requesttype == 'GET'): # passed via GET self.parent.kvp['elementname'] = self.parent.kvp['elementname'].split(',') self.parent.kvp['elementsetname'] = 'summary' if 'typenames' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'typenames', 'Missing typenames parameter') if ('typenames' in self.parent.kvp and self.parent.requesttype == 'GET'): # passed via GET self.parent.kvp['typenames'] = self.parent.kvp['typenames'].split(',') if 'typenames' in self.parent.kvp: for tname in self.parent.kvp['typenames']: if (tname not in self.parent.context.model['operations']['GetRecords'] ['parameters']['typeNames']['values']): return self.exceptionreport('InvalidParameterValue', 'typenames', 'Invalid typeNames parameter value: %s' % tname) # check elementname's if 'elementname' in self.parent.kvp: for ename in self.parent.kvp['elementname']: enamelist = self.parent.repository.queryables['_all'].keys() if ename not in enamelist: return self.exceptionreport('InvalidParameterValue', 'elementname', 'Invalid ElementName parameter value: %s' % ename) if self.parent.kvp['resulttype'] == 'validate': return self._write_acknowledgement() maxrecords_cfg = int(self.parent.config['server'].get('maxrecords', -1)) if 'maxrecords' not in self.parent.kvp: # not specified by client if maxrecords_cfg > -1: # specified in config self.parent.kvp['maxrecords'] = maxrecords_cfg else: # spec default self.parent.kvp['maxrecords'] = 10 else: # specified by client if self.parent.kvp['maxrecords'] == '': self.parent.kvp['maxrecords'] = 10 if maxrecords_cfg > -1: # set in config if int(self.parent.kvp['maxrecords']) > maxrecords_cfg: self.parent.kvp['maxrecords'] = maxrecords_cfg if any(x in opensearch.QUERY_PARAMETERS for x in self.parent.kvp): LOGGER.debug('OpenSearch Geo/Time parameters detected.') self.parent.kvp['constraintlanguage'] = 'FILTER' tmp_filter = opensearch.kvp2filterxml(self.parent.kvp, self.parent.context, self.parent.profiles) if tmp_filter != "": self.parent.kvp['constraint'] = tmp_filter LOGGER.debug('OpenSearch Geo/Time parameters to Filter: %s.', self.parent.kvp['constraint']) if self.parent.requesttype == 'GET': if 'constraint' in self.parent.kvp: # GET request LOGGER.debug('csw:Constraint passed over HTTP GET.') if 'constraintlanguage' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'constraintlanguage', 'constraintlanguage required when constraint specified') if (self.parent.kvp['constraintlanguage'] not in self.parent.context.model['operations']['GetRecords']['parameters'] ['CONSTRAINTLANGUAGE']['values']): return self.exceptionreport('InvalidParameterValue', 'constraintlanguage', 'Invalid constraintlanguage: %s' % self.parent.kvp['constraintlanguage']) if self.parent.kvp['constraintlanguage'] == 'CQL_TEXT': tmp = self.parent.kvp['constraint'] try: LOGGER.info('Transforming CQL into fes1') LOGGER.debug('CQL: %s', tmp) self.parent.kvp['constraint'] = {} self.parent.kvp['constraint']['type'] = 'filter' cql = cql2fes(tmp, self.parent.context.namespaces, fes_version='1.0') self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = fes1.parse(cql, self.parent.repository.queryables['_all'], self.parent.repository.dbtype, self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) self.parent.kvp['constraint']['_dict'] = xml2dict(etree.tostring(cql), self.parent.context.namespaces) except Exception as err: LOGGER.exception('Invalid CQL query %s', tmp) return self.exceptionreport('InvalidParameterValue', 'constraint', 'Invalid Filter syntax') elif self.parent.kvp['constraintlanguage'] == 'FILTER': # validate filter XML try: schema = os.path.join(self.parent.config['server'].get('home'), 'core', 'schemas', 'ogc', 'filter', '1.1.0', 'filter.xsd') LOGGER.info('Validating Filter %s', self.parent.kvp['constraint']) schema = etree.XMLSchema(file=schema) parser = etree.XMLParser(schema=schema, resolve_entities=False) doc = etree.fromstring(self.parent.kvp['constraint'], parser) LOGGER.debug('Filter is valid XML') self.parent.kvp['constraint'] = {} self.parent.kvp['constraint']['type'] = 'filter' self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = \ fes1.parse(doc, self.parent.repository.queryables['_all'], self.parent.repository.dbtype, self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) self.parent.kvp['constraint']['_dict'] = xml2dict(etree.tostring(doc), self.parent.context.namespaces) except Exception as err: errortext = \ 'Exception: document not valid.\nError: %s.' % str(err) LOGGER.exception(errortext) return self.exceptionreport('InvalidParameterValue', 'constraint', 'Invalid Filter query: %s' % errortext) else: self.parent.kvp['constraint'] = {} if 'sortby' not in self.parent.kvp: self.parent.kvp['sortby'] = None elif 'sortby' in self.parent.kvp and self.parent.requesttype == 'GET': LOGGER.debug('Sorted query specified') tmp = self.parent.kvp['sortby'] self.parent.kvp['sortby'] = {} try: name, order = tmp.rsplit(':', 1) except Exception: return self.exceptionreport('InvalidParameterValue', 'sortby', 'Invalid SortBy value: must be in the format\ propertyname:A or propertyname:D') try: self.parent.kvp['sortby']['propertyname'] = \ self.parent.repository.queryables['_all'][name]['dbcol'] if name.find('BoundingBox') != -1 or name.find('Envelope') != -1: # it's a spatial sort self.parent.kvp['sortby']['spatial'] = True except Exception as err: return self.exceptionreport('InvalidParameterValue', 'sortby', 'Invalid SortBy propertyname: %s' % name) if order not in ['A', 'D']: return self.exceptionreport('InvalidParameterValue', 'sortby', 'Invalid SortBy value: sort order must be "A" or "D"') if order == 'D': self.parent.kvp['sortby']['order'] = 'DESC' else: self.parent.kvp['sortby']['order'] = 'ASC' if 'startposition' not in self.parent.kvp or not self.parent.kvp['startposition']: self.parent.kvp['startposition'] = 1 # query repository LOGGER.debug('Querying repository with constraint: %s,\ sortby: %s, typenames: %s, maxrecords: %s, startposition: %s', self.parent.kvp['constraint'], self.parent.kvp['sortby'], self.parent.kvp['typenames'], self.parent.kvp['maxrecords'], self.parent.kvp['startposition']) try: matched, results = self.parent.repository.query( constraint=self.parent.kvp['constraint'], sortby=self.parent.kvp['sortby'], typenames=self.parent.kvp['typenames'], maxrecords=self.parent.kvp['maxrecords'], startposition=int(self.parent.kvp['startposition'])-1) except Exception as err: LOGGER.exception('Invalid query syntax. Query: %s', self.parent.kvp['constraint']) LOGGER.exception('Invalid query syntax. Result: %s', err) return self.exceptionreport('InvalidParameterValue', 'constraint', 'Invalid query syntax') dsresults = [] hopcount = int(self.parent.kvp.get('hopcount', 2)) - 1 if ('federatedcatalogues' in self.parent.config and self.parent.kvp.get('distributedsearch') and hopcount > 0): LOGGER.debug('DistributedSearch specified (hopCount: %s).', hopcount) from owslib.csw import CatalogueServiceWeb from owslib.ows import ExceptionReport for fedcat in self.parent.config.get('federatedcatalogues', []): if fedcat['type'] != 'CSW': LOGGER.debug(f"Federated catalogue type {fc['type']} not supported; skipping") continue LOGGER.debug('Performing distributed search on federated \ catalogue: %s.', fedcat['url']) remotecsw = CatalogueServiceWeb(fedcat['url'], version='2.0.2', skip_caps=True) try: if str(self.parent.request).startswith('http'): self.parent.request = self.parent.request.split('?')[-1] self.parent.request = self.parent.request.replace('mode=opensearch', '') remotecsw.getrecords2(xml=self.parent.request, esn=self.parent.kvp['elementsetname'], outputschema=self.parent.kvp['outputschema']) if hasattr(remotecsw, 'results'): LOGGER.debug( 'Distributed search results from catalogue \ %s: %s.', fedcat['url'], remotecsw.results) remotecsw_matches = int(remotecsw.results['matches']) plural = 's' if remotecsw_matches != 1 else '' if remotecsw_matches > 0: matched = str(int(matched) + remotecsw_matches) dsresults.append(etree.Comment( ' %d result%s from %s ' % (remotecsw_matches, plural, fedcat['url']))) dsresults.append(remotecsw.records) except ExceptionReport as err: error_string = 'remote CSW %s returned exception: ' % fedcat['url'] dsresults.append(etree.Comment( ' %s\n\n%s ' % (error_string, err))) LOGGER.exception(error_string) except Exception as err: error_string = 'remote CSW %s returned error: ' % fedcat['url'] dsresults.append(etree.Comment( ' %s\n\n%s ' % (error_string, err))) LOGGER.exception(error_string) if int(matched) == 0: returned = nextrecord = '0' elif int(self.parent.kvp['maxrecords']) == 0: returned = '0' nextrecord = '1' elif int(matched) < int(self.parent.kvp['startposition']): returned = '0' nextrecord = '1' elif int(matched) <= int(self.parent.kvp['startposition']) + int(self.parent.kvp['maxrecords']) - 1: returned = str(int(matched) - int(self.parent.kvp['startposition']) + 1) nextrecord = '0' else: returned = str(self.parent.kvp['maxrecords']) nextrecord = str(int(self.parent.kvp['startposition']) + int(self.parent.kvp['maxrecords'])) LOGGER.debug('Results: matched: %s, returned: %s, next: %s', matched, returned, nextrecord) node = etree.Element(util.nspath_eval('csw:GetRecordsResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='2.0.2') node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = \ '%s %s/csw/2.0.2/CSW-discovery.xsd' % \ (self.parent.context.namespaces['csw'], self.parent.config['server'].get('ogc_schemas_base')) if 'requestid' in self.parent.kvp and self.parent.kvp['requestid'] is not None: etree.SubElement(node, util.nspath_eval('csw:RequestId', self.parent.context.namespaces)).text = self.parent.kvp['requestid'] etree.SubElement(node, util.nspath_eval('csw:SearchStatus', self.parent.context.namespaces), timestamp=timestamp) if 'where' not in self.parent.kvp['constraint'] and \ self.parent.kvp['resulttype'] in [None, 'hits']: returned = '0' searchresults = etree.SubElement(node, util.nspath_eval('csw:SearchResults', self.parent.context.namespaces), numberOfRecordsMatched=matched, numberOfRecordsReturned=returned, nextRecord=nextrecord, recordSchema=self.parent.kvp['outputschema']) if self.parent.kvp['elementsetname'] is not None: searchresults.attrib['elementSet'] = self.parent.kvp['elementsetname'] if 'where' not in self.parent.kvp['constraint'] \ and self.parent.kvp['resulttype'] is None: LOGGER.debug('Empty result set returned') return node if self.parent.kvp['resulttype'] == 'hits': return node if results is not None: if len(results) < int(self.parent.kvp['maxrecords']): max1 = len(results) else: max1 = int(self.parent.kvp['startposition']) + (int(self.parent.kvp['maxrecords'])-1) LOGGER.info('Presenting records %s - %s', self.parent.kvp['startposition'], max1) for res in results: node_ = None if self.parent.xslts: try: node_ = self.parent._render_xslt(res) except Exception as err: self.parent.response = self.exceptionreport( 'NoApplicableCode', 'service', 'XSLT transformation failed. Check server logs for errors %s' % str(err)) return self.parent.response if node_ is not None: searchresults.append(node_) else: try: if (self.parent.kvp['outputschema'] == 'http://www.opengis.net/cat/csw/2.0.2' and 'csw:Record' in self.parent.kvp['typenames']): # serialize csw:Record inline searchresults.append(self._write_record( res, self.parent.repository.queryables['_all'])) elif (self.parent.kvp['outputschema'] == 'http://www.opengis.net/cat/csw/2.0.2' and 'csw:Record' not in self.parent.kvp['typenames']): # serialize into csw:Record model for prof in self.parent.profiles['loaded']: # find source typename if self.parent.profiles['loaded'][prof].typename in \ self.parent.kvp['typenames']: typename = self.parent.profiles['loaded'][prof].typename break util.transform_mappings( self.parent.repository.queryables['_all'], self.parent.context.model['typenames'][typename][ 'mappings']['csw:Record'] ) searchresults.append(self._write_record( res, self.parent.repository.queryables['_all'])) elif self.parent.kvp['outputschema'] in self.parent.outputschemas.keys(): # use outputschema serializer searchresults.append(self.parent.outputschemas[self.parent.kvp['outputschema']].write_record(res, self.parent.kvp['elementsetname'], self.parent.context, self.parent.config['server'].get('url'))) else: # use profile serializer searchresults.append( self.parent.profiles['loaded'][self.parent.kvp['outputschema']].\ write_record(res, self.parent.kvp['elementsetname'], self.parent.kvp['outputschema'], self.parent.repository.queryables['_all'])) except Exception as err: self.parent.response = self.exceptionreport( 'NoApplicableCode', 'service', 'Record serialization failed: %s' % str(err)) return self.parent.response if len(dsresults) > 0: # return DistributedSearch results for resultset in dsresults: if isinstance(resultset, etree._Comment): searchresults.append(resultset) for rec in resultset: searchresults.append(etree.fromstring(resultset[rec].xml, self.parent.context.parser)) if 'responsehandler' in self.parent.kvp: # process the handler self.parent._process_responsehandler(etree.tostring(node, pretty_print=self.parent.pretty_print)) else: return node def getrecordbyid(self, raw=False): ''' Handle GetRecordById request ''' if 'id' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'id', 'Missing id parameter') if len(self.parent.kvp['id']) < 1: return self.exceptionreport('InvalidParameterValue', 'id', 'Invalid id parameter') if 'outputschema' not in self.parent.kvp: self.parent.kvp['outputschema'] = self.parent.context.namespaces['csw'] if self.parent.requesttype == 'GET': self.parent.kvp['id'] = self.parent.kvp['id'].split(',') if ('outputformat' in self.parent.kvp and self.parent.kvp['outputformat'] not in self.parent.context.model['operations']['GetRecordById']['parameters'] ['outputFormat']['values']): return self.exceptionreport('InvalidParameterValue', 'outputformat', 'Invalid outputformat parameter %s' % self.parent.kvp['outputformat']) if ('outputschema' in self.parent.kvp and self.parent.kvp['outputschema'] not in self.parent.context.model['operations']['GetRecordById']['parameters'] ['outputSchema']['values']): return self.exceptionreport('InvalidParameterValue', 'outputschema', 'Invalid outputschema parameter %s' % self.parent.kvp['outputschema']) if 'elementsetname' not in self.parent.kvp: self.parent.kvp['elementsetname'] = 'summary' else: if (self.parent.kvp['elementsetname'] not in self.parent.context.model['operations']['GetRecordById']['parameters'] ['ElementSetName']['values']): return self.exceptionreport('InvalidParameterValue', 'elementsetname', 'Invalid elementsetname parameter %s' % self.parent.kvp['elementsetname']) node = etree.Element(util.nspath_eval('csw:GetRecordByIdResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces) node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = '%s %s/csw/2.0.2/CSW-discovery.xsd' % \ (self.parent.context.namespaces['csw'], self.parent.config['server'].get('ogc_schemas_base')) # query repository LOGGER.info('Querying repository with ids: %s', self.parent.kvp['id'][0]) results = self.parent.repository.query_ids(self.parent.kvp['id']) if raw: # GetRepositoryItem request LOGGER.debug('GetRepositoryItem request') if len(results) > 0: return etree.fromstring(util.getqattr(results[0], self.parent.context.md_core_model['mappings']['pycsw:XML']), self.parent.context.parser) for result in results: node_ = None if self.parent.xslts: try: node_ = self.parent._render_xslt(result) except Exception as err: self.parent.response = self.exceptionreport( 'NoApplicableCode', 'service', 'XSLT transformation failed. Check server logs for errors %s' % str(err)) return self.parent.response if node_ is not None: node = node_ else: if (util.getqattr(result, self.parent.context.md_core_model['mappings']['pycsw:Typename']) == 'csw:Record' and self.parent.kvp['outputschema'] == 'http://www.opengis.net/cat/csw/2.0.2'): # serialize record inline node.append(self._write_record( result, self.parent.repository.queryables['_all'])) elif (self.parent.kvp['outputschema'] == 'http://www.opengis.net/cat/csw/2.0.2'): # serialize into csw:Record model typename = None for prof in self.parent.profiles['loaded']: # find source typename if self.parent.profiles['loaded'][prof].typename in \ [util.getqattr(result, self.parent.context.md_core_model['mappings']['pycsw:Typename'])]: typename = self.parent.profiles['loaded'][prof].typename break if typename is not None: util.transform_mappings( self.parent.repository.queryables['_all'], self.parent.context.model['typenames'][typename][ 'mappings']['csw:Record'] ) node.append(self._write_record( result, self.parent.repository.queryables['_all'])) elif self.parent.kvp['outputschema'] in self.parent.outputschemas.keys(): # use outputschema serializer node.append(self.parent.outputschemas[self.parent.kvp['outputschema']].write_record(result, self.parent.kvp['elementsetname'], self.parent.context, self.parent.config['server'].get('url'))) else: # it's a profile output node.append( self.parent.profiles['loaded'][self.parent.kvp['outputschema']].write_record( result, self.parent.kvp['elementsetname'], self.parent.kvp['outputschema'], self.parent.repository.queryables['_all'])) if raw and len(results) == 0: return None return node def getrepositoryitem(self): ''' Handle GetRepositoryItem request ''' # similar to GetRecordById without csw:* wrapping node = self.parent.getrecordbyid(raw=True) if node is None: return self.exceptionreport('NotFound', 'id', 'No repository item found for \'%s\'' % self.parent.kvp['id']) else: return node def transaction(self): ''' Handle Transaction request ''' try: self.parent._test_manager() except Exception as err: return self.exceptionreport('NoApplicableCode', 'transaction', str(err)) inserted = 0 updated = 0 deleted = 0 insertresults = [] LOGGER.debug('Transaction list: %s', self.parent.kvp['transactions']) for ttype in self.parent.kvp['transactions']: if ttype['type'] == 'insert': try: record = metadata.parse_record(self.parent.context, ttype['xml'], self.parent.repository)[0] except Exception as err: LOGGER.exception('Transaction (insert) failed') return self.exceptionreport('NoApplicableCode', 'insert', 'Transaction (insert) failed: record parsing failed: %s' \ % str(err)) LOGGER.debug('Transaction operation: %s', record) if not hasattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']): return self.exceptionreport('NoApplicableCode', 'insert', 'Record requires an identifier') # insert new record try: self.parent.repository.insert(record, 'local', util.get_today_and_now()) inserted += 1 insertresults.append( {'identifier': getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']), 'title': getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Title'])}) except Exception as err: return self.exceptionreport('NoApplicableCode', 'insert', 'Transaction (insert) failed: %s.' % str(err)) elif ttype['type'] == 'update': if 'constraint' not in ttype: # update full existing resource in repository try: record = metadata.parse_record(self.parent.context, ttype['xml'], self.parent.repository)[0] identifier = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']) except Exception as err: return self.exceptionreport('NoApplicableCode', 'insert', 'Transaction (update) failed: record parsing failed: %s' \ % str(err)) # query repository to see if record already exists LOGGER.info('checking if record exists (%s)', identifier) results = self.parent.repository.query_ids(ids=[identifier]) if len(results) == 0: LOGGER.debug('id %s does not exist in repository', identifier) else: # existing record, it's an update try: self.parent.repository.update(record) updated += 1 except Exception as err: return self.exceptionreport('NoApplicableCode', 'update', 'Transaction (update) failed: %s.' % str(err)) else: # update by record property and constraint # get / set XPath for property names for rp in ttype['recordproperty']: if rp['name'] not in self.parent.repository.queryables['_all']: # is it an XPath? if rp['name'].find('/') != -1: # scan outputschemas; if match, bind for osch in self.parent.outputschemas.values(): for key, value in osch.XPATH_MAPPINGS.items(): if value == rp['name']: # match rp['rp'] = {'xpath': value, 'name': key} rp['rp']['dbcol'] = self.parent.repository.queryables['_all'][key] break else: return self.exceptionreport('NoApplicableCode', 'update', 'Transaction (update) failed: invalid property2: %s.' % str(rp['name'])) else: rp['rp']= \ self.parent.repository.queryables['_all'][rp['name']] LOGGER.debug('Record Properties: %s.', ttype['recordproperty']) try: updated += self.parent.repository.update(record=None, recprops=ttype['recordproperty'], constraint=ttype['constraint']) except Exception as err: LOGGER.exception('Transaction (updated) failed') return self.exceptionreport('NoApplicableCode', 'update', 'Transaction (update) failed: %s.' % str(err)) elif ttype['type'] == 'delete': deleted += self.parent.repository.delete(ttype['constraint']) node = etree.Element(util.nspath_eval('csw:TransactionResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='2.0.2') node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = '%s %s/csw/2.0.2/CSW-publication.xsd' % \ (self.parent.context.namespaces['csw'], self.parent.config['server'].get('ogc_schemas_base')) node.append( self._write_transactionsummary( inserted=inserted, updated=updated, deleted=deleted)) if (len(insertresults) > 0 and self.parent.kvp['verboseresponse']): # show insert result identifiers node.append(self._write_verboseresponse(insertresults)) return node def harvest(self): ''' Handle Harvest request ''' service_identifier = None old_identifier = None deleted = [] try: self.parent._test_manager() except Exception as err: return self.exceptionreport('NoApplicableCode', 'harvest', str(err)) if self.parent.requesttype == 'GET': if 'resourcetype' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'resourcetype', 'Missing resourcetype parameter') if 'source' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'source', 'Missing source parameter') # validate resourcetype if (self.parent.kvp['resourcetype'] not in self.parent.context.model['operations']['Harvest']['parameters']['ResourceType'] ['values']): return self.exceptionreport('InvalidParameterValue', 'resourcetype', 'Invalid resource type parameter: %s.\ Allowable resourcetype values: %s' % (self.parent.kvp['resourcetype'], ','.join(sorted(self.parent.context.model['operations']['Harvest']['parameters'] ['ResourceType']['values'])))) if (self.parent.kvp['resourcetype'].find('opengis.net') == -1 and self.parent.kvp['resourcetype'].find('urn:geoss:waf') == -1): # fetch content-based resource LOGGER.debug('Fetching resource %s', self.parent.kvp['source']) try: content = util.http_request('GET', self.parent.kvp['source']) except Exception as err: errortext = 'Error fetching resource %s.\nError: %s.' % \ (self.parent.kvp['source'], str(err)) LOGGER.exception(errortext) return self.exceptionreport('InvalidParameterValue', 'source', errortext) else: # it's a service URL content = self.parent.kvp['source'] # query repository to see if service already exists LOGGER.info('checking if service exists (%s)', content) results = self.parent.repository.query_source(content) if len(results) > 0: # exists, keep identifier for update LOGGER.debug('Service already exists, keeping identifier and results') service_identifier = getattr(results[0], self.parent.context.md_core_model['mappings']['pycsw:Identifier']) service_results = results LOGGER.debug('Identifier is %s', service_identifier) # return self.exceptionreport('NoApplicableCode', 'source', # 'Insert failed: service %s already in repository' % content) if hasattr(self.parent.repository, 'local_ingest') and self.parent.repository.local_ingest: updated = 0 deleted = [] try: ir = self.parent.repository.insert(self.parent.kvp['resourcetype'], self.parent.kvp['source']) inserted = len(ir) except Exception as err: LOGGER.exception('Harvest (insert) failed') return self.exceptionreport('NoApplicableCode', 'source', 'Harvest (insert) failed: %s.' % str(err)) else: # parse resource into record try: records_parsed = metadata.parse_record(self.parent.context, content, self.parent.repository, self.parent.kvp['resourcetype'], pagesize=self.parent.csw_harvest_pagesize) except Exception as err: LOGGER.exception(err) return self.exceptionreport('NoApplicableCode', 'source', 'Harvest failed: record parsing failed: %s' % str(err)) inserted = 0 updated = 0 ir = [] LOGGER.debug('Total Records parsed: %d', len(records_parsed)) for record in records_parsed: if self.parent.kvp['resourcetype'] == 'urn:geoss:waf': src = record.source else: src = self.parent.kvp['source'] setattr(record, self.parent.context.md_core_model['mappings']['pycsw:Source'], src) setattr(record, self.parent.context.md_core_model['mappings']['pycsw:InsertDate'], util.get_today_and_now()) identifier = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']) source = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Source']) insert_date = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:InsertDate']) title = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Title']) record_type = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Type']) record_identifier = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']) if record_type == 'service' and service_identifier is not None: # service endpoint LOGGER.info('Replacing service identifier from %s to %s', record_identifier, service_identifier) old_identifier = record_identifier identifier = record_identifier = service_identifier if (record_type != 'service' and service_identifier is not None and old_identifier is not None): # service resource if record_identifier.find(old_identifier) != -1: new_identifier = record_identifier.replace(old_identifier, service_identifier) LOGGER.debug('Replacing service resource identifier from %s to %s', record_identifier, new_identifier) identifier = record_identifier = new_identifier ir.append({'identifier': identifier, 'title': title}) results = [] if 'source' not in self.parent.config['repository']: # query repository to see if record already exists LOGGER.info('checking if record exists (%s)', identifier) results = self.parent.repository.query_ids(ids=[identifier]) if len(results) == 0: # check for service identifier LOGGER.info('checking if service id exists (%s)', service_identifier) results = self.parent.repository.query_ids(ids=[service_identifier]) LOGGER.debug(str(results)) if len(results) == 0: # new record, it's a new insert inserted += 1 try: tmp = self.parent.repository.insert(record, source, insert_date) if tmp is not None: ir = tmp except Exception as err: return self.exceptionreport('NoApplicableCode', 'source', 'Harvest (insert) failed: %s.' % str(err)) else: # existing record, it's an update if source != results[0].source: # same identifier, but different source return self.exceptionreport('NoApplicableCode', 'source', 'Insert failed: identifier %s in repository\ has source %s.' % (identifier, source)) try: self.parent.repository.update(record) except Exception as err: return self.exceptionreport('NoApplicableCode', 'source', 'Harvest (update) failed: %s.' % str(err)) updated += 1 if service_identifier is not None: fresh_records = [str(i['identifier']) for i in ir] existing_records = [str(i.identifier) for i in service_results] deleted = set(existing_records) - set(fresh_records) LOGGER.debug('Records to delete: %s', deleted) for to_delete in deleted: delete_constraint = { 'type': 'filter', 'values': [to_delete], 'where': 'identifier = :pvalue0' } self.parent.repository.delete(delete_constraint) node = etree.Element(util.nspath_eval('csw:HarvestResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces) node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = \ '%s %s/csw/2.0.2/CSW-publication.xsd' % (self.parent.context.namespaces['csw'], self.parent.config['server'].get('ogc_schemas_base')) node2 = etree.SubElement(node, util.nspath_eval('csw:TransactionResponse', self.parent.context.namespaces), version='2.0.2') node2.append( self._write_transactionsummary(inserted=len(ir), updated=updated, deleted=len(deleted))) if inserted > 0: # show insert result identifiers node2.append(self._write_verboseresponse(ir)) if 'responsehandler' in self.parent.kvp: # process the handler self.parent._process_responsehandler(etree.tostring(node, pretty_print=self.parent.pretty_print)) else: return node def _write_record(self, recobj, queryables): ''' Generate csw:Record ''' if self.parent.kvp['elementsetname'] == 'brief': elname = 'BriefRecord' elif self.parent.kvp['elementsetname'] == 'summary': elname = 'SummaryRecord' else: elname = 'Record' record = etree.Element(util.nspath_eval('csw:%s' % elname, self.parent.context.namespaces)) if ('elementname' in self.parent.kvp and len(self.parent.kvp['elementname']) > 0): for elemname in self.parent.kvp['elementname']: if (elemname.find('BoundingBox') != -1 or elemname.find('Envelope') != -1): bboxel = write_boundingbox(util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:BoundingBox']), self.parent.context.namespaces) if bboxel is not None: record.append(bboxel) else: value = util.getqattr(recobj, queryables[elemname]['dbcol']) if value: etree.SubElement(record, util.nspath_eval(elemname, self.parent.context.namespaces)).text = value elif 'elementsetname' in self.parent.kvp: if (self.parent.kvp['elementsetname'] == 'full' and util.getqattr(recobj, self.parent.context.md_core_model['mappings']\ ['pycsw:Typename']) == 'csw:Record' and util.getqattr(recobj, self.parent.context.md_core_model['mappings']\ ['pycsw:Schema']) == 'http://www.opengis.net/cat/csw/2.0.2' and util.getqattr(recobj, self.parent.context.md_core_model['mappings']\ ['pycsw:Type']) != 'service'): # dump record as is and exit return etree.fromstring(util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:XML']), self.parent.context.parser) etree.SubElement(record, util.nspath_eval('dc:identifier', self.parent.context.namespaces)).text = \ util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:Identifier']) for i in ['dc:title', 'dc:type']: val = util.getqattr(recobj, queryables[i]['dbcol']) if not val: val = '' etree.SubElement(record, util.nspath_eval(i, self.parent.context.namespaces)).text = val if self.parent.kvp['elementsetname'] in ['summary', 'full']: # add summary elements keywords = util.getqattr(recobj, queryables['dc:subject']['dbcol']) if keywords is not None: for keyword in keywords.split(','): etree.SubElement(record, util.nspath_eval('dc:subject', self.parent.context.namespaces)).text = keyword val = util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:TopicCategory']) if val: etree.SubElement(record, util.nspath_eval('dc:subject', self.parent.context.namespaces), scheme='http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_TopicCategoryCode').text = val val = util.getqattr(recobj, queryables['dc:format']['dbcol']) if val: etree.SubElement(record, util.nspath_eval('dc:format', self.parent.context.namespaces)).text = val # links rlinks = util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:Links']) if rlinks: for link in util.jsonify_links(rlinks): ref = etree.SubElement(record, util.nspath_eval('dct:references', self.parent.context.namespaces)) if link.get('protocol'): ref.attrib['scheme'] = link['protocol'] ref.text = link['url'] for i in ['dc:relation', 'dct:modified', 'dct:abstract']: val = util.getqattr(recobj, queryables[i]['dbcol']) if val is not None: etree.SubElement(record, util.nspath_eval(i, self.parent.context.namespaces)).text = val if self.parent.kvp['elementsetname'] == 'full': # add full elements for i in ['dc:date', 'dc:creator', \ 'dc:publisher', 'dc:contributor', 'dc:source', \ 'dc:language', 'dc:rights', 'dct:alternative']: val = util.getqattr(recobj, queryables[i]['dbcol']) if val: if isinstance(val, list): # if there are multiple publishers or contributors for v in val: etree.SubElement(record, util.nspath_eval(i, self.parent.context.namespaces)).text = str(v) else: etree.SubElement(record, util.nspath_eval(i, self.parent.context.namespaces)).text = val val = util.getqattr(recobj, queryables['dct:spatial']['dbcol']) if val: etree.SubElement(record, util.nspath_eval('dct:spatial', self.parent.context.namespaces), scheme='http://www.opengis.net/def/crs').text = val # always write out ows:BoundingBox bboxel = write_boundingbox(getattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:BoundingBox']), self.parent.context.namespaces) if bboxel is not None: record.append(bboxel) return record def _parse_constraint(self, element): ''' Parse csw:Constraint ''' query = {} tmp = element.find(util.nspath_eval('ogc:Filter', self.parent.context.namespaces)) if tmp is not None: LOGGER.debug('Filter constraint specified') try: query['type'] = 'filter' query['where'], query['values'] = fes1.parse(tmp, self.parent.repository.queryables['_all'], self.parent.repository.dbtype, self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) query['_dict'] = xml2dict(etree.tostring(tmp), self.parent.context.namespaces) except Exception as err: return 'Invalid Filter request: %s' % err tmp = element.find(util.nspath_eval('csw:CqlText', self.parent.context.namespaces)) if tmp is not None: LOGGER.debug('CQL specified: %s.', tmp.text) try: LOGGER.info('Transforming CQL into OGC Filter') query['type'] = 'filter' cql = cql2fes(tmp.text, self.parent.context.namespaces, fes_version='1.0') query['where'], query['values'] = fes1.parse(cql, self.parent.repository.queryables['_all'], self.parent.repository.dbtype, self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) query['_dict'] = xml2dict(etree.tostring(cql), self.parent.context.namespaces) except Exception as err: LOGGER.exception('Invalid CQL request: %s', tmp.text) LOGGER.exception('Error message: %s', err) return 'Invalid CQL request' return query def parse_postdata(self, postdata): ''' Parse POST XML ''' request = {} try: LOGGER.info('Parsing %s', postdata) doc = etree.fromstring(postdata, self.parent.context.parser) except Exception as err: errortext = \ 'Exception: document not well-formed.\nError: %s.' % str(err) LOGGER.exception(errortext) return errortext # if this is a SOAP request, get to SOAP-ENV:Body/csw:* if (doc.tag == util.nspath_eval('soapenv:Envelope', self.parent.context.namespaces)): LOGGER.debug('SOAP request specified') self.parent.soap = True doc = doc.find( util.nspath_eval('soapenv:Body', self.parent.context.namespaces)).xpath('child::*')[0] if (doc.tag in [util.nspath_eval('csw:Transaction', self.parent.context.namespaces), util.nspath_eval('csw:Harvest', self.parent.context.namespaces)]): schema = os.path.join(self.parent.config['server'].get('home'), 'core', 'schemas', 'ogc', 'csw', '2.0.2', 'CSW-publication.xsd') else: schema = os.path.join(self.parent.config['server'].get('home'), 'core', 'schemas', 'ogc', 'csw', '2.0.2', 'CSW-discovery.xsd') try: # it is virtually impossible to validate a csw:Transaction # csw:Insert|csw:Update (with single child) XML document. # Only validate non csw:Transaction XML if doc.find('.//%s' % util.nspath_eval('csw:Insert', self.parent.context.namespaces)) is None and \ len(doc.xpath('//csw:Update/child::*', namespaces=self.parent.context.namespaces)) == 0: LOGGER.info('Validating %s', postdata) schema = etree.XMLSchema(file=schema) parser = etree.XMLParser(schema=schema, resolve_entities=False) if hasattr(self.parent, 'soap') and self.parent.soap: # validate the body of the SOAP request doc = etree.fromstring(etree.tostring(doc), parser) else: # validate the request normally doc = etree.fromstring(postdata, parser) LOGGER.debug('Request is valid XML.') else: # parse Transaction without validation doc = etree.fromstring(postdata, self.parent.context.parser) except Exception as err: errortext = \ 'Exception: the document is not valid.\nError: %s' % str(err) LOGGER.exception(errortext) return errortext request['request'] = etree.QName(doc).localname LOGGER.debug('Request operation %s specified.', request['request']) tmp = doc.find('.').attrib.get('service') if tmp is not None: request['service'] = tmp tmp = doc.find('.').attrib.get('version') if tmp is not None: request['version'] = tmp tmp = doc.find('.//%s' % util.nspath_eval('ows:Version', self.parent.context.namespaces)) if tmp is not None: request['version'] = tmp.text tmp = doc.find('.').attrib.get('updateSequence') if tmp is not None: request['updatesequence'] = tmp # GetCapabilities if request['request'] == 'GetCapabilities': tmp = doc.find(util.nspath_eval('ows:Sections', self.parent.context.namespaces)) if tmp is not None: request['sections'] = ','.join([section.text for section in \ doc.findall(util.nspath_eval('ows:Sections/ows:Section', self.parent.context.namespaces))]) # DescribeRecord if request['request'] == 'DescribeRecord': request['typename'] = [typename.text for typename in \ doc.findall(util.nspath_eval('csw:TypeName', self.parent.context.namespaces))] tmp = doc.find('.').attrib.get('schemaLanguage') if tmp is not None: request['schemalanguage'] = tmp tmp = doc.find('.').attrib.get('outputFormat') if tmp is not None: request['outputformat'] = tmp # GetDomain if request['request'] == 'GetDomain': tmp = doc.find(util.nspath_eval('csw:ParameterName', self.parent.context.namespaces)) if tmp is not None: request['parametername'] = tmp.text tmp = doc.find(util.nspath_eval('csw:PropertyName', self.parent.context.namespaces)) if tmp is not None: request['propertyname'] = tmp.text # GetRecords if request['request'] == 'GetRecords': tmp = doc.find('.').attrib.get('outputSchema') request['outputschema'] = tmp if tmp is not None \ else self.parent.context.namespaces['csw'] tmp = doc.find('.').attrib.get('resultType') request['resulttype'] = tmp if tmp is not None else None tmp = doc.find('.').attrib.get('outputFormat') request['outputformat'] = tmp if tmp is not None \ else 'application/xml' tmp = doc.find('.').attrib.get('startPosition') request['startposition'] = tmp if tmp is not None else 1 tmp = doc.find('.').attrib.get('requestId') request['requestid'] = tmp if tmp is not None else None tmp = doc.find('.').attrib.get('maxRecords') if tmp is not None: request['maxrecords'] = tmp tmp = doc.find(util.nspath_eval('csw:DistributedSearch', self.parent.context.namespaces)) if tmp is not None: request['distributedsearch'] = True hopcount = tmp.attrib.get('hopCount') request['hopcount'] = int(hopcount) if hopcount is not None \ else 2 else: request['distributedsearch'] = False tmp = doc.find(util.nspath_eval('csw:ResponseHandler', self.parent.context.namespaces)) if tmp is not None: request['responsehandler'] = tmp.text tmp = doc.find(util.nspath_eval('csw:Query/csw:ElementSetName', self.parent.context.namespaces)) request['elementsetname'] = tmp.text if tmp is not None else None tmp = doc.find(util.nspath_eval( 'csw:Query', self.parent.context.namespaces)).attrib.get('typeNames') request['typenames'] = tmp.split() if tmp is not None \ else 'csw:Record' request['elementname'] = [elname.text for elname in \ doc.findall(util.nspath_eval('csw:Query/csw:ElementName', self.parent.context.namespaces))] request['constraint'] = {} tmp = doc.find(util.nspath_eval('csw:Query/csw:Constraint', self.parent.context.namespaces)) if tmp is not None: request['constraint'] = self._parse_constraint(tmp) if isinstance(request['constraint'], str): # parse error return 'Invalid Constraint: %s' % request['constraint'] else: LOGGER.debug('No csw:Constraint (ogc:Filter or csw:CqlText) \ specified') tmp = doc.find(util.nspath_eval('csw:Query/ogc:SortBy', self.parent.context.namespaces)) if tmp is not None: LOGGER.debug('Sorted query specified') request['sortby'] = {} try: elname = tmp.find(util.nspath_eval( 'ogc:SortProperty/ogc:PropertyName', self.parent.context.namespaces)).text request['sortby']['propertyname'] = \ self.parent.repository.queryables['_all'][elname]['dbcol'] if (elname.find('BoundingBox') != -1 or elname.find('Envelope') != -1): # it's a spatial sort request['sortby']['spatial'] = True except Exception as err: errortext = \ 'Invalid ogc:SortProperty/ogc:PropertyName: %s' % str(err) LOGGER.exception(errortext) return errortext tmp2 = tmp.find(util.nspath_eval( 'ogc:SortProperty/ogc:SortOrder', self.parent.context.namespaces)) request['sortby']['order'] = tmp2.text if tmp2 is not None \ else 'ASC' else: request['sortby'] = None # GetRecordById if request['request'] == 'GetRecordById': request['id'] = [id1.text for id1 in \ doc.findall(util.nspath_eval('csw:Id', self.parent.context.namespaces))] tmp = doc.find(util.nspath_eval('csw:ElementSetName', self.parent.context.namespaces)) request['elementsetname'] = tmp.text if tmp is not None \ else 'summary' tmp = doc.find('.').attrib.get('outputSchema') request['outputschema'] = tmp if tmp is not None \ else self.parent.context.namespaces['csw'] tmp = doc.find('.').attrib.get('outputFormat') if tmp is not None: request['outputformat'] = tmp # Transaction if request['request'] == 'Transaction': request['verboseresponse'] = True tmp = doc.find('.').attrib.get('verboseResponse') if tmp is not None: if tmp in ['false', '0']: request['verboseresponse'] = False tmp = doc.find('.').attrib.get('requestId') request['requestid'] = tmp if tmp is not None else None request['transactions'] = [] for ttype in \ doc.xpath('//csw:Insert', namespaces=self.parent.context.namespaces): tname = ttype.attrib.get('typeName') for mdrec in ttype.xpath('child::*'): xml = mdrec request['transactions'].append( {'type': 'insert', 'typename': tname, 'xml': xml}) for ttype in \ doc.xpath('//csw:Update', namespaces=self.parent.context.namespaces): child = ttype.xpath('child::*') update = {'type': 'update'} if len(child) == 1: # it's a wholesale update update['xml'] = child[0] else: # it's a RecordProperty with Constraint Update update['recordproperty'] = [] for recprop in ttype.findall( util.nspath_eval('csw:RecordProperty', self.parent.context.namespaces)): rpname = recprop.find(util.nspath_eval('csw:Name', self.parent.context.namespaces)).text rpvalue = recprop.find( util.nspath_eval('csw:Value', self.parent.context.namespaces)).text update['recordproperty'].append( {'name': rpname, 'value': rpvalue}) update['constraint'] = self._parse_constraint( ttype.find(util.nspath_eval('csw:Constraint', self.parent.context.namespaces))) request['transactions'].append(update) for ttype in \ doc.xpath('//csw:Delete', namespaces=self.parent.context.namespaces): tname = ttype.attrib.get('typeName') constraint = self._parse_constraint( ttype.find(util.nspath_eval('csw:Constraint', self.parent.context.namespaces))) if isinstance(constraint, str): # parse error return 'Invalid Constraint: %s' % constraint request['transactions'].append( {'type': 'delete', 'typename': tname, 'constraint': constraint}) # Harvest if request['request'] == 'Harvest': request['source'] = doc.find(util.nspath_eval('csw:Source', self.parent.context.namespaces)).text request['resourcetype'] = \ doc.find(util.nspath_eval('csw:ResourceType', self.parent.context.namespaces)).text tmp = doc.find(util.nspath_eval('csw:ResourceFormat', self.parent.context.namespaces)) if tmp is not None: request['resourceformat'] = tmp.text else: request['resourceformat'] = 'application/xml' tmp = doc.find(util.nspath_eval('csw:HarvestInterval', self.parent.context.namespaces)) if tmp is not None: request['harvestinterval'] = tmp.text tmp = doc.find(util.nspath_eval('csw:ResponseHandler', self.parent.context.namespaces)) if tmp is not None: request['responsehandler'] = tmp.text return request def _write_transactionsummary(self, inserted=0, updated=0, deleted=0): ''' Write csw:TransactionSummary construct ''' node = etree.Element(util.nspath_eval('csw:TransactionSummary', self.parent.context.namespaces)) if 'requestid' in self.parent.kvp and self.parent.kvp['requestid'] is not None: node.attrib['requestId'] = self.parent.kvp['requestid'] etree.SubElement(node, util.nspath_eval('csw:totalInserted', self.parent.context.namespaces)).text = str(inserted) etree.SubElement(node, util.nspath_eval('csw:totalUpdated', self.parent.context.namespaces)).text = str(updated) etree.SubElement(node, util.nspath_eval('csw:totalDeleted', self.parent.context.namespaces)).text = str(deleted) return node def _write_acknowledgement(self, root=True): ''' Generate csw:Acknowledgement ''' node = etree.Element(util.nspath_eval('csw:Acknowledgement', self.parent.context.namespaces), nsmap = self.parent.context.namespaces, timeStamp=util.get_today_and_now()) if root: node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = \ '%s %s/csw/2.0.2/CSW-discovery.xsd' % (self.parent.context.namespaces['csw'], \ self.parent.config['server'].get('ogc_schemas_base')) node1 = etree.SubElement(node, util.nspath_eval('csw:EchoedRequest', self.parent.context.namespaces)) if self.parent.requesttype == 'POST': node1.append(etree.fromstring(self.parent.request, self.parent.context.parser)) else: # GET node2 = etree.SubElement(node1, util.nspath_eval('ows:Get', self.parent.context.namespaces)) node2.text = self.parent.request if self.parent.asynchronous: etree.SubElement(node, util.nspath_eval('csw:RequestId', self.parent.context.namespaces)).text = self.parent.kvp['requestid'] return node def _write_verboseresponse(self, insertresults): ''' show insert result identifiers ''' insertresult = etree.Element(util.nspath_eval('csw:InsertResult', self.parent.context.namespaces)) for ir in insertresults: briefrec = etree.SubElement(insertresult, util.nspath_eval('csw:BriefRecord', self.parent.context.namespaces)) etree.SubElement(briefrec, util.nspath_eval('dc:identifier', self.parent.context.namespaces)).text = ir['identifier'] etree.SubElement(briefrec, util.nspath_eval('dc:title', self.parent.context.namespaces)).text = ir['title'] return insertresult def exceptionreport(self, code, locator, text): ''' Generate ExceptionReport ''' self.parent.exception = True self.parent.status = 'OK' try: language = self.parent.config['server'].get('language') ogc_schemas_base = self.parent.config['server'].get('ogc_schemas_base') except Exception: LOGGER.debug('Dropping to default language and OGC schemas base') language = 'en-US' ogc_schemas_base = self.parent.context.ogc_schemas_base node = etree.Element(util.nspath_eval('ows:ExceptionReport', self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='1.2.0', language=language) node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = \ '%s %s/ows/1.0.0/owsExceptionReport.xsd' % \ (self.parent.context.namespaces['ows'], ogc_schemas_base) exception = etree.SubElement(node, util.nspath_eval('ows:Exception', self.parent.context.namespaces), exceptionCode=code, locator=locator) exception_text = etree.SubElement(exception, util.nspath_eval('ows:ExceptionText', self.parent.context.namespaces)) try: exception_text.text = text except ValueError as err: exception_text.text = repr(text) return node def write_boundingbox(bbox, nsmap): ''' Generate ows:BoundingBox ''' if bbox is not None: try: bbox2 = util.wkt2geom(bbox) except Exception as err: LOGGER.debug(f'Geometry parsing error: {err}') return None if len(bbox2) == 4: boundingbox = etree.Element(util.nspath_eval('ows:BoundingBox', nsmap), crs='urn:x-ogc:def:crs:EPSG:6.11:4326', dimensions='2') etree.SubElement(boundingbox, util.nspath_eval('ows:LowerCorner', nsmap)).text = '%s %s' % (bbox2[1], bbox2[0]) etree.SubElement(boundingbox, util.nspath_eval('ows:UpperCorner', nsmap)).text = '%s %s' % (bbox2[3], bbox2[2]) return boundingbox else: return None else: return None ================================================ FILE: pycsw/ogc/csw/csw3.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import os from time import time from pycsw.core.etree import etree from pycsw.ogc.csw.cql import cql2fes from pycsw import opensearch from pycsw.core import metadata, util from pycsw.core.formats.fmt_json import xml2dict from pycsw.ogc.fes import fes1, fes2 import logging LOGGER = logging.getLogger(__name__) class Csw3(object): ''' CSW 3.x server ''' def __init__(self, server_csw): ''' Initialize CSW3 ''' self.parent = server_csw self.version = '3.0.0' def getcapabilities(self): ''' Handle GetCapabilities request ''' serviceidentification = True serviceprovider = True operationsmetadata = True filtercaps = False languages = False # validate acceptformats LOGGER.info('Validating ows20:AcceptFormats') LOGGER.debug(self.parent.context.model['operations']['GetCapabilities']['parameters']['acceptFormats']['values']) if 'acceptformats' in self.parent.kvp: bfound = False for fmt in self.parent.kvp['acceptformats'].split(','): if fmt in self.parent.context.model['operations']['GetCapabilities']['parameters']['acceptFormats']['values']: self.parent.mimetype = fmt bfound = True break if not bfound: return self.exceptionreport('InvalidParameterValue', 'acceptformats', 'Invalid acceptFormats parameter value: %s' % self.parent.kvp['acceptformats']) if 'sections' in self.parent.kvp and self.parent.kvp['sections'] != '': serviceidentification = False serviceprovider = False operationsmetadata = False for section in self.parent.kvp['sections'].split(','): if section == 'ServiceIdentification': serviceidentification = True if section == 'ServiceProvider': serviceprovider = True if section == 'OperationsMetadata': operationsmetadata = True if section == 'All': serviceidentification = True serviceprovider = True operationsmetadata = True filtercaps = True languages = True else: filtercaps = True languages = True # check extra parameters that may be def'd by profiles if self.parent.profiles is not None: for prof in self.parent.profiles['loaded'].keys(): result = \ self.parent.profiles['loaded'][prof].check_parameters(self.parent.kvp) if result is not None: return self.exceptionreport(result['code'], result['locator'], result['text']) # @updateSequence: get latest update to repository try: updatesequence = \ util.get_time_iso2unix(self.parent.repository.query_insert()) except Exception as err: LOGGER.debug(f'Cannot set updatesequence: {err}') updatesequence = None node = etree.Element(util.nspath_eval('csw30:Capabilities', self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='3.0.0', updateSequence=str(updatesequence)) if 'updatesequence' in self.parent.kvp: if int(self.parent.kvp['updatesequence']) == updatesequence: return node elif int(self.parent.kvp['updatesequence']) > updatesequence: return self.exceptionreport('InvalidUpdateSequence', 'updatesequence', 'outputsequence specified (%s) is higher than server\'s \ updatesequence (%s)' % (self.parent.kvp['updatesequence'], updatesequence)) node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = '%s %s/cat/csw/3.0/cswGetCapabilities.xsd' % \ (self.parent.context.namespaces['csw30'], self.parent.config['server'].get('ogc_schemas_base')) metadata_main = self.parent.config['metadata'] if serviceidentification: LOGGER.info('Writing section ServiceIdentification') serviceidentification = etree.SubElement(node, \ util.nspath_eval('ows20:ServiceIdentification', self.parent.context.namespaces)) etree.SubElement(serviceidentification, util.nspath_eval('ows20:Title', self.parent.context.namespaces)).text = \ metadata_main['identification'].get('title', 'missing') etree.SubElement(serviceidentification, util.nspath_eval('ows20:Abstract', self.parent.context.namespaces)).text = \ metadata_main['identification'].get('description', 'missing') keywords = etree.SubElement(serviceidentification, util.nspath_eval('ows20:Keywords', self.parent.context.namespaces)) for k in metadata_main['identification']['keywords']: etree.SubElement( keywords, util.nspath_eval('ows20:Keyword', self.parent.context.namespaces)).text = k etree.SubElement(keywords, util.nspath_eval('ows20:Type', self.parent.context.namespaces), codeSpace='ISOTC211/19115').text = \ metadata_main['identification'].get('keywords_type', 'missing') etree.SubElement(serviceidentification, util.nspath_eval('ows20:ServiceType', self.parent.context.namespaces), codeSpace='OGC').text = 'CSW' for stv in self.parent.context.model['parameters']['version']['values']: etree.SubElement(serviceidentification, util.nspath_eval('ows20:ServiceTypeVersion', self.parent.context.namespaces)).text = stv if self.parent.profiles is not None: for prof in self.parent.profiles['loaded'].keys(): prof_name = self.parent.profiles['loaded'][prof].name prof_val = self.parent.profiles['loaded'][prof].namespaces[prof_name] etree.SubElement(serviceidentification, util.nspath_eval('ows20:Profile', self.parent.context.namespaces)).text = prof_val etree.SubElement(serviceidentification, util.nspath_eval('ows20:Fees', self.parent.context.namespaces)).text = \ metadata_main['identification'].get('fees', 'missing') etree.SubElement(serviceidentification, util.nspath_eval('ows20:AccessConstraints', self.parent.context.namespaces)).text = \ metadata_main['identification'].get('accessconstraints', 'missing') if serviceprovider: LOGGER.info('Writing section ServiceProvider') serviceprovider = etree.SubElement(node, util.nspath_eval('ows20:ServiceProvider', self.parent.context.namespaces)) etree.SubElement(serviceprovider, util.nspath_eval('ows20:ProviderName', self.parent.context.namespaces)).text = \ metadata_main['provider'].get('name', 'missing') providersite = etree.SubElement(serviceprovider, util.nspath_eval('ows20:ProviderSite', self.parent.context.namespaces)) providersite.attrib[util.nspath_eval('xlink:type', self.parent.context.namespaces)] = 'simple' providersite.attrib[util.nspath_eval('xlink:href', self.parent.context.namespaces)] = \ metadata_main['provider'].get('url', 'missing') servicecontact = etree.SubElement(serviceprovider, util.nspath_eval('ows20:ServiceContact', self.parent.context.namespaces)) etree.SubElement(servicecontact, util.nspath_eval('ows20:IndividualName', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('name', 'missing') etree.SubElement(servicecontact, util.nspath_eval('ows20:PositionName', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('position', 'missing') contactinfo = etree.SubElement(servicecontact, util.nspath_eval('ows20:ContactInfo', self.parent.context.namespaces)) phone = etree.SubElement(contactinfo, util.nspath_eval('ows20:Phone', self.parent.context.namespaces)) etree.SubElement(phone, util.nspath_eval('ows20:Voice', self.parent.context.namespaces)).text = \ str(metadata_main['contact'].get('phone', 'missing')) etree.SubElement(phone, util.nspath_eval('ows20:Facsimile', self.parent.context.namespaces)).text = \ str(metadata_main['contact'].get('fax', 'missing')) address = etree.SubElement(contactinfo, util.nspath_eval('ows20:Address', self.parent.context.namespaces)) etree.SubElement(address, util.nspath_eval('ows20:DeliveryPoint', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('address', 'missing') etree.SubElement(address, util.nspath_eval('ows20:City', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('city', 'missing') etree.SubElement(address, util.nspath_eval('ows20:AdministrativeArea', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('stateorprovince', 'missing') etree.SubElement(address, util.nspath_eval('ows20:PostalCode', self.parent.context.namespaces)).text = \ str(metadata_main['contact'].get('postalcode', 'missing')) etree.SubElement(address, util.nspath_eval('ows20:Country', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('country', 'missing') etree.SubElement(address, util.nspath_eval('ows20:ElectronicMailAddress', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('email', 'missing') url = etree.SubElement(contactinfo, util.nspath_eval('ows20:OnlineResource', self.parent.context.namespaces)) url.attrib[util.nspath_eval('xlink:type', self.parent.context.namespaces)] = 'simple' url.attrib[util.nspath_eval('xlink:href', self.parent.context.namespaces)] = \ metadata_main['contact'].get('url', 'missing') etree.SubElement(contactinfo, util.nspath_eval('ows20:HoursOfService', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('hours', 'missing') etree.SubElement(contactinfo, util.nspath_eval('ows20:ContactInstructions', self.parent.context.namespaces)).text = \ metadata_main['contact'].get('instructions', 'missing') etree.SubElement(servicecontact, util.nspath_eval('ows20:Role', self.parent.context.namespaces), codeSpace='ISOTC211/19115').text = \ metadata_main['contact'].get('role', 'missing') if operationsmetadata: LOGGER.info('Writing section OperationsMetadata') operationsmetadata = etree.SubElement(node, util.nspath_eval('ows20:OperationsMetadata', self.parent.context.namespaces)) for operation in self.parent.context.model['operations_order']: oper = etree.SubElement(operationsmetadata, util.nspath_eval('ows20:Operation', self.parent.context.namespaces), name=operation) dcp = etree.SubElement(oper, util.nspath_eval('ows20:DCP', self.parent.context.namespaces)) http = etree.SubElement(dcp, util.nspath_eval('ows20:HTTP', self.parent.context.namespaces)) if self.parent.context.model['operations'][operation]['methods']['get']: get = etree.SubElement(http, util.nspath_eval('ows20:Get', self.parent.context.namespaces)) get.attrib[util.nspath_eval('xlink:type',\ self.parent.context.namespaces)] = 'simple' get.attrib[util.nspath_eval('xlink:href',\ self.parent.context.namespaces)] = self.parent.config['server'].get('url') if self.parent.context.model['operations'][operation]['methods']['post']: post = etree.SubElement(http, util.nspath_eval('ows20:Post', self.parent.context.namespaces)) post.attrib[util.nspath_eval('xlink:type', self.parent.context.namespaces)] = 'simple' post.attrib[util.nspath_eval('xlink:href', self.parent.context.namespaces)] = \ self.parent.config['server'].get('url') for parameter in \ sorted(self.parent.context.model['operations'][operation]['parameters']): param = etree.SubElement(oper, util.nspath_eval('ows20:Parameter', self.parent.context.namespaces), name=parameter) param.append(self._write_allowed_values(self.parent.context.model['operations'][operation]['parameters'][parameter]['values'])) if operation == 'GetRecords': # advertise queryables, MaxRecordDefault for qbl in sorted(self.parent.repository.queryables.keys()): if qbl not in ['_all', 'SupportedDublinCoreQueryables']: param = etree.SubElement(oper, util.nspath_eval('ows20:Constraint', self.parent.context.namespaces), name=qbl) param.append(self._write_allowed_values(self.parent.repository.queryables[qbl])) if self.parent.profiles is not None: for con in sorted(self.parent.context.model[\ 'operations']['GetRecords']['constraints'].keys()): param = etree.SubElement(oper, util.nspath_eval('ows20:Constraint', self.parent.context.namespaces), name=con) param.append(self._write_allowed_values(self.parent.context.model['operations']['GetRecords']['constraints'][con]['values'])) extra_constraints = { 'OpenSearchDescriptionDocument': ['%s?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities' % self.parent.config['server'].get('url')], 'MaxRecordDefault': self.parent.context.model['constraints']['MaxRecordDefault']['values'], } for key in sorted(extra_constraints.keys()): param = etree.SubElement(oper, util.nspath_eval('ows20:Constraint', self.parent.context.namespaces), name=key) param.append(self._write_allowed_values(extra_constraints[key])) if 'FederatedCatalogues' in self.parent.context.model['constraints']: param = etree.SubElement(oper, util.nspath_eval('ows20:Constraint', self.parent.context.namespaces), name='FederatedCatalogues') param.append(self._write_allowed_values(self.parent.context.model['constraints']['FederatedCatalogues']['values'])) for parameter in sorted(self.parent.context.model['parameters'].keys()): param = etree.SubElement(operationsmetadata, util.nspath_eval('ows20:Parameter', self.parent.context.namespaces), name=parameter) param.append(self._write_allowed_values(self.parent.context.model['parameters'][parameter]['values'])) for qbl in sorted(self.parent.repository.queryables.keys()): if qbl == 'SupportedDublinCoreQueryables': param = etree.SubElement(operationsmetadata, util.nspath_eval('ows20:Constraint', self.parent.context.namespaces), name='CoreQueryables') param.append(self._write_allowed_values(self.parent.repository.queryables[qbl])) for constraint in sorted(self.parent.context.model['constraints'].keys()): param = etree.SubElement(operationsmetadata, util.nspath_eval('ows20:Constraint', self.parent.context.namespaces), name=constraint) param.append(self._write_allowed_values(self.parent.context.model['constraints'][constraint]['values'])) if self.parent.profiles is not None: for prof in self.parent.profiles['loaded'].keys(): ecnode = \ self.parent.profiles['loaded'][prof].get_extendedcapabilities() if ecnode is not None: operationsmetadata.append(ecnode) if languages: LOGGER.info('Writing section ows:Languages') langs = etree.SubElement(node, util.nspath_eval('ows20:Languages', self.parent.context.namespaces)) etree.SubElement(langs, util.nspath_eval('ows20:Language', self.parent.context.namespaces)).text = self.parent.language['639_code'] if not filtercaps: return node # always write out Filter_Capabilities LOGGER.info('Writing section Filter_Capabilities') fltcaps = etree.SubElement(node, util.nspath_eval('fes20:Filter_Capabilities', self.parent.context.namespaces)) conformance = etree.SubElement(fltcaps, util.nspath_eval('fes20:Conformance', self.parent.context.namespaces)) for value in fes2.MODEL['Conformance']['values']: constraint = etree.SubElement(conformance, util.nspath_eval('fes20:Constraint', self.parent.context.namespaces), name=value) etree.SubElement(constraint, util.nspath_eval('ows11:NoValues', self.parent.context.namespaces)) etree.SubElement(constraint, util.nspath_eval('ows11:DefaultValue', self.parent.context.namespaces)).text = 'TRUE' idcaps = etree.SubElement(fltcaps, util.nspath_eval('fes20:Id_Capabilities', self.parent.context.namespaces)) for idcap in fes2.MODEL['Ids']['values']: etree.SubElement(idcaps, util.nspath_eval('fes20:ResourceIdentifier', self.parent.context.namespaces), name=idcap) scalarcaps = etree.SubElement(fltcaps, util.nspath_eval('fes20:Scalar_Capabilities', self.parent.context.namespaces)) etree.SubElement(scalarcaps, util.nspath_eval('fes20:LogicalOperators', self.parent.context.namespaces)) cmpops = etree.SubElement(scalarcaps, util.nspath_eval('fes20:ComparisonOperators', self.parent.context.namespaces)) for cmpop in sorted(fes2.MODEL['ComparisonOperators'].keys()): etree.SubElement(cmpops, util.nspath_eval('fes20:ComparisonOperator', self.parent.context.namespaces), name=fes2.MODEL['ComparisonOperators'][cmpop]['opname']) spatialcaps = etree.SubElement(fltcaps, util.nspath_eval('fes20:Spatial_Capabilities', self.parent.context.namespaces)) geomops = etree.SubElement(spatialcaps, util.nspath_eval('fes20:GeometryOperands', self.parent.context.namespaces)) for geomtype in \ fes2.MODEL['GeometryOperands']['values']: etree.SubElement(geomops, util.nspath_eval('fes20:GeometryOperand', self.parent.context.namespaces), name=geomtype) spatialops = etree.SubElement(spatialcaps, util.nspath_eval('fes20:SpatialOperators', self.parent.context.namespaces)) for spatial_comparison in \ fes2.MODEL['SpatialOperators']['values']: etree.SubElement(spatialops, util.nspath_eval('fes20:SpatialOperator', self.parent.context.namespaces), name=spatial_comparison) functions = etree.SubElement(fltcaps, util.nspath_eval('fes20:Functions', self.parent.context.namespaces)) for fnop in sorted(fes2.MODEL['Functions'].keys()): fn = etree.SubElement(functions, util.nspath_eval('fes20:Function', self.parent.context.namespaces), name=fnop) etree.SubElement(fn, util.nspath_eval('fes20:Returns', self.parent.context.namespaces)).text = \ fes2.MODEL['Functions'][fnop]['returns'] return node def getdomain(self): ''' Handle GetDomain request ''' if ('parametername' not in self.parent.kvp and 'valuereference' not in self.parent.kvp): return self.exceptionreport('MissingParameterValue', 'parametername', 'Missing value. \ One of valuereference or parametername must be specified') node = etree.Element(util.nspath_eval('csw30:GetDomainResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces) node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = '%s %s/cat/csw/3.0/cswGetDomain.xsd' % \ (self.parent.context.namespaces['csw30'], self.parent.config['server'].get('ogc_schemas_base')) if 'parametername' in self.parent.kvp: for pname in self.parent.kvp['parametername'].split(','): LOGGER.info('Parsing parametername %s', pname) domainvalue = etree.SubElement(node, util.nspath_eval('csw30:DomainValues', self.parent.context.namespaces), type='csw30:Record', resultType='available') etree.SubElement(domainvalue, util.nspath_eval('csw30:ParameterName', self.parent.context.namespaces)).text = pname try: operation, parameter = pname.split('.') except Exception as err: LOGGER.debug(f'pname2 not found: {err}') return node if (operation in self.parent.context.model['operations'] and parameter in self.parent.context.model['operations'][operation]['parameters']): listofvalues = etree.SubElement(domainvalue, util.nspath_eval('csw30:ListOfValues', self.parent.context.namespaces)) for val in \ sorted(self.parent.context.model['operations'][operation]\ ['parameters'][parameter]['values']): etree.SubElement(listofvalues, util.nspath_eval('csw30:Value', self.parent.context.namespaces)).text = val if 'valuereference' in self.parent.kvp: for pname in self.parent.kvp['valuereference'].split(','): LOGGER.info('Parsing valuereference %s', pname) if pname.find('/') == 0: # it's an XPath pname2 = pname else: # it's a core queryable, map to internal typename model try: pname2 = self.parent.repository.queryables['_all'][pname]['dbcol'] except Exception as err: LOGGER.debug(f'pname2 not found: {err}') # decipher typename dvtype = None if self.parent.profiles is not None: for prof in self.parent.profiles['loaded'].keys(): for prefix in self.parent.profiles['loaded'][prof].prefixes: if pname2.find(prefix) != -1: dvtype = self.parent.profiles['loaded'][prof].typename break if not dvtype: dvtype = 'csw30:Record' domainvalue = etree.SubElement(node, util.nspath_eval('csw30:DomainValues', self.parent.context.namespaces), type=dvtype, resultType='available') etree.SubElement(domainvalue, util.nspath_eval('csw30:ValueReference', self.parent.context.namespaces)).text = pname try: LOGGER.debug( 'Querying repository property %s, typename %s, \ domainquerytype %s', pname2, dvtype, self.parent.domainquerytype) results = self.parent.repository.query_domain( pname2, dvtype, self.parent.domainquerytype, True) LOGGER.debug('Results: %d', len(results)) if self.parent.domainquerytype == 'range': rangeofvalues = etree.SubElement(domainvalue, util.nspath_eval('csw30:RangeOfValues', self.parent.context.namespaces)) etree.SubElement(rangeofvalues, util.nspath_eval('csw30:MinValue', self.parent.context.namespaces)).text = results[0][0] etree.SubElement(rangeofvalues, util.nspath_eval('csw30:MaxValue', self.parent.context.namespaces)).text = results[0][1] else: listofvalues = etree.SubElement(domainvalue, util.nspath_eval('csw30:ListOfValues', self.parent.context.namespaces)) for result in results: LOGGER.debug(str(result)) if (result is not None and result[0] is not None): # drop null values etree.SubElement(listofvalues, util.nspath_eval('csw30:Value', self.parent.context.namespaces), count=str(result[1])).text = result[0] except Exception as err: # here we fail silently back to the client because # CSW tells us to LOGGER.exception('No results for propertyname') return node def getrecords(self): ''' Handle GetRecords request ''' timestamp = util.get_today_and_now() if ('elementsetname' not in self.parent.kvp and 'elementname' not in self.parent.kvp): if self.parent.requesttype == 'GET': LOGGER.debug(self.parent.requesttype) self.parent.kvp['elementsetname'] = 'summary' else: # mutually exclusive required return self.exceptionreport('MissingParameterValue', 'elementsetname', 'Missing one of ElementSetName or ElementName parameter(s)') if 'elementsetname' in self.parent.kvp and 'elementname' in self.parent.kvp and self.parent.kvp['elementname']: # mutually exclusive required return self.exceptionreport('NoApplicableCode', 'elementsetname', 'Only ONE of ElementSetName or ElementName parameter(s) is permitted') if 'elementsetname' not in self.parent.kvp: self.parent.kvp['elementsetname'] = 'summary' if 'outputschema' not in self.parent.kvp: self.parent.kvp['outputschema'] = self.parent.context.namespaces['csw30'] LOGGER.debug(self.parent.context.model['operations']['GetRecords']['parameters']['outputSchema']['values']) if (self.parent.kvp['outputschema'] not in self.parent.context.model['operations'] ['GetRecords']['parameters']['outputSchema']['values']): return self.exceptionreport('InvalidParameterValue', 'outputschema', 'Invalid outputSchema parameter value: %s' % self.parent.kvp['outputschema']) if 'outputformat' not in self.parent.kvp: self.parent.kvp['outputformat'] = 'application/xml' if 'HTTP_ACCEPT' in self.parent.environ: LOGGER.debug('Detected HTTP Accept header: %s', self.parent.environ['HTTP_ACCEPT']) formats_match = False if 'outputformat' in self.parent.kvp: LOGGER.debug(self.parent.kvp['outputformat']) for ofmt in self.parent.environ['HTTP_ACCEPT'].split(','): LOGGER.info('Comparing %s and %s', ofmt, self.parent.kvp['outputformat']) if ofmt.split('/')[0] in self.parent.kvp['outputformat']: LOGGER.debug('Found output match') formats_match = True if not formats_match and self.parent.environ['HTTP_ACCEPT'] != '*/*': return self.exceptionreport('InvalidParameterValue', 'outputformat', 'HTTP Accept header (%s) and outputformat (%s) must agree' % (self.parent.environ['HTTP_ACCEPT'], self.parent.kvp['outputformat'])) else: for ofmt in self.parent.environ['HTTP_ACCEPT'].split(','): if ofmt in self.parent.context.model['operations']['GetRecords']['parameters']['outputFormat']['values']: self.parent.kvp['outputformat'] = ofmt break if (self.parent.kvp['outputformat'] not in self.parent.context.model['operations'] ['GetRecords']['parameters']['outputFormat']['values']): return self.exceptionreport('InvalidParameterValue', 'outputformat', 'Invalid outputFormat parameter value: %s' % self.parent.kvp['outputformat']) if 'outputformat' in self.parent.kvp: LOGGER.info('Setting content type') self.parent.contenttype = self.parent.kvp['outputformat'] if self.parent.kvp['outputformat'] == 'application/atom+xml': self.parent.kvp['outputschema'] = self.parent.context.namespaces['atom'] self.parent.mode = 'opensearch' if (('elementname' not in self.parent.kvp or len(self.parent.kvp['elementname']) == 0) and self.parent.kvp['elementsetname'] not in self.parent.context.model['operations']['GetRecords']['parameters'] ['ElementSetName']['values']): return self.exceptionreport('InvalidParameterValue', 'elementsetname', 'Invalid ElementSetName parameter value: %s' % self.parent.kvp['elementsetname']) if 'typenames' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'typenames', 'Missing typenames parameter') if ('typenames' in self.parent.kvp and self.parent.requesttype == 'GET'): # passed via GET #self.parent.kvp['typenames'] = self.parent.kvp['typenames'].split(',') self.parent.kvp['typenames'] = ['csw:Record' if x=='Record' else x for x in self.parent.kvp['typenames'].split(',')] if 'namespace' in self.parent.kvp: LOGGER.info('resolving KVP namespace bindings') LOGGER.debug(self.parent.kvp['typenames']) self.parent.kvp['typenames'] = self.resolve_nsmap(self.parent.kvp['typenames']) if 'elementname' in self.parent.kvp: LOGGER.debug(self.parent.kvp['elementname']) self.parent.kvp['elementname'] = self.resolve_nsmap(self.parent.kvp['elementname'].split(',')) if 'typenames' in self.parent.kvp: for tname in self.parent.kvp['typenames']: #if tname == 'Record': # tname = 'csw:Record' if (tname not in self.parent.context.model['operations']['GetRecords'] ['parameters']['typeNames']['values']): return self.exceptionreport('InvalidParameterValue', 'typenames', 'Invalid typeNames parameter value: %s' % tname) # check elementname's if 'elementname' in self.parent.kvp: for ename in self.parent.kvp['elementname']: if ename not in self.parent.repository.queryables['_all']: return self.exceptionreport('InvalidParameterValue', 'elementname', 'Invalid ElementName parameter value: %s' % ename) maxrecords_cfg = int(self.parent.config['server'].get('maxrecords', -1)) if 'maxrecords' in self.parent.kvp and self.parent.kvp['maxrecords'] == 'unlimited': LOGGER.debug('Detected maxrecords=unlimited') self.parent.kvp.pop('maxrecords') if 'maxrecords' not in self.parent.kvp: # not specified by client if maxrecords_cfg > -1: # specified in config self.parent.kvp['maxrecords'] = maxrecords_cfg else: # spec default self.parent.kvp['maxrecords'] = 10 else: # specified by client if self.parent.kvp['maxrecords'] == '': self.parent.kvp['maxrecords'] = 10 if maxrecords_cfg > -1: # set in config if int(self.parent.kvp['maxrecords']) > maxrecords_cfg: self.parent.kvp['maxrecords'] = maxrecords_cfg if any(x in opensearch.QUERY_PARAMETERS for x in self.parent.kvp): LOGGER.debug('OpenSearch Geo/Time parameters detected.') self.parent.kvp['constraintlanguage'] = 'FILTER' try: tmp_filter = opensearch.kvp2filterxml(self.parent.kvp, self.parent.context, self.parent.profiles, fes_version='2.0') except Exception as err: return self.exceptionreport('InvalidParameterValue', 'bbox', str(err)) if tmp_filter != "": self.parent.kvp['constraint'] = tmp_filter LOGGER.debug('OpenSearch Geo/Time parameters to Filter: %s.', self.parent.kvp['constraint']) if self.parent.requesttype == 'GET': if 'constraint' in self.parent.kvp: # GET request LOGGER.debug('csw:Constraint passed over HTTP GET.') if 'constraintlanguage' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'constraintlanguage', 'constraintlanguage required when constraint specified') if (self.parent.kvp['constraintlanguage'] not in self.parent.context.model['operations']['GetRecords']['parameters'] ['CONSTRAINTLANGUAGE']['values']): return self.exceptionreport('InvalidParameterValue', 'constraintlanguage', 'Invalid constraintlanguage: %s' % self.parent.kvp['constraintlanguage']) if self.parent.kvp['constraintlanguage'] == 'CQL_TEXT': tmp = self.parent.kvp['constraint'] try: LOGGER.info('Transforming CQL into fes1') LOGGER.debug('CQL: %s', tmp) self.parent.kvp['constraint'] = {} self.parent.kvp['constraint']['type'] = 'filter' cql = cql2fes(tmp, self.parent.context.namespaces, fes_version='1.0') self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = fes1.parse(cql, self.parent.repository.queryables['_all'], self.parent.repository.dbtype, self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) self.parent.kvp['constraint']['_dict'] = xml2dict(etree.tostring(cql), self.parent.context.namespaces) except Exception as err: LOGGER.exception('Invalid CQL query %s', tmp) return self.exceptionreport('InvalidParameterValue', 'constraint', 'Invalid Filter syntax') elif self.parent.kvp['constraintlanguage'] == 'FILTER': # validate filter XML try: schema = os.path.join(self.parent.config['server'].get('home'), 'core', 'schemas', 'ogc', 'filter', '2.0', '_wrapper.xsd') LOGGER.info('Validating Filter %s.', self.parent.kvp['constraint']) schema = etree.XMLSchema(file=schema) parser = etree.XMLParser(schema=schema, resolve_entities=False) doc = etree.fromstring(self.parent.kvp['constraint'], parser) LOGGER.debug('Filter is valid XML.') self.parent.kvp['constraint'] = {} self.parent.kvp['constraint']['type'] = 'filter' self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = \ fes2.parse(doc, self.parent.repository.queryables['_all'], self.parent.repository.dbtype, self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) self.parent.kvp['constraint']['_dict'] = xml2dict(etree.tostring(doc), self.parent.context.namespaces) except Exception as err: errortext = \ 'Exception: document not valid.\nError: %s' % str(err) LOGGER.exception(errortext) return self.exceptionreport('InvalidParameterValue', 'bbox', 'Invalid Filter query: %s' % errortext) else: self.parent.kvp['constraint'] = {} if 'sortby' not in self.parent.kvp: self.parent.kvp['sortby'] = None elif 'sortby' in self.parent.kvp and self.parent.requesttype == 'GET': LOGGER.debug('Sorted query specified') tmp = self.parent.kvp['sortby'] self.parent.kvp['sortby'] = {} try: name, order = tmp.rsplit(':', 1) except Exception: return self.exceptionreport('InvalidParameterValue', 'sortby', 'Invalid SortBy value: must be in the format\ propertyname:A or propertyname:D') try: self.parent.kvp['sortby']['propertyname'] = \ self.parent.repository.queryables['_all'][name]['dbcol'] if name.find('BoundingBox') != -1 or name.find('Envelope') != -1: # it's a spatial sort self.parent.kvp['sortby']['spatial'] = True except Exception as err: return self.exceptionreport('InvalidParameterValue', 'sortby', 'Invalid SortBy propertyname: %s' % name) if order not in ['A', 'D']: return self.exceptionreport('InvalidParameterValue', 'sortby', 'Invalid SortBy value: sort order must be "A" or "D"') if order == 'D': self.parent.kvp['sortby']['order'] = 'DESC' else: self.parent.kvp['sortby']['order'] = 'ASC' if 'startposition' not in self.parent.kvp or not self.parent.kvp['startposition']: self.parent.kvp['startposition'] = 1 if 'recordids' in self.parent.kvp and self.parent.kvp['recordids'] != '': # query repository LOGGER.info('Querying repository with RECORD ids: %s', self.parent.kvp['recordids']) results = self.parent.repository.query_ids(self.parent.kvp['recordids'].split(',')) matched = str(len(results)) if len(results) == 0: return self.exceptionreport('NotFound', 'recordids', 'No records found for \'%s\'' % self.parent.kvp['recordids']) else: # query repository LOGGER.info('Querying repository with constraint: %s,\ sortby: %s, typenames: %s, maxrecords: %s, startposition: %s.', self.parent.kvp['constraint'], self.parent.kvp['sortby'], self.parent.kvp['typenames'], self.parent.kvp['maxrecords'], self.parent.kvp['startposition']) try: matched, results = self.parent.repository.query( constraint=self.parent.kvp['constraint'], sortby=self.parent.kvp['sortby'], typenames=self.parent.kvp['typenames'], maxrecords=self.parent.kvp['maxrecords'], startposition=int(self.parent.kvp['startposition'])-1) except Exception as err: LOGGER.exception('Invalid query syntax. Query: %s', self.parent.kvp['constraint']) LOGGER.exception('Invalid query syntax. Result: %s', err) return self.exceptionreport('InvalidParameterValue', 'constraint', 'Invalid query syntax') if int(matched) == 0: returned = nextrecord = '0' elif int(self.parent.kvp['maxrecords']) == 0: returned = nextrecord = '0' elif int(matched) < int(self.parent.kvp['startposition']): returned = nextrecord = '0' elif int(matched) <= int(self.parent.kvp['startposition']) + int(self.parent.kvp['maxrecords']) - 1: returned = str(int(matched) - int(self.parent.kvp['startposition']) + 1) nextrecord = '0' else: returned = str(self.parent.kvp['maxrecords']) nextrecord = str(int(self.parent.kvp['startposition']) + int(self.parent.kvp['maxrecords'])) LOGGER.debug('Results: matched: %s, returned: %s, next: %s', matched, returned, nextrecord) node = etree.Element(util.nspath_eval('csw30:GetRecordsResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='3.0.0') node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = \ '%s %s/cat/csw/3.0/cswGetRecords.xsd' % \ (self.parent.context.namespaces['csw30'], self.parent.config['server'].get('ogc_schemas_base')) if 'requestid' in self.parent.kvp and self.parent.kvp['requestid'] is not None: etree.SubElement(node, util.nspath_eval('csw:RequestId', self.parent.context.namespaces)).text = self.parent.kvp['requestid'] etree.SubElement(node, util.nspath_eval('csw30:SearchStatus', self.parent.context.namespaces), timestamp=timestamp) #if 'where' not in self.parent.kvp['constraint'] and \ #self.parent.kvp['resulttype'] is None: # returned = '0' searchresults = etree.SubElement(node, util.nspath_eval('csw30:SearchResults', self.parent.context.namespaces), numberOfRecordsMatched=matched, numberOfRecordsReturned=returned, nextRecord=nextrecord, recordSchema=self.parent.kvp['outputschema'], expires=timestamp, status=get_resultset_status(matched, nextrecord)) if self.parent.kvp['elementsetname'] is not None: searchresults.attrib['elementSet'] = self.parent.kvp['elementsetname'] #if 'where' not in self.parent.kvp['constraint'] \ #and self.parent.kvp['resulttype'] is None: # LOGGER.debug('Empty result set returned') # return node if results is not None: if len(results) < int(self.parent.kvp['maxrecords']): max1 = len(results) else: max1 = int(self.parent.kvp['startposition']) + (int(self.parent.kvp['maxrecords'])-1) LOGGER.info('Presenting records %s - %s', self.parent.kvp['startposition'], max1) for res in results: node_ = None if self.parent.xslts: try: node_ = self.parent._render_xslt(res) except Exception as err: self.parent.response = self.exceptionreport( 'NoApplicableCode', 'service', 'XSLT transformation failed. Check server logs for errors') return self.parent.response if node_ is not None: searchresults.append(node_) else: try: if (self.parent.kvp['outputschema'] == 'http://www.opengis.net/cat/csw/3.0' and ('csw:Record' in self.parent.kvp['typenames'] or 'csw30:Record' in self.parent.kvp['typenames'])): # serialize csw:Record inline searchresults.append(self._write_record( res, self.parent.repository.queryables['_all'])) elif (self.parent.kvp['outputschema'] == 'http://www.opengis.net/cat/csw/3.0' and 'csw:Record' not in self.parent.kvp['typenames']): # serialize into csw:Record model for prof in self.parent.profiles['loaded']: # find source typename if self.parent.profiles['loaded'][prof].typename in \ self.parent.kvp['typenames']: typename = self.parent.profiles['loaded'][prof].typename break util.transform_mappings( self.parent.repository.queryables['_all'], self.parent.context.model['typenames'][typename][ 'mappings']['csw:Record'] ) searchresults.append(self._write_record( res, self.parent.repository.queryables['_all'])) elif self.parent.kvp['outputschema'] in self.parent.outputschemas: # use outputschema serializer searchresults.append(self.parent.outputschemas[self.parent.kvp['outputschema']].write_record(res, self.parent.kvp['elementsetname'], self.parent.context, self.parent.config['server'].get('url'))) else: # use profile serializer searchresults.append( self.parent.profiles['loaded'][self.parent.kvp['outputschema']].\ write_record(res, self.parent.kvp['elementsetname'], self.parent.kvp['outputschema'], self.parent.repository.queryables['_all'])) except Exception as err: self.parent.response = self.exceptionreport( 'NoApplicableCode', 'service', 'Record serialization failed: %s' % str(err)) return self.parent.response hopcount = int(self.parent.kvp.get('hopcount', 2)) - 1 if ('federatedcatalogues' in self.parent.config and self.parent.kvp.get('distributedsearch') and hopcount > 0): LOGGER.debug('DistributedSearch specified (hopCount: %s).', hopcount) from owslib.csw import CatalogueServiceWeb from owslib.ows import ExceptionReport for fedcat in self.parent.config.get('federatedcatalogues', []): if fedcat['type'] != 'CSW': LOGGER.debug(f"Federated catalogue type {fc['type']} not supported; skipping") continue LOGGER.info('Performing distributed search on federated \ catalogue: %s', fedcat['url']) try: start_time = time() remotecsw = CatalogueServiceWeb(fedcat['url'], version='3.0.0', skip_caps=True) if str(self.parent.request).startswith('http'): self.parent.request = self.parent.request.split('?')[-1] self.parent.request = self.parent.request.replace('mode=opensearch', '') remotecsw.getrecords(xml=self.parent.request, esn=self.parent.kvp['elementsetname'], outputschema=self.parent.kvp['outputschema']) fsr = etree.SubElement(searchresults, util.nspath_eval( 'csw30:FederatedSearchResult', self.parent.context.namespaces), catalogueURL=fedcat['url']) msg = 'Distributed search results from catalogue %s: %s.' % (fedcat['url'], remotecsw.results) LOGGER.debug(msg) fsr.append(etree.Comment(msg)) search_result = etree.SubElement(fsr, util.nspath_eval( 'csw30:searchResult', self.parent.context.namespaces), recordSchema=self.parent.kvp['outputschema'], elementSetName=self.parent.kvp['elementsetname'], numberOfRecordsMatched=str(remotecsw.results['matches']), numberOfRecordsReturned=str(remotecsw.results['returned']), nextRecord=str(remotecsw.results['nextrecord']), elapsedTime=str(get_elapsed_time(start_time, time())), status=get_resultset_status( remotecsw.results['matches'], remotecsw.results['nextrecord'])) for result in remotecsw.records.values(): search_result.append(etree.fromstring(result.xml, self.parent.context.parser)) except ExceptionReport as err: error_string = 'remote CSW %s returned exception: ' % fedcat['url'] searchresults.append(etree.Comment( ' %s\n\n%s ' % (error_string, err))) LOGGER.exception(error_string) except Exception as err: error_string = 'remote CSW %s returned error: ' % fedcat['url'] searchresults.append(etree.Comment( ' %s\n\n%s ' % (error_string, err))) LOGGER.exception(error_string) searchresults.attrib['elapsedTime'] = str(get_elapsed_time(self.parent.process_time_start, time())) if 'responsehandler' in self.parent.kvp: # process the handler self.parent._process_responsehandler(etree.tostring(node, pretty_print=self.parent.pretty_print)) else: return node def getrecordbyid(self, raw=False): ''' Handle GetRecordById request ''' if 'id' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'id', 'Missing id parameter') if len(self.parent.kvp['id']) < 1: return self.exceptionreport('InvalidParameterValue', 'id', 'Invalid id parameter') if 'outputschema' not in self.parent.kvp: self.parent.kvp['outputschema'] = self.parent.context.namespaces['csw30'] if 'HTTP_ACCEPT' in self.parent.environ: LOGGER.debug('Detected HTTP Accept header: %s', self.parent.environ['HTTP_ACCEPT']) formats_match = False if 'outputformat' in self.parent.kvp: LOGGER.debug(self.parent.kvp['outputformat']) for ofmt in self.parent.environ['HTTP_ACCEPT'].split(','): LOGGER.info('Comparing %s and %s', ofmt, self.parent.kvp['outputformat']) if ofmt.split('/')[0] in self.parent.kvp['outputformat']: LOGGER.debug('FOUND OUTPUT MATCH') formats_match = True if not formats_match: return self.exceptionreport('InvalidParameterValue', 'outputformat', 'HTTP Accept header (%s) and outputformat (%s) must agree' % (self.parent.environ['HTTP_ACCEPT'], self.parent.kvp['outputformat'])) else: for ofmt in self.parent.environ['HTTP_ACCEPT'].split(','): if ofmt in self.parent.context.model['operations']['GetRecords']['parameters']['outputFormat']['values']: self.parent.kvp['outputformat'] = ofmt break if ('outputformat' in self.parent.kvp and self.parent.kvp['outputformat'] not in self.parent.context.model['operations']['GetRecordById']['parameters'] ['outputFormat']['values']): return self.exceptionreport('InvalidParameterValue', 'outputformat', 'Invalid outputformat parameter %s' % self.parent.kvp['outputformat']) if ('outputschema' in self.parent.kvp and self.parent.kvp['outputschema'] not in self.parent.context.model['operations']['GetRecordById']['parameters'] ['outputSchema']['values']): return self.exceptionreport('InvalidParameterValue', 'outputschema', 'Invalid outputschema parameter %s' % self.parent.kvp['outputschema']) if 'outputformat' in self.parent.kvp: self.parent.contenttype = self.parent.kvp['outputformat'] if self.parent.kvp['outputformat'] == 'application/atom+xml': self.parent.kvp['outputschema'] = self.parent.context.namespaces['atom'] self.parent.mode = 'opensearch' if 'elementsetname' not in self.parent.kvp: self.parent.kvp['elementsetname'] = 'summary' else: if (self.parent.kvp['elementsetname'] not in self.parent.context.model['operations']['GetRecordById']['parameters'] ['ElementSetName']['values']): return self.exceptionreport('InvalidParameterValue', 'elementsetname', 'Invalid elementsetname parameter %s' % self.parent.kvp['elementsetname']) # query repository LOGGER.info('Querying repository with ids: %s', self.parent.kvp['id']) results = self.parent.repository.query_ids([self.parent.kvp['id']]) if raw: # GetRepositoryItem request LOGGER.debug('GetRepositoryItem request.') if len(results) > 0: return etree.fromstring(util.getqattr(results[0], self.parent.context.md_core_model['mappings']['pycsw:XML']), self.parent.context.parser) for result in results: node_ = None if self.parent.xslts: try: node_ = self.parent._render_xslt(result) except Exception as err: self.parent.response = self.exceptionreport( 'NoApplicableCode', 'service', 'XSLT transformation failed. Check server logs for errors %s' % str(err)) return self.parent.response if node_ is not None: node = node_ else: if (util.getqattr(result, self.parent.context.md_core_model['mappings']['pycsw:Typename']) == 'csw:Record' and self.parent.kvp['outputschema'] == 'http://www.opengis.net/cat/csw/3.0'): # serialize record inline node = self._write_record( result, self.parent.repository.queryables['_all']) elif (self.parent.kvp['outputschema'] == 'http://www.opengis.net/cat/csw/3.0'): # serialize into csw:Record model typename = None for prof in self.parent.profiles['loaded']: # find source typename if self.parent.profiles['loaded'][prof].typename in \ [util.getqattr(result, self.parent.context.md_core_model['mappings']['pycsw:Typename'])]: typename = self.parent.profiles['loaded'][prof].typename break if typename is not None: util.transform_mappings( self.parent.repository.queryables['_all'], self.parent.context.model['typenames'][typename][ 'mappings']['csw:Record'] ) node = self._write_record( result, self.parent.repository.queryables['_all']) elif self.parent.kvp['outputschema'] in self.parent.outputschemas: # use outputschema serializer node = self.parent.outputschemas[self.parent.kvp['outputschema']].write_record(result, self.parent.kvp['elementsetname'], self.parent.context, self.parent.config['server'].get('url')) else: # it's a profile output node = self.parent.profiles['loaded'][self.parent.kvp['outputschema']].write_record( result, self.parent.kvp['elementsetname'], self.parent.kvp['outputschema'], self.parent.repository.queryables['_all']) if raw and len(results) == 0: return None if len(results) == 0: return self.exceptionreport('NotFound', 'id', 'No repository item found for \'%s\'' % self.parent.kvp['id']) return node def getrepositoryitem(self): ''' Handle GetRepositoryItem request ''' # similar to GetRecordById without csw:* wrapping node = self.parent.getrecordbyid(raw=True) if node is None: return self.exceptionreport('NotFound', 'id', 'No repository item found for \'%s\'' % self.parent.kvp['id']) else: return node def transaction(self): ''' Handle Transaction request ''' try: self.parent._test_manager() except Exception as err: return self.exceptionreport('NoApplicableCode', 'transaction', str(err)) inserted = 0 updated = 0 deleted = 0 insertresults = [] LOGGER.debug('Transaction list: %s', self.parent.kvp['transactions']) for ttype in self.parent.kvp['transactions']: if ttype['type'] == 'insert': try: record = metadata.parse_record(self.parent.context, ttype['xml'], self.parent.repository)[0] except Exception as err: LOGGER.exception('Transaction (insert) failed') return self.exceptionreport('NoApplicableCode', 'insert', 'Transaction (insert) failed: record parsing failed: %s' \ % str(err)) LOGGER.debug('Transaction operation: %s', record) if not hasattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']): return self.exceptionreport('NoApplicableCode', 'insert', 'Record requires an identifier') # insert new record try: self.parent.repository.insert(record, 'local', util.get_today_and_now()) inserted += 1 insertresults.append( {'identifier': getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']), 'title': getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Title'])}) except Exception as err: LOGGER.exception('Transaction (insert) failed') return self.exceptionreport('NoApplicableCode', 'insert', 'Transaction (insert) failed: %s.' % str(err)) elif ttype['type'] == 'update': if 'constraint' not in ttype: # update full existing resource in repository try: record = metadata.parse_record(self.parent.context, ttype['xml'], self.parent.repository)[0] identifier = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']) except Exception as err: return self.exceptionreport('NoApplicableCode', 'insert', 'Transaction (update) failed: record parsing failed: %s' \ % str(err)) # query repository to see if record already exists LOGGER.info('checking if record exists (%s)', identifier) results = self.parent.repository.query_ids(ids=[identifier]) if len(results) == 0: LOGGER.debug('id %s does not exist in repository', identifier) else: # existing record, it's an update try: self.parent.repository.update(record) updated += 1 except Exception as err: return self.exceptionreport('NoApplicableCode', 'update', 'Transaction (update) failed: %s.' % str(err)) else: # update by record property and constraint # get / set XPath for property names for rp in ttype['recordproperty']: if rp['name'] not in self.parent.repository.queryables['_all']: # is it an XPath? if rp['name'].find('/') != -1: # scan outputschemas; if match, bind for osch in self.parent.outputschemas.values(): for key, value in osch.XPATH_MAPPINGS.items(): if value == rp['name']: # match rp['rp'] = {'xpath': value, 'name': key} rp['rp']['dbcol'] = self.parent.repository.queryables['_all'][key] break else: return self.exceptionreport('NoApplicableCode', 'update', 'Transaction (update) failed: invalid property2: %s.' % str(rp['name'])) else: rp['rp']= \ self.parent.repository.queryables['_all'][rp['name']] LOGGER.debug('Record Properties: %s', ttype['recordproperty']) try: updated += self.parent.repository.update(record=None, recprops=ttype['recordproperty'], constraint=ttype['constraint']) except Exception as err: LOGGER.exception('Transaction (update) failed') return self.exceptionreport('NoApplicableCode', 'update', 'Transaction (update) failed: %s.' % str(err)) elif ttype['type'] == 'delete': deleted += self.parent.repository.delete(ttype['constraint']) node = etree.Element(util.nspath_eval('csw30:TransactionResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='3.0.0') node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = '%s %s/csw/3.0/cswTransaction.xsd' % \ (self.parent.context.namespaces['csw30'], self.parent.config['server'].get('ogc_schemas_base')) node.append( self._write_transactionsummary( inserted=inserted, updated=updated, deleted=deleted)) if (len(insertresults) > 0 and self.parent.kvp['verboseresponse']): # show insert result identifiers node.append(self._write_verboseresponse(insertresults)) return node def harvest(self): ''' Handle Harvest request ''' service_identifier = None old_identifier = None deleted = [] try: self.parent._test_manager() except Exception as err: return self.exceptionreport('NoApplicableCode', 'harvest', str(err)) if self.parent.requesttype == 'GET': if 'resourcetype' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'resourcetype', 'Missing resourcetype parameter') if 'source' not in self.parent.kvp: return self.exceptionreport('MissingParameterValue', 'source', 'Missing source parameter') # validate resourcetype if (self.parent.kvp['resourcetype'] not in self.parent.context.model['operations']['Harvest']['parameters']['ResourceType'] ['values']): return self.exceptionreport('InvalidParameterValue', 'resourcetype', 'Invalid resource type parameter: %s.\ Allowable resourcetype values: %s' % (self.parent.kvp['resourcetype'], ','.join(sorted(self.parent.context.model['operations']['Harvest']['parameters'] ['ResourceType']['values'])))) if (self.parent.kvp['resourcetype'].find('opengis.net') == -1 and self.parent.kvp['resourcetype'].find('urn:geoss:waf') == -1): # fetch content-based resource LOGGER.info('Fetching resource %s', self.parent.kvp['source']) try: content = util.http_request('GET', self.parent.kvp['source']) except Exception as err: errortext = 'Error fetching resource %s.\nError: %s.' % \ (self.parent.kvp['source'], str(err)) LOGGER.exception(errortext) return self.exceptionreport('InvalidParameterValue', 'source', errortext) else: # it's a service URL content = self.parent.kvp['source'] # query repository to see if service already exists LOGGER.info('checking if service exists (%s)', content) results = self.parent.repository.query_source(content) if len(results) > 0: # exists, keep identifier for update LOGGER.debug('Service already exists, keeping identifier and results') service_identifier = getattr(results[0], self.parent.context.md_core_model['mappings']['pycsw:Identifier']) service_results = results LOGGER.debug('Identifier is %s', service_identifier) # return self.exceptionreport('NoApplicableCode', 'source', # 'Insert failed: service %s already in repository' % content) if hasattr(self.parent.repository, 'local_ingest') and self.parent.repository.local_ingest: updated = 0 deleted = [] try: ir = self.parent.repository.insert(self.parent.kvp['resourcetype'], self.parent.kvp['source']) inserted = len(ir) except Exception as err: LOGGER.exception('Harvest (insert) failed') return self.exceptionreport('NoApplicableCode', 'source', 'Harvest (insert) failed: %s.' % str(err)) else: # parse resource into record try: records_parsed = metadata.parse_record(self.parent.context, content, self.parent.repository, self.parent.kvp['resourcetype'], pagesize=self.parent.csw_harvest_pagesize) except Exception as err: LOGGER.exception(err) return self.exceptionreport('NoApplicableCode', 'source', 'Harvest failed: record parsing failed: %s' % str(err)) inserted = 0 updated = 0 ir = [] LOGGER.debug('Total Records parsed: %d', len(records_parsed)) for record in records_parsed: if self.parent.kvp['resourcetype'] == 'urn:geoss:waf': src = record.source else: src = self.parent.kvp['source'] setattr(record, self.parent.context.md_core_model['mappings']['pycsw:Source'], src) setattr(record, self.parent.context.md_core_model['mappings']['pycsw:InsertDate'], util.get_today_and_now()) identifier = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']) source = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Source']) insert_date = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:InsertDate']) title = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Title']) record_type = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Type']) record_identifier = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier']) if record_type == 'service' and service_identifier is not None: # service endpoint LOGGER.info('Replacing service identifier from %s to %s', record_identifier, service_identifier) old_identifier = record_identifier identifier = record_identifier = service_identifier if (record_type != 'service' and service_identifier is not None and old_identifier is not None): # service resource if record_identifier.find(old_identifier) != -1: new_identifier = record_identifier.replace(old_identifier, service_identifier) LOGGER.info('Replacing service resource identifier from %s to %s', record_identifier, new_identifier) identifier = record_identifier = new_identifier ir.append({'identifier': identifier, 'title': title}) results = [] if 'source' not in self.parent.config['repository']: # query repository to see if record already exists LOGGER.info('checking if record exists (%s)', identifier) results = self.parent.repository.query_ids(ids=[identifier]) if len(results) == 0: # check for service identifier LOGGER.info('checking if service id exists (%s)', service_identifier) results = self.parent.repository.query_ids(ids=[service_identifier]) LOGGER.debug(str(results)) if len(results) == 0: # new record, it's a new insert inserted += 1 try: tmp = self.parent.repository.insert(record, source, insert_date) if tmp is not None: ir = tmp except Exception as err: return self.exceptionreport('NoApplicableCode', 'source', 'Harvest (insert) failed: %s.' % str(err)) else: # existing record, it's an update if source != results[0].source: # same identifier, but different source return self.exceptionreport('NoApplicableCode', 'source', 'Insert failed: identifier %s in repository\ has source %s.' % (identifier, source)) try: self.parent.repository.update(record) except Exception as err: return self.exceptionreport('NoApplicableCode', 'source', 'Harvest (update) failed: %s.' % str(err)) updated += 1 if service_identifier is not None: fresh_records = [str(i['identifier']) for i in ir] existing_records = [str(i.identifier) for i in service_results] deleted = set(existing_records) - set(fresh_records) LOGGER.debug('Records to delete: %s', deleted) for to_delete in deleted: delete_constraint = { 'type': 'filter', 'values': [to_delete], 'where': 'identifier = :pvalue0' } self.parent.repository.delete(delete_constraint) node = etree.Element(util.nspath_eval('csw:HarvestResponse', self.parent.context.namespaces), nsmap=self.parent.context.namespaces) node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = \ '%s %s/csw/3.0/cswHarvest.xsd' % (self.parent.context.namespaces['csw30'], self.parent.config['server'].get('ogc_schemas_base')) node2 = etree.SubElement(node, util.nspath_eval('csw:TransactionResponse', self.parent.context.namespaces), version='2.0.2') node2.append( self._write_transactionsummary(inserted=len(ir), updated=updated, deleted=len(deleted))) if inserted > 0: # show insert result identifiers node2.append(self._write_verboseresponse(ir)) if 'responsehandler' in self.parent.kvp: # process the handler self.parent._process_responsehandler(etree.tostring(node, pretty_print=self.parent.pretty_print)) else: return node def _write_record(self, recobj, queryables): ''' Generate csw30:Record ''' if self.parent.kvp['elementsetname'] == 'brief': elname = 'BriefRecord' elif self.parent.kvp['elementsetname'] == 'summary': elname = 'SummaryRecord' else: elname = 'Record' record = etree.Element(util.nspath_eval('csw30:%s' % elname, self.parent.context.namespaces), nsmap=self.parent.context.namespaces) if ('elementname' in self.parent.kvp and len(self.parent.kvp['elementname']) > 0): for req_term in ['dc:identifier', 'dc:title']: if req_term not in self.parent.kvp['elementname']: value = util.getqattr(recobj, queryables[req_term]['dbcol']) etree.SubElement(record, util.nspath_eval(req_term, self.parent.context.namespaces)).text = value for elemname in self.parent.kvp['elementname']: if (elemname.find('BoundingBox') != -1 or elemname.find('Envelope') != -1): bboxel = write_boundingbox(util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:BoundingBox']), self.parent.context.namespaces) if bboxel is not None: record.append(bboxel) else: value = util.getqattr(recobj, queryables[elemname]['dbcol']) elem = etree.SubElement(record, util.nspath_eval(elemname, self.parent.context.namespaces)) if value: elem.text = value elif 'elementsetname' in self.parent.kvp: if (self.parent.kvp['elementsetname'] == 'full' and util.getqattr(recobj, self.parent.context.md_core_model['mappings']\ ['pycsw:Typename']) == 'csw:Record' and util.getqattr(recobj, self.parent.context.md_core_model['mappings']\ ['pycsw:Schema']) == 'http://www.opengis.net/cat/csw/3.0' and util.getqattr(recobj, self.parent.context.md_core_model['mappings']\ ['pycsw:Type']) != 'service'): # dump record as is and exit return etree.fromstring(util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:XML']), self.parent.context.parser) etree.SubElement(record, util.nspath_eval('dc:identifier', self.parent.context.namespaces)).text = \ util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:Identifier']) for i in ['dc:title', 'dc:type']: val = util.getqattr(recobj, queryables[i]['dbcol']) if not val: val = '' etree.SubElement(record, util.nspath_eval(i, self.parent.context.namespaces)).text = val if self.parent.kvp['elementsetname'] in ['summary', 'full']: # add summary elements keywords = util.getqattr(recobj, queryables['dc:subject']['dbcol']) if keywords is not None: for keyword in keywords.split(','): etree.SubElement(record, util.nspath_eval('dc:subject', self.parent.context.namespaces)).text = keyword val = util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:TopicCategory']) if val: etree.SubElement(record, util.nspath_eval('dc:subject', self.parent.context.namespaces), scheme='http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_TopicCategoryCode').text = val val = util.getqattr(recobj, queryables['dc:format']['dbcol']) if val: etree.SubElement(record, util.nspath_eval('dc:format', self.parent.context.namespaces)).text = val # links rlinks = util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:Links']) if rlinks: LOGGER.info(f'link type: {type(rlinks)}') for link in util.jsonify_links(rlinks): ref = etree.SubElement(record, util.nspath_eval('dct:references', self.parent.context.namespaces)) if link.get('protocol'): ref.attrib['scheme'] = link['protocol'] ref.text = link['url'] for i in ['dc:relation', 'dct:modified', 'dct:abstract']: val = util.getqattr(recobj, queryables[i]['dbcol']) if val is not None: etree.SubElement(record, util.nspath_eval(i, self.parent.context.namespaces)).text = val if self.parent.kvp['elementsetname'] == 'full': # add full elements for i in ['dc:date', 'dc:creator', \ 'dc:publisher', 'dc:contributor', 'dc:source', \ 'dc:language', 'dc:rights', 'dct:alternative']: val = util.getqattr(recobj, queryables[i]['dbcol']) if val: etree.SubElement(record, util.nspath_eval(i, self.parent.context.namespaces)).text = val val = util.getqattr(recobj, queryables['dct:spatial']['dbcol']) if val: etree.SubElement(record, util.nspath_eval('dct:spatial', self.parent.context.namespaces), scheme='http://www.opengis.net/def/crs').text = val # always write out ows:BoundingBox bboxel = write_boundingbox(getattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:BoundingBox']), self.parent.context.namespaces) if bboxel is not None: record.append(bboxel) if self.parent.kvp['elementsetname'] != 'brief': # add temporal extent begin = util.getqattr(record, self.parent.context.md_core_model['mappings']['pycsw:TempExtent_begin']) end = util.getqattr(record, self.parent.context.md_core_model['mappings']['pycsw:TempExtent_end']) if begin or end: tempext = etree.SubElement(record, util.nspath_eval('csw30:TemporalExtent', self.parent.context.namespaces)) if begin: etree.SubElement(record, util.nspath_eval('csw30:begin', self.parent.context.namespaces)).text = begin if end: etree.SubElement(record, util.nspath_eval('csw30:end', self.parent.context.namespaces)).text = end return record def _parse_constraint(self, element): ''' Parse csw:Constraint ''' query = {} tmp = element.find(util.nspath_eval('fes20:Filter', self.parent.context.namespaces)) if tmp is not None: LOGGER.debug('Filter constraint specified') try: query['type'] = 'filter' query['where'], query['values'] = fes2.parse(tmp, self.parent.repository.queryables['_all'], self.parent.repository.dbtype, self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) query['_dict'] = xml2dict(etree.tostring(tmp), self.parent.context.namespaces) except Exception as err: return 'Invalid Filter request: %s' % err tmp = element.find(util.nspath_eval('csw30:CqlText', self.parent.context.namespaces)) if tmp is not None: LOGGER.debug('CQL specified: %s.', tmp.text) try: LOGGER.info('Transforming CQL into OGC Filter') query['type'] = 'filter' cql = cql2fes(tmp.text, self.parent.context.namespaces, fes_version='2.0') query['where'], query['values'] = fes2.parse(cql, self.parent.repository.queryables['_all'], self.parent.repository.dbtype, self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) query['_dict'] = xml2dict(etree.tostring(cql), self.parent.context.namespaces) except Exception as err: LOGGER.exception('Invalid CQL request: %s', tmp.text) LOGGER.exception('Error message: %s', err) return 'Invalid CQL request' return query def parse_postdata(self, postdata): ''' Parse POST XML ''' request = {} try: LOGGER.info('Parsing %s.', postdata) doc = etree.fromstring(postdata, self.parent.context.parser) except Exception as err: errortext = \ 'Exception: document not well-formed.\nError: %s.' % str(err) LOGGER.exception(errortext) return errortext # if this is a SOAP request, get to SOAP-ENV:Body/csw:* if (doc.tag == util.nspath_eval('soapenv:Envelope', self.parent.context.namespaces)): LOGGER.debug('SOAP request specified') self.parent.soap = True doc = doc.find( util.nspath_eval('soapenv:Body', self.parent.context.namespaces)).xpath('child::*')[0] xsd_filename = '_wrapper.xsd' schema = os.path.join(self.parent.config['server'].get('home'), 'core', 'schemas', 'ogc', 'cat', 'csw', '3.0', xsd_filename) try: # it is virtually impossible to validate a csw:Transaction # csw:Insert|csw:Update (with single child) XML document. # Only validate non csw:Transaction XML if doc.find('.//%s' % util.nspath_eval('csw30:Insert', self.parent.context.namespaces)) is None and \ len(doc.xpath('//csw30:Update/child::*', namespaces=self.parent.context.namespaces)) == 0: LOGGER.info('Validating %s', postdata) schema = etree.XMLSchema(file=schema) parser = etree.XMLParser(schema=schema, resolve_entities=False) if hasattr(self.parent, 'soap') and self.parent.soap: # validate the body of the SOAP request doc = etree.fromstring(etree.tostring(doc), parser) else: # validate the request normally doc = etree.fromstring(postdata, parser) LOGGER.debug('Request is valid XML') else: # parse Transaction without validation doc = etree.fromstring(postdata, self.parent.context.parser) except Exception as err: errortext = \ 'Exception: the document is not valid.\nError: %s' % str(err) LOGGER.exception(errortext) return errortext request['request'] = etree.QName(doc).localname LOGGER.debug('Request operation %s specified.', request['request']) tmp = doc.find('.').attrib.get('service') if tmp is not None: request['service'] = tmp tmp = doc.find('.').attrib.get('version') if tmp is not None: request['version'] = tmp tmp = doc.find('.//%s' % util.nspath_eval('ows20:Version', self.parent.context.namespaces)) if tmp is not None: request['version'] = tmp.text tmp = doc.find('.').attrib.get('updateSequence') if tmp is not None: request['updatesequence'] = tmp # GetCapabilities if request['request'] == 'GetCapabilities': tmp = doc.find(util.nspath_eval('ows20:Sections', self.parent.context.namespaces)) if tmp is not None: request['sections'] = ','.join([section.text for section in \ doc.findall(util.nspath_eval('ows20:Sections/ows20:Section', self.parent.context.namespaces))]) tmp = doc.find(util.nspath_eval('ows20:AcceptFormats', self.parent.context.namespaces)) if tmp is not None: request['acceptformats'] = ','.join([aformat.text for aformat in \ doc.findall(util.nspath_eval('ows20:AcceptFormats/ows20:OutputFormat', self.parent.context.namespaces))]) tmp = doc.find(util.nspath_eval('ows20:AcceptVersions', self.parent.context.namespaces)) if tmp is not None: request['acceptversions'] = ','.join([version.text for version in \ doc.findall(util.nspath_eval('ows20:AcceptVersions/ows20:Version', self.parent.context.namespaces))]) # GetDomain if request['request'] == 'GetDomain': tmp = doc.find(util.nspath_eval('csw30:ParameterName', self.parent.context.namespaces)) if tmp is not None: request['parametername'] = tmp.text tmp = doc.find(util.nspath_eval('csw30:ValueReference', self.parent.context.namespaces)) if tmp is not None: request['valuereference'] = tmp.text # GetRecords if request['request'] == 'GetRecords': tmp = doc.find('.').attrib.get('outputSchema') request['outputschema'] = tmp if tmp is not None \ else self.parent.context.namespaces['csw30'] tmp = doc.find('.').attrib.get('outputFormat') request['outputformat'] = tmp if tmp is not None \ else 'application/xml' tmp = doc.find('.').attrib.get('startPosition') request['startposition'] = tmp if tmp is not None else 1 tmp = doc.find('.').attrib.get('requestId') request['requestid'] = tmp if tmp is not None else None tmp = doc.find('.').attrib.get('maxRecords') if tmp is not None: request['maxrecords'] = tmp tmp = doc.find(util.nspath_eval('csw30:DistributedSearch', self.parent.context.namespaces)) if tmp is not None: request['distributedsearch'] = True hopcount = tmp.attrib.get('hopCount') request['hopcount'] = int(hopcount) if hopcount is not None \ else 2 else: request['distributedsearch'] = False tmp = doc.find(util.nspath_eval('csw30:ResponseHandler', self.parent.context.namespaces)) if tmp is not None: request['responsehandler'] = tmp.text tmp = doc.find(util.nspath_eval('csw30:Query/csw30:ElementSetName', self.parent.context.namespaces)) request['elementsetname'] = tmp.text if tmp is not None else None tmp = doc.find(util.nspath_eval( 'csw30:Query', self.parent.context.namespaces)).attrib.get('typeNames') request['typenames'] = tmp.split() if tmp is not None \ else 'csw:Record' request['elementname'] = [elname.text for elname in \ doc.findall(util.nspath_eval('csw30:Query/csw30:ElementName', self.parent.context.namespaces))] request['constraint'] = {} tmp = doc.find(util.nspath_eval('csw30:Query/csw30:Constraint', self.parent.context.namespaces)) if tmp is not None: request['constraint'] = self._parse_constraint(tmp) if isinstance(request['constraint'], str): # parse error return 'Invalid Constraint: %s' % request['constraint'] else: LOGGER.debug('No csw30:Constraint (fes20:Filter or csw30:CqlText) \ specified') tmp = doc.find(util.nspath_eval('csw30:Query/fes20:SortBy', self.parent.context.namespaces)) if tmp is not None: LOGGER.debug('Sorted query specified') request['sortby'] = {} try: elname = tmp.find(util.nspath_eval( 'fes20:SortProperty/fes20:ValueReference', self.parent.context.namespaces)).text request['sortby']['propertyname'] = \ self.parent.repository.queryables['_all'][elname]['dbcol'] if (elname.find('BoundingBox') != -1 or elname.find('Envelope') != -1): # it's a spatial sort request['sortby']['spatial'] = True except Exception as err: errortext = \ 'Invalid fes20:SortProperty/fes20:ValueReference: %s' % str(err) LOGGER.exception(errortext) return errortext tmp2 = tmp.find(util.nspath_eval( 'fes20:SortProperty/fes20:SortOrder', self.parent.context.namespaces)) request['sortby']['order'] = tmp2.text if tmp2 is not None \ else 'ASC' else: request['sortby'] = None # GetRecordById if request['request'] == 'GetRecordById': request['id'] = None tmp = doc.find(util.nspath_eval('csw30:Id', self.parent.context.namespaces)) if tmp is not None: request['id'] = tmp.text tmp = doc.find(util.nspath_eval('csw30:ElementSetName', self.parent.context.namespaces)) request['elementsetname'] = tmp.text if tmp is not None \ else 'summary' tmp = doc.find('.').attrib.get('outputSchema') request['outputschema'] = tmp if tmp is not None \ else self.parent.context.namespaces['csw30'] tmp = doc.find('.').attrib.get('outputFormat') if tmp is not None: request['outputformat'] = tmp # Transaction if request['request'] == 'Transaction': request['verboseresponse'] = True tmp = doc.find('.').attrib.get('verboseResponse') if tmp is not None: if tmp in ['false', '0']: request['verboseresponse'] = False tmp = doc.find('.').attrib.get('requestId') request['requestid'] = tmp if tmp is not None else None request['transactions'] = [] for ttype in \ doc.xpath('//csw30:Insert', namespaces=self.parent.context.namespaces): tname = ttype.attrib.get('typeName') for mdrec in ttype.xpath('child::*'): xml = mdrec request['transactions'].append( {'type': 'insert', 'typename': tname, 'xml': xml}) for ttype in \ doc.xpath('//csw30:Update', namespaces=self.parent.context.namespaces): child = ttype.xpath('child::*') update = {'type': 'update'} if len(child) == 1: # it's a wholesale update update['xml'] = child[0] else: # it's a RecordProperty with Constraint Update update['recordproperty'] = [] for recprop in ttype.findall( util.nspath_eval('csw:RecordProperty', self.parent.context.namespaces)): rpname = recprop.find(util.nspath_eval('csw30:Name', self.parent.context.namespaces)).text rpvalue = recprop.find( util.nspath_eval('csw30:Value', self.parent.context.namespaces)).text update['recordproperty'].append( {'name': rpname, 'value': rpvalue}) update['constraint'] = self._parse_constraint( ttype.find(util.nspath_eval('csw30:Constraint', self.parent.context.namespaces))) request['transactions'].append(update) for ttype in \ doc.xpath('//csw30:Delete', namespaces=self.parent.context.namespaces): tname = ttype.attrib.get('typeName') constraint = self._parse_constraint( ttype.find(util.nspath_eval('csw30:Constraint', self.parent.context.namespaces))) if isinstance(constraint, str): # parse error return 'Invalid Constraint: %s' % constraint request['transactions'].append( {'type': 'delete', 'typename': tname, 'constraint': constraint}) # Harvest if request['request'] == 'Harvest': request['source'] = doc.find(util.nspath_eval('csw30:Source', self.parent.context.namespaces)).text request['resourcetype'] = \ doc.find(util.nspath_eval('csw30:ResourceType', self.parent.context.namespaces)).text tmp = doc.find(util.nspath_eval('csw30:ResourceFormat', self.parent.context.namespaces)) if tmp is not None: request['resourceformat'] = tmp.text else: request['resourceformat'] = 'application/xml' tmp = doc.find(util.nspath_eval('csw30:HarvestInterval', self.parent.context.namespaces)) if tmp is not None: request['harvestinterval'] = tmp.text tmp = doc.find(util.nspath_eval('csw30:ResponseHandler', self.parent.context.namespaces)) if tmp is not None: request['responsehandler'] = tmp.text return request def _write_transactionsummary(self, inserted=0, updated=0, deleted=0): ''' Write csw:TransactionSummary construct ''' node = etree.Element(util.nspath_eval('csw30:TransactionSummary', self.parent.context.namespaces)) if 'requestid' in self.parent.kvp and self.parent.kvp['requestid'] is not None: node.attrib['requestId'] = self.parent.kvp['requestid'] etree.SubElement(node, util.nspath_eval('csw30:totalInserted', self.parent.context.namespaces)).text = str(inserted) etree.SubElement(node, util.nspath_eval('csw30:totalUpdated', self.parent.context.namespaces)).text = str(updated) etree.SubElement(node, util.nspath_eval('csw30:totalDeleted', self.parent.context.namespaces)).text = str(deleted) return node def _write_acknowledgement(self, root=True): ''' Generate csw:Acknowledgement ''' node = etree.Element(util.nspath_eval('csw30:Acknowledgement', self.parent.context.namespaces), nsmap = self.parent.context.namespaces, timeStamp=util.get_today_and_now()) if root: node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = \ '%s %s/cat/csw/3.0/cswAll.xsd' % (self.parent.context.namespaces['csw30'], \ self.parent.config['server'].get('ogc_schemas_base')) node1 = etree.SubElement(node, util.nspath_eval('csw30:EchoedRequest', self.parent.context.namespaces)) if self.parent.requesttype == 'POST': node1.append(etree.fromstring(self.parent.request, self.parent.context.parser)) else: # GET node2 = etree.SubElement(node1, util.nspath_eval('ows:Get', self.parent.context.namespaces)) node2.text = self.parent.request if self.parent.asynchronous: etree.SubElement(node, util.nspath_eval('csw30:RequestId', self.parent.context.namespaces)).text = self.parent.kvp['requestid'] return node def _write_verboseresponse(self, insertresults): ''' show insert result identifiers ''' insertresult = etree.Element(util.nspath_eval('csw30:InsertResult', self.parent.context.namespaces)) for ir in insertresults: briefrec = etree.SubElement(insertresult, util.nspath_eval('csw30:BriefRecord', self.parent.context.namespaces)) etree.SubElement(briefrec, util.nspath_eval('dc:identifier', self.parent.context.namespaces)).text = ir['identifier'] etree.SubElement(briefrec, util.nspath_eval('dc:title', self.parent.context.namespaces)).text = ir['title'] return insertresult def _write_allowed_values(self, values): ''' design pattern to write ows20:AllowedValues ''' allowed_values = etree.Element(util.nspath_eval('ows20:AllowedValues', self.parent.context.namespaces)) for value in sorted(values): etree.SubElement(allowed_values, util.nspath_eval('ows20:Value', self.parent.context.namespaces)).text = str(value) return allowed_values def exceptionreport(self, code, locator, text): ''' Generate ExceptionReport ''' self.parent.exception = True self.parent.status = code try: language = self.parent.config['server'].get('language') ogc_schemas_base = self.parent.config['server'].get('ogc_schemas_base') except Exception: LOGGER.debug('Dropping to default language and OGC schemas base') language = 'en-US' ogc_schemas_base = self.parent.context.ogc_schemas_base node = etree.Element(util.nspath_eval('ows20:ExceptionReport', self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='3.0.0') node.attrib['{http://www.w3.org/XML/1998/namespace}lang'] = language node.attrib[util.nspath_eval('xsi:schemaLocation', self.parent.context.namespaces)] = \ '%s %s/ows/2.0/owsExceptionReport.xsd' % \ (self.parent.context.namespaces['ows20'], ogc_schemas_base) exception = etree.SubElement(node, util.nspath_eval('ows20:Exception', self.parent.context.namespaces), exceptionCode=code, locator=locator) exception_text = etree.SubElement(exception, util.nspath_eval('ows20:ExceptionText', self.parent.context.namespaces)) try: exception_text.text = text except ValueError as err: exception_text.text = repr(text) return node def resolve_nsmap(self, list_): '''' Resolve typename bindings based on default and KVP namespaces ''' nsmap = {} tns = [] LOGGER.debug('Namespace list pairs: %s', list_) # bind KVP namespaces into typenames for ns in self.parent.kvp['namespace'].split(','): nspair = ns.split('(')[1].split(')')[0].split('=') if len(nspair) == 1: # default namespace nsmap['csw'] = nspair[1] else: nsmap[nspair[0]] = nspair[1] LOGGER.debug('Namespace pairs: %s', nsmap) for tn in list_: LOGGER.debug(tn) if tn.find(':') != -1: # resolve prefix prefix = tn.split(':')[0] if prefix in nsmap.keys(): # get uri uri = nsmap[prefix] newprefix = next(k for k, v in self.parent.context.namespaces.items() if v == uri) LOGGER.debug(uri) LOGGER.debug(prefix) LOGGER.debug(newprefix) #if prefix == 'csw30': newprefix = 'csw' newvalue = tn.replace(prefix, newprefix).replace('csw30', 'csw') else: newvalue = tn else: # default namespace newvalue = tn tns.append(newvalue) LOGGER.debug(tns) return tns def write_boundingbox(bbox, nsmap): ''' Generate ows20:BoundingBox ''' if bbox is not None: try: bbox2 = util.wkt2geom(bbox) except Exception as err: LOGGER.debug(f'Geometry parsing error: {err}') return None if len(bbox2) == 4: boundingbox = etree.Element(util.nspath_eval('ows20:BoundingBox', nsmap), crs='http://www.opengis.net/def/crs/EPSG/0/4326', dimensions='2') etree.SubElement(boundingbox, util.nspath_eval('ows20:LowerCorner', nsmap)).text = '%s %s' % (bbox2[1], bbox2[0]) etree.SubElement(boundingbox, util.nspath_eval('ows20:UpperCorner', nsmap)).text = '%s %s' % (bbox2[3], bbox2[2]) return boundingbox else: return None else: return None if nextrecord == 0: searchresult_status = 'complete' elif nextrecord > 0: searchresult_status = 'subset' elif matched == 0: searchresult_status = 'none' def get_resultset_status(matched, nextrecord): ''' Helper function to assess status of a result set ''' status = 'subset' # default if nextrecord == 0: status = 'complete' elif matched == 0: status = 'none' return status def get_elapsed_time(begin, end): """Helper function to calculate elapsed time in milliseconds.""" return int((end - begin) * 1000) ================================================ FILE: pycsw/ogc/fes/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/ogc/fes/fes1.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2024 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from pycsw.core import util from pycsw.core.etree import etree from pycsw.ogc.gml import gml3 LOGGER = logging.getLogger(__name__) MODEL = { 'GeometryOperands': { 'values': gml3.TYPES }, 'SpatialOperators': { 'values': ['BBOX', 'Beyond', 'Contains', 'Crosses', 'Disjoint', 'DWithin', 'Equals', 'Intersects', 'Overlaps', 'Touches', 'Within'] }, 'ComparisonOperators': { 'ogc:PropertyIsBetween': {'opname': 'Between', 'opvalue': 'and'}, 'ogc:PropertyIsEqualTo': {'opname': 'EqualTo', 'opvalue': '='}, 'ogc:PropertyIsGreaterThan': {'opname': 'GreaterThan', 'opvalue': '>'}, 'ogc:PropertyIsGreaterThanOrEqualTo': { 'opname': 'GreaterThanEqualTo', 'opvalue': '>='}, 'ogc:PropertyIsLessThan': {'opname': 'LessThan', 'opvalue': '<'}, 'ogc:PropertyIsLessThanOrEqualTo': { 'opname': 'LessThanEqualTo', 'opvalue': '<='}, 'ogc:PropertyIsLike': {'opname': 'Like', 'opvalue': 'like'}, 'ogc:PropertyIsNotEqualTo': {'opname': 'NotEqualTo', 'opvalue': '!='}, 'ogc:PropertyIsNull': {'opname': 'NullCheck', 'opvalue': 'is null'}, }, 'Functions': { 'length': {'args': '1'}, 'lower': {'args': '1'}, 'ltrim': {'args': '1'}, 'rtrim': {'args': '1'}, 'trim': {'args': '1'}, 'upper': {'args': '1'}, }, 'Ids': { 'values': ['EID', 'FID'] } } def parse(element, queryables, dbtype, nsmap, orm='sqlalchemy', language='english', fts=False): """OGC Filter object support""" boq = None is_pg = dbtype.startswith('postgresql') tmp = element.xpath('ogc:And|ogc:Or|ogc:Not', namespaces=nsmap) if len(tmp) > 0: # this is binary logic query element_name = etree.QName(tmp[0]).localname boq = ' %s ' % element_name.lower() LOGGER.debug('Binary logic detected; operator=%s', boq) tmp = tmp[0] else: tmp = element pvalue_serial = [0] def assign_param(): if orm == 'django': return '%s' param = ':pvalue%d' % pvalue_serial[0] pvalue_serial[0] += 1 return param def _get_comparison_expression(elem): """return the SQL expression based on Filter query""" fname = None matchcase = elem.attrib.get('matchCase') wildcard = elem.attrib.get('wildCard') singlechar = elem.attrib.get('singleChar') expression = None if wildcard is None: wildcard = '%' if singlechar is None: singlechar = '_' if (elem.xpath('child::*')[0].tag == util.nspath_eval('ogc:Function', nsmap)): LOGGER.debug('ogc:Function detected') if (elem.xpath('child::*')[0].attrib['name'] not in MODEL['Functions']): raise RuntimeError('Invalid ogc:Function: %s' % (elem.xpath('child::*')[0].attrib['name'])) fname = elem.xpath('child::*')[0].attrib['name'] try: LOGGER.debug('Testing existence of ogc:PropertyName') pname = queryables[elem.find(util.nspath_eval('ogc:Function/ogc:PropertyName', nsmap)).text]['dbcol'] except Exception as err: raise RuntimeError('Invalid PropertyName: %s. %s' % (elem.find(util.nspath_eval('ogc:Function/ogc:PropertyName', nsmap)).text, str(err))) from err else: try: LOGGER.debug('Testing existence of ogc:PropertyName') pname = queryables[elem.find( util.nspath_eval('ogc:PropertyName', nsmap)).text]['dbcol'] except Exception as err: raise RuntimeError('Invalid PropertyName: %s. %s' % (elem.find(util.nspath_eval('ogc:PropertyName', nsmap)).text, str(err))) from err if (elem.tag != util.nspath_eval('ogc:PropertyIsBetween', nsmap)): if elem.tag in [util.nspath_eval('ogc:%s' % n, nsmap) for n in MODEL['SpatialOperators']['values']]: boolean_true = '\'true\'' boolean_false = '\'false\'' if dbtype == 'mysql': boolean_true = 'true' boolean_false = 'false' return "%s = %s" % (_get_spatial_operator(queryables['pycsw:BoundingBox'], elem, dbtype, nsmap), boolean_true) else: pval = elem.find(util.nspath_eval('ogc:Literal', nsmap)).text com_op = _get_comparison_operator(elem) LOGGER.debug('Comparison operator: %s', com_op) # if this is a case insensitive search # then set the DB-specific LIKE comparison operator LOGGER.debug('Setting csw:AnyText property') anytext = queryables['csw:AnyText']['dbcol'] if ((matchcase is not None and matchcase == 'false') or pname == anytext): com_op = 'ilike' if is_pg else 'like' if (elem.tag == util.nspath_eval('ogc:PropertyIsBetween', nsmap)): com_op = 'between' lower_boundary = elem.find( util.nspath_eval('ogc:LowerBoundary/ogc:Literal', nsmap)).text upper_boundary = elem.find( util.nspath_eval('ogc:UpperBoundary/ogc:Literal', nsmap)).text expression = "%s %s %s and %s" % \ (pname, com_op, assign_param(), assign_param()) values.append(lower_boundary) values.append(upper_boundary) else: if pname == anytext and is_pg and fts: LOGGER.debug('PostgreSQL FTS specific search') # do nothing, let FTS do conversion (#212) pvalue = pval else: LOGGER.debug('PostgreSQL non-FTS specific search') pvalue = pval.replace(wildcard, '%').replace(singlechar, '_') if pname == anytext: # pad anytext with wildcards LOGGER.debug('PostgreSQL non-FTS specific anytext search') LOGGER.debug('old value: %s', pval) pvalue = '%%%s%%' % pvalue.rstrip('%').lstrip('%') LOGGER.debug('new value: %s', pvalue) values.append(pvalue) if boq == ' not ': if fname is not None: expression = "%s is null or not %s(%s) %s %s" % \ (pname, fname, pname, com_op, assign_param()) elif pname == anytext and is_pg and fts: LOGGER.debug('PostgreSQL FTS specific search') expression = ("%s is null or not plainto_tsquery('%s', %s) @@ anytext_tsvector" % (anytext, language, assign_param())) else: LOGGER.debug('PostgreSQL non-FTS specific search') expression = "%s is null or not %s %s %s" % \ (pname, pname, com_op, assign_param()) else: if fname is not None: expression = "%s(%s) %s %s" % \ (fname, pname, com_op, assign_param()) elif pname == anytext and is_pg and fts: LOGGER.debug('PostgreSQL FTS specific search') expression = ("plainto_tsquery('%s', %s) @@ anytext_tsvector" % (language, assign_param())) else: LOGGER.debug('PostgreSQL non-FTS specific search') expression = "%s %s %s" % (pname, com_op, assign_param()) return expression queries = [] values = [] LOGGER.debug('Scanning children elements') for child in tmp.xpath('child::*'): com_op = '' boolean_true = '\'true\'' boolean_false = '\'false\'' if dbtype == 'mysql': boolean_true = 'true' boolean_false = 'false' if child.tag == util.nspath_eval('ogc:Not', nsmap): LOGGER.debug('ogc:Not query detected') child_not = child.xpath('child::*')[0] if child_not.tag in \ [util.nspath_eval('ogc:%s' % n, nsmap) for n in MODEL['SpatialOperators']['values']]: LOGGER.debug('ogc:Not / spatial operator detected: %s', child.tag) queries.append("%s = %s" % (_get_spatial_operator( queryables['pycsw:BoundingBox'], child.xpath('child::*')[0], dbtype, nsmap), boolean_false)) else: LOGGER.debug('ogc:Not / comparison operator detected: %s', child.tag) queries.append('not %s' % _get_comparison_expression(child_not)) elif child.tag in \ [util.nspath_eval('ogc:%s' % n, nsmap) for n in MODEL['SpatialOperators']['values']]: LOGGER.debug('spatial operator detected: %s', child.tag) if boq is not None and boq == ' not ': # for ogc:Not spatial queries in PostGIS we must explictly # test that pycsw:BoundingBox is null as well # TODO: Do we need the same for 'postgresql+postgis+native'??? if dbtype == 'postgresql+postgis+wkt': LOGGER.debug('Setting bbox is null test in PostgreSQL') queries.append("%s = %s or %s is null" % (_get_spatial_operator( queryables['pycsw:BoundingBox'], child, dbtype, nsmap), boolean_false, queryables['pycsw:BoundingBox'])) else: queries.append("%s = %s" % (_get_spatial_operator( queryables['pycsw:BoundingBox'], child, dbtype, nsmap), boolean_false)) else: queries.append("%s = %s" % (_get_spatial_operator( queryables['pycsw:BoundingBox'], child, dbtype, nsmap), boolean_true)) elif child.tag == util.nspath_eval('ogc:FeatureId', nsmap): LOGGER.debug('ogc:FeatureId filter detected') queries.append("%s = %s" % (queryables['pycsw:Identifier'], assign_param())) values.append(child.attrib.get('fid')) else: # comparison operator LOGGER.debug('Comparison operator processing') child_tag_name = etree.QName(child).localname tagname = ' %s ' % child_tag_name.lower() if tagname in [' or ', ' and ']: # this is a nested binary logic query LOGGER.debug('Nested binary logic detected; operator=%s', tagname) queries_nested = [] for child2 in child.xpath('child::*'): queries_nested.append(_get_comparison_expression(child2)) LOGGER.debug('Nested binary logic queries: %s', queries_nested) queries.append('(%s)' % tagname.join(queries_nested)) else: queries.append(_get_comparison_expression(child)) where = boq.join(queries) if (boq is not None and boq != ' not ') \ else queries[0] return where, values def _get_spatial_operator(geomattr, element, dbtype, nsmap, postgis_geometry_column='wkb_geometry'): """return the spatial predicate function""" property_name = element.find(util.nspath_eval('ogc:PropertyName', nsmap)) distance = element.find(util.nspath_eval('ogc:Distance', nsmap)) distance = 'false' if distance is None else distance.text LOGGER.debug('Scanning for spatial property name') if property_name is None: raise RuntimeError('Missing ogc:PropertyName in spatial filter') if (property_name.text.find('BoundingBox') == -1 and property_name.text.find('Envelope') == -1): raise RuntimeError('Invalid ogc:PropertyName in spatial filter: %s' % property_name.text) geometry = gml3.Geometry(element, nsmap) #make decision to apply spatial ranking to results set_spatial_ranking(geometry) spatial_predicate = etree.QName(element).localname.lower() LOGGER.debug('Spatial predicate: %s', spatial_predicate) if dbtype == 'mysql': # adjust spatial query for MySQL LOGGER.debug('Adjusting spatial query for MySQL') if spatial_predicate == 'bbox': spatial_predicate = 'intersects' if spatial_predicate == 'beyond': spatial_query = "ifnull(distance(geomfromtext(%s), \ geomfromtext('%s')) > convert(%s, signed),false)" % \ (geomattr, geometry.wkt, distance) elif spatial_predicate == 'dwithin': spatial_query = "ifnull(distance(geomfromtext(%s), \ geomfromtext('%s')) <= convert(%s, signed),false)" % \ (geomattr, geometry.wkt, distance) else: spatial_query = "ifnull(%s(geomfromtext(%s), \ geomfromtext('%s')),false)" % \ (spatial_predicate, geomattr, geometry.wkt) elif dbtype == 'postgresql+postgis+wkt': # adjust spatial query for PostGIS with WKT geometry column LOGGER.debug('Adjusting spatial query for PostgreSQL+PostGIS+WKT') if spatial_predicate == 'bbox': spatial_predicate = 'intersects' if spatial_predicate == 'beyond': spatial_query = "not st_dwithin(st_geomfromtext(%s), \ st_geomfromtext('%s'), %f)" % \ (geomattr, geometry.wkt, float(distance)) elif spatial_predicate == 'dwithin': spatial_query = "st_dwithin(st_geomfromtext(%s), \ st_geomfromtext('%s'), %f)" % \ (geomattr, geometry.wkt, float(distance)) else: spatial_query = "st_%s(st_geomfromtext(%s), \ st_geomfromtext('%s'))" % \ (spatial_predicate, geomattr, geometry.wkt) elif dbtype == 'postgresql+postgis+native': # adjust spatial query for PostGIS with native geometry LOGGER.debug('Adjusting spatial query for PostgreSQL+PostGIS+native') if spatial_predicate == 'bbox': spatial_predicate = 'intersects' if spatial_predicate == 'beyond': spatial_query = "not st_dwithin(%s, \ st_geomfromtext('%s',4326), %f)" % \ (postgis_geometry_column, geometry.wkt, float(distance)) elif spatial_predicate == 'dwithin': spatial_query = "st_dwithin(%s, \ st_geomfromtext('%s',4326), %f)" % \ (postgis_geometry_column, geometry.wkt, float(distance)) else: spatial_query = "st_%s(%s, \ st_geomfromtext('%s',4326))" % \ (spatial_predicate, postgis_geometry_column, geometry.wkt) else: LOGGER.debug('Adjusting spatial query') spatial_query = "query_spatial(%s,'%s','%s','%s')" % \ (geomattr, geometry.wkt, spatial_predicate, distance) return spatial_query def _get_comparison_operator(element): """return the SQL operator based on Filter query""" element_name = etree.QName(element).localname return MODEL['ComparisonOperators']['ogc:%s' % element_name]['opvalue'] def set_spatial_ranking(geometry): """Given that we have a spatial query in ogc:Filter we check the type of geometry and set the ranking variables""" if util.ranking_enabled: if geometry.type in ['Polygon', 'Envelope']: util.ranking_pass = True util.ranking_query_geometry = geometry.wkt elif geometry.type in ['LineString', 'Point']: from shapely.geometry import box from shapely.wkt import loads,dumps ls = loads(geometry.wkt) b = ls.bounds if geometry.type == 'LineString': tmp_box = box(b[0],b[1],b[2],b[3]) tmp_wkt = dumps(tmp_box) if tmp_box.area > 0: util.ranking_pass = True util.ranking_query_geometry = tmp_wkt elif geometry.type == 'Point': tmp_box = box((float(b[0])-1.0),(float(b[1])-1.0),(float(b[2])+1.0),(float(b[3])+1.0)) tmp_wkt = dumps(tmp_box) util.ranking_pass = True util.ranking_query_geometry = tmp_wkt ================================================ FILE: pycsw/ogc/fes/fes2.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2024 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from pycsw.core import util from pycsw.core.etree import etree from pycsw.ogc.gml import gml32 LOGGER = logging.getLogger(__name__) MODEL = { 'Conformance': { 'values': [ 'ImplementsQuery', 'ImplementsAdHocQuery', 'ImplementsFunctions', 'ImplementsResourceld', 'ImplementsMinStandardFilter', 'ImplementsStandardFilter', 'ImplementsMinSpatialFilter', 'ImplementsSpatialFilter', 'ImplementsMinTemporalFilter', 'ImplementsTemporalFilter', 'ImplementsVersionNav', 'ImplementsSorting', 'ImplementsExtendedOperators', 'ImplementsMinimumXPath', 'ImplementsSchemaElementFunc' ] }, 'GeometryOperands': { 'values': gml32.TYPES }, 'SpatialOperators': { 'values': ['BBOX', 'Beyond', 'Contains', 'Crosses', 'Disjoint', 'DWithin', 'Equals', 'Intersects', 'Overlaps', 'Touches', 'Within'] }, 'ComparisonOperators': { 'fes20:PropertyIsBetween': {'opname': 'PropertyIsBetween', 'opvalue': 'and'}, 'fes20:PropertyIsEqualTo': {'opname': 'PropertyIsEqualTo', 'opvalue': '='}, 'fes20:PropertyIsGreaterThan': {'opname': 'PropertyIsGreaterThan', 'opvalue': '>'}, 'fes20:PropertyIsGreaterThanOrEqualTo': { 'opname': 'PropertyIsGreaterThanOrEqualTo', 'opvalue': '>='}, 'fes20:PropertyIsLessThan': {'opname': 'PropertyIsLessThan', 'opvalue': '<'}, 'fes20:PropertyIsLessThanOrEqualTo': { 'opname': 'PropertyIsLessThanOrEqualTo', 'opvalue': '<='}, 'fes20:PropertyIsLike': {'opname': 'PropertyIsLike', 'opvalue': 'like'}, 'fes20:PropertyIsNotEqualTo': {'opname': 'PropertyIsNotEqualTo', 'opvalue': '!='}, 'fes20:PropertyIsNull': {'opname': 'PropertyIsNull', 'opvalue': 'is null'}, }, 'Functions': { 'length': {'returns': 'xs:string'}, 'lower': {'returns': 'xs:string'}, 'ltrim': {'returns': 'xs:string'}, 'rtrim': {'returns': 'xs:string'}, 'trim': {'returns': 'xs:string'}, 'upper': {'returns': 'xs:string'}, }, 'Ids': { 'values': ['csw30:id'] } } def parse(element, queryables, dbtype, nsmap, orm='sqlalchemy', language='english', fts=False): """OGC Filter object support""" boq = None is_pg = dbtype.startswith('postgresql') tmp = element.xpath('fes20:And|fes20:Or|fes20:Not', namespaces=nsmap) if len(tmp) > 0: # this is binary logic query element_name = etree.QName(tmp[0]).localname boq = ' %s ' % element_name.lower() LOGGER.debug('Binary logic detected; operator=%s', boq) tmp = tmp[0] else: tmp = element pvalue_serial = [0] def assign_param(): if orm == 'django': return '%s' param = ':pvalue%d' % pvalue_serial[0] pvalue_serial[0] += 1 return param def _get_comparison_expression(elem): """return the SQL expression based on Filter query""" fname = None matchcase = elem.attrib.get('matchCase') wildcard = elem.attrib.get('wildCard') singlechar = elem.attrib.get('singleChar') expression = None if wildcard is None: wildcard = '%' if singlechar is None: singlechar = '_' if (elem.xpath('child::*')[0].tag == util.nspath_eval('fes20:Function', nsmap)): LOGGER.debug('fes20:Function detected') if (elem.xpath('child::*')[0].attrib['name'] not in MODEL['Functions']): raise RuntimeError('Invalid fes20:Function: %s' % (elem.xpath('child::*')[0].attrib['name'])) fname = elem.xpath('child::*')[0].attrib['name'] try: LOGGER.debug('Testing existence of fes20:ValueReference') pname = queryables[elem.find(util.nspath_eval('fes20:Function/fes20:ValueReference', nsmap)).text]['dbcol'] except Exception as err: raise RuntimeError('Invalid PropertyName: %s. %s' % (elem.find(util.nspath_eval('fes20:Function/fes20:ValueReference', nsmap)).text, str(err))) from err else: try: LOGGER.debug('Testing existence of fes20:ValueReference') pname = queryables[elem.find( util.nspath_eval('fes20:ValueReference', nsmap)).text]['dbcol'] except Exception as err: raise RuntimeError('Invalid PropertyName: %s. %s' % (elem.find(util.nspath_eval('fes20:ValueReference', nsmap)).text, str(err))) from err if (elem.tag != util.nspath_eval('fes20:PropertyIsBetween', nsmap)): if elem.tag in [util.nspath_eval('fes20:%s' % n, nsmap) for n in MODEL['SpatialOperators']['values']]: boolean_true = '\'true\'' boolean_false = '\'false\'' if dbtype == 'mysql': boolean_true = 'true' boolean_false = 'false' return "%s = %s" % (_get_spatial_operator(queryables['pycsw:BoundingBox'], elem, dbtype, nsmap), boolean_true) else: pval = elem.find(util.nspath_eval('fes20:Literal', nsmap)).text com_op = _get_comparison_operator(elem) LOGGER.debug('Comparison operator: %s', com_op) # if this is a case insensitive search # then set the DB-specific LIKE comparison operator LOGGER.debug('Setting csw:AnyText property') anytext = queryables['csw:AnyText']['dbcol'] if ((matchcase is not None and matchcase == 'false') or pname == anytext): com_op = 'ilike' if is_pg else 'like' if (elem.tag == util.nspath_eval('fes20:PropertyIsBetween', nsmap)): com_op = 'between' lower_boundary = elem.find( util.nspath_eval('fes20:LowerBoundary/fes20:Literal', nsmap)).text upper_boundary = elem.find( util.nspath_eval('fes20:UpperBoundary/fes20:Literal', nsmap)).text expression = "%s %s %s and %s" % \ (pname, com_op, assign_param(), assign_param()) values.append(lower_boundary) values.append(upper_boundary) else: if pname == anytext and is_pg and fts: LOGGER.debug('PostgreSQL FTS specific search') # do nothing, let FTS do conversion (#212) pvalue = pval else: LOGGER.debug('PostgreSQL non-FTS specific search') pvalue = pval.replace(wildcard, '%').replace(singlechar, '_') if pname == anytext: # pad anytext with wildcards LOGGER.debug('PostgreSQL non-FTS specific anytext search') LOGGER.debug('old value: %s', pval) pvalue = '%%%s%%' % pvalue.rstrip('%').lstrip('%') LOGGER.debug('new value: %s', pvalue) values.append(pvalue) if boq == ' not ': if fname is not None: expression = "%s is null or not %s(%s) %s %s" % \ (pname, fname, pname, com_op, assign_param()) elif pname == anytext and is_pg and fts: LOGGER.debug('PostgreSQL FTS specific search') expression = ("%s is null or not plainto_tsquery('%s', %s) @@ anytext_tsvector" % (anytext, language, assign_param())) else: LOGGER.debug('PostgreSQL non-FTS specific search') expression = "%s is null or not %s %s %s" % \ (pname, pname, com_op, assign_param()) else: if fname is not None: expression = "%s(%s) %s %s" % \ (fname, pname, com_op, assign_param()) elif pname == anytext and is_pg and fts: LOGGER.debug('PostgreSQL FTS specific search') expression = ("plainto_tsquery('%s', %s) @@ anytext_tsvector" % (language, assign_param())) else: LOGGER.debug('PostgreSQL non-FTS specific search') expression = "%s %s %s" % (pname, com_op, assign_param()) return expression queries = [] values = [] LOGGER.debug('Scanning children elements') for child in tmp.xpath('child::*'): com_op = '' boolean_true = '\'true\'' boolean_false = '\'false\'' if dbtype == 'mysql': boolean_true = 'true' boolean_false = 'false' if child.tag == util.nspath_eval('fes20:Not', nsmap): LOGGER.debug('fes20:Not query detected') child_not = child.xpath('child::*')[0] if child_not.tag in \ [util.nspath_eval('fes20:%s' % n, nsmap) for n in MODEL['SpatialOperators']['values']]: LOGGER.debug('fes20:Not / spatial operator detected: %s', child.tag) queries.append("%s = %s" % (_get_spatial_operator( queryables['pycsw:BoundingBox'], child.xpath('child::*')[0], dbtype, nsmap), boolean_false)) else: LOGGER.debug('fes20:Not / comparison operator detected: %s', child.tag) queries.append('not %s' % _get_comparison_expression(child_not)) elif child.tag in \ [util.nspath_eval('fes20:%s' % n, nsmap) for n in MODEL['SpatialOperators']['values']]: LOGGER.debug('spatial operator detected: %s', child.tag) if boq is not None and boq == ' not ': # for fes20:Not spatial queries in PostGIS we must explictly # test that pycsw:BoundingBox is null as well # TODO: Do we need the same for 'postgresql+postgis+native'??? if dbtype == 'postgresql+postgis+wkt': LOGGER.debug('Setting bbox is null test in PostgreSQL') queries.append("%s = %s or %s is null" % (_get_spatial_operator( queryables['pycsw:BoundingBox'], child, dbtype, nsmap), boolean_false, queryables['pycsw:BoundingBox'])) else: queries.append("%s = %s" % (_get_spatial_operator( queryables['pycsw:BoundingBox'], child, dbtype, nsmap), boolean_false)) else: queries.append("%s = %s" % (_get_spatial_operator( queryables['pycsw:BoundingBox'], child, dbtype, nsmap), boolean_true)) elif child.tag == util.nspath_eval('fes20:FeatureId', nsmap): LOGGER.debug('fes20:FeatureId filter detected') queries.append("%s = %s" % (queryables['pycsw:Identifier'], assign_param())) values.append(child.attrib.get('fid')) else: # comparison operator LOGGER.debug('Comparison operator processing') child_tag_name = etree.QName(child).localname tagname = ' %s ' % child_tag_name.lower() if tagname in [' or ', ' and ']: # this is a nested binary logic query LOGGER.debug('Nested binary logic detected; operator=%s', tagname) queries_nested = [] for child2 in child.xpath('child::*'): queries_nested.append(_get_comparison_expression(child2)) LOGGER.debug('Nested binary logic queries: %s', queries_nested) queries.append('(%s)' % tagname.join(queries_nested)) else: queries.append(_get_comparison_expression(child)) where = boq.join(queries) if (boq is not None and boq != ' not ') \ else queries[0] return where, values def _get_spatial_operator(geomattr, element, dbtype, nsmap, postgis_geometry_column='wkb_geometry'): """return the spatial predicate function""" property_name = element.find(util.nspath_eval('fes20:ValueReference', nsmap)) distance = element.find(util.nspath_eval('fes20:Distance', nsmap)) distance = 'false' if distance is None else distance.text LOGGER.debug('Scanning for spatial property name') if property_name is None: raise RuntimeError('Missing fes20:ValueReference in spatial filter') if (property_name.text.find('BoundingBox') == -1 and property_name.text.find('Envelope') == -1): raise RuntimeError('Invalid fes20:ValueReference in spatial filter: %s' % property_name.text) geometry = gml32.Geometry(element, nsmap) #make decision to apply spatial ranking to results set_spatial_ranking(geometry) spatial_predicate = etree.QName(element).localname.lower() LOGGER.debug('Spatial predicate: %s', spatial_predicate) if dbtype == 'mysql': # adjust spatial query for MySQL LOGGER.debug('Adjusting spatial query for MySQL') if spatial_predicate == 'bbox': spatial_predicate = 'intersects' if spatial_predicate == 'beyond': spatial_query = "ifnull(distance(geomfromtext(%s), \ geomfromtext('%s')) > convert(%s, signed),false)" % \ (geomattr, geometry.wkt, distance) elif spatial_predicate == 'dwithin': spatial_query = "ifnull(distance(geomfromtext(%s), \ geomfromtext('%s')) <= convert(%s, signed),false)" % \ (geomattr, geometry.wkt, distance) else: spatial_query = "ifnull(%s(geomfromtext(%s), \ geomfromtext('%s')),false)" % \ (spatial_predicate, geomattr, geometry.wkt) elif dbtype == 'postgresql+postgis+wkt': # adjust spatial query for PostGIS with WKT geometry column LOGGER.debug('Adjusting spatial query for PostgreSQL+PostGIS+WKT') if spatial_predicate == 'bbox': spatial_predicate = 'intersects' if spatial_predicate == 'beyond': spatial_query = "not st_dwithin(st_geomfromtext(%s), \ st_geomfromtext('%s'), %f)" % \ (geomattr, geometry.wkt, float(distance)) elif spatial_predicate == 'dwithin': spatial_query = "st_dwithin(st_geomfromtext(%s), \ st_geomfromtext('%s'), %f)" % \ (geomattr, geometry.wkt, float(distance)) else: spatial_query = "st_%s(st_geomfromtext(%s), \ st_geomfromtext('%s'))" % \ (spatial_predicate, geomattr, geometry.wkt) elif dbtype == 'postgresql+postgis+native': # adjust spatial query for PostGIS with native geometry LOGGER.debug('Adjusting spatial query for PostgreSQL+PostGIS+native') if spatial_predicate == 'bbox': spatial_predicate = 'intersects' if spatial_predicate == 'beyond': spatial_query = "not st_dwithin(%s, \ st_geomfromtext('%s',4326), %f)" % \ (postgis_geometry_column, geometry.wkt, float(distance)) elif spatial_predicate == 'dwithin': spatial_query = "st_dwithin(%s, \ st_geomfromtext('%s',4326), %f)" % \ (postgis_geometry_column, geometry.wkt, float(distance)) else: spatial_query = "st_%s(%s, \ st_geomfromtext('%s',4326))" % \ (spatial_predicate, postgis_geometry_column, geometry.wkt) else: LOGGER.debug('Adjusting spatial query') spatial_query = "query_spatial(%s,'%s','%s','%s')" % \ (geomattr, geometry.wkt, spatial_predicate, distance) return spatial_query def _get_comparison_operator(element): """return the SQL operator based on Filter query""" element_name = etree.QName(element).localname return MODEL['ComparisonOperators']['fes20:%s' % element_name]['opvalue'] def set_spatial_ranking(geometry): """Given that we have a spatial query in fes20:Filter we check the type of geometry and set the ranking variables""" if util.ranking_enabled: if geometry.type in ['Polygon', 'Envelope']: util.ranking_pass = True util.ranking_query_geometry = geometry.wkt elif geometry.type in ['LineString', 'Point']: from shapely.geometry import box from shapely.wkt import loads,dumps ls = loads(geometry.wkt) b = ls.bounds if geometry.type == 'LineString': tmp_box = box(b[0],b[1],b[2],b[3]) tmp_wkt = dumps(tmp_box) if tmp_box.area > 0: util.ranking_pass = True util.ranking_query_geometry = tmp_wkt elif geometry.type == 'Point': tmp_box = box((float(b[0])-1.0),(float(b[1])-1.0),(float(b[2])+1.0),(float(b[3])+1.0)) tmp_wkt = dumps(tmp_box) util.ranking_pass = True util.ranking_query_geometry = tmp_wkt ================================================ FILE: pycsw/ogc/gml/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/ogc/gml/gml3.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from owslib import crs from pycsw.core import util from pycsw.core.etree import etree LOGGER = logging.getLogger(__name__) TYPES = ['gml:Point', 'gml:LineString', 'gml:Polygon', 'gml:Envelope'] DEFAULT_SRS = crs.Crs('urn:x-ogc:def:crs:EPSG:6.11:4326') def _poslist2wkt(poslist, axisorder, geomtype): """Repurpose gml:posList into WKT aware list""" tmp = poslist.split() poslist2 = [] if geomtype == 'polygon': len_ = 8 elif geomtype == 'line': len_ = 4 if len(tmp) < len_: msg = 'Invalid number of coordinates in geometry' LOGGER.error(msg) raise RuntimeError(msg) xlist = tmp[::2] ylist = tmp[1::2] if axisorder == 'yx': for i, j in zip(ylist, xlist): poslist2.append('%s %s' % (i, j)) else: for i, j in zip(xlist, ylist): poslist2.append('%s %s' % (i, j)) return ', '.join(poslist2) class Geometry(object): """base geometry class""" def __init__(self, element, nsmap): """initialize geometry parser""" self.nsmap = nsmap self.type = None self.wkt = None self.crs = None self._exml = element # return OGC WKT for GML geometry operand = element.xpath( '|'.join(TYPES), namespaces={'gml': 'http://www.opengis.net/gml'})[0] if 'srsName' in operand.attrib: LOGGER.debug('geometry srsName detected') self.crs = crs.Crs(operand.attrib['srsName']) else: LOGGER.debug('setting default geometry srsName %s', DEFAULT_SRS) self.crs = DEFAULT_SRS self.type = etree.QName(operand).localname if self.type == 'Point': self._get_point() elif self.type == 'LineString': self._get_linestring() elif self.type == 'Polygon': self._get_polygon() elif self.type == 'Envelope': self._get_envelope() else: raise RuntimeError('Unsupported geometry type (Must be one of %s)' % ','.join(TYPES)) # reproject data if needed if self.crs is not None and self.crs.code not in [4326, 'CRS84']: LOGGER.info('transforming geometry to 4326') try: self.wkt = self.transform(self.crs.code, DEFAULT_SRS.code) except Exception as err: LOGGER.exception('Coordinate transformation error') raise RuntimeError('Reprojection error: Invalid srsName') def _get_point(self): """Parse gml:Point""" tmp = self._exml.find(util.nspath_eval('gml:Point/gml:pos', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml:Point geometry. Missing gml:pos') else: xypoint = tmp.text.split() if self.crs.axisorder == 'yx': self.wkt = 'POINT(%s %s)' % (xypoint[1], xypoint[0]) else: self.wkt = 'POINT(%s %s)' % (xypoint[0], xypoint[1]) def _get_linestring(self): """Parse gml:LineString""" tmp = self._exml.find(util.nspath_eval('gml:LineString/gml:posList', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml:LineString geometry.\ Missing gml:posList') else: self.wkt = 'LINESTRING(%s)' % _poslist2wkt(tmp.text, self.crs.axisorder, 'line') def _get_polygon(self): """Parse gml:Polygon""" tmp = self._exml.find('.//%s' % util.nspath_eval('gml:posList', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml:LineString geometry.\ Missing gml:posList') else: self.wkt = 'POLYGON((%s))' % _poslist2wkt(tmp.text, self.crs.axisorder, 'polygon') def _get_envelope(self): """Parse gml:Envelope""" tmp = self._exml.find(util.nspath_eval('gml:Envelope/gml:lowerCorner', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml:Envelope geometry.\ Missing gml:lowerCorner') else: lower_left = tmp.text tmp = self._exml.find(util.nspath_eval('gml:Envelope/gml:upperCorner', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml:Envelope geometry.\ Missing gml:upperCorner') else: upper_right = tmp.text llmin = lower_left.split() urmax = upper_right.split() if len(llmin) < 2 or len(urmax) < 2: raise RuntimeError('Invalid gml:Envelope geometry. \ gml:lowerCorner and gml:upperCorner must hold at least x and y') if self.crs.axisorder == 'yx': self.wkt = util.bbox2wktpolygon('%s,%s,%s,%s' % (llmin[1], llmin[0], urmax[1], urmax[0])) else: self.wkt = util.bbox2wktpolygon('%s,%s,%s,%s' % (llmin[0], llmin[1], urmax[0], urmax[1])) def transform(self, src, dest): """transform coordinates from one CRS to another""" from pyproj import Transformer from shapely.geometry import Point, LineString, Polygon from shapely.wkt import loads LOGGER.info('Transforming geometry from %s to %s', src, dest) vertices = [] try: proj_src = 'epsg:%s' % src proj_dst = 'epsg:%s' % dest transformer = Transformer.from_crs(proj_src, proj_dst, always_xy=True) except Exception as err: msg = f'Invalid projection transformation: {err}' raise RuntimeError(msg) geom = loads(self.wkt) if geom.geom_type == 'Point': newgeom = Point(transformer.transform(geom.x, geom.y)) wkt2 = newgeom.wkt elif geom.geom_type == 'LineString': for vertice in list(geom.coords): newgeom = transformer.transform(vertice[0], vertice[1]) vertices.append(newgeom) linestring = LineString(vertices) wkt2 = linestring.wkt elif geom.geom_type == 'Polygon': for vertice in list(geom.exterior.coords): newgeom = transformer.transform(vertice[0], vertice[1]) vertices.append(newgeom) polygon = Polygon(vertices) wkt2 = polygon.wkt return wkt2 ================================================ FILE: pycsw/ogc/gml/gml32.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from owslib import crs from pycsw.core import util from pycsw.core.etree import etree LOGGER = logging.getLogger(__name__) TYPES = ['gml32:Point', 'gml32:LineString', 'gml32:Polygon', 'gml32:Envelope'] DEFAULT_SRS = crs.Crs('urn:x-ogc:def:crs:EPSG:6.11:4326') def _poslist2wkt(poslist, axisorder, geomtype): """Repurpose gml32:posList into WKT aware list""" tmp = poslist.split() poslist2 = [] if geomtype == 'polygon': len_ = 8 elif geomtype == 'line': len_ = 4 if len(tmp) < len_: msg = 'Invalid number of coordinates in geometry' LOGGER.error(msg) raise RuntimeError(msg) xlist = tmp[::2] ylist = tmp[1::2] if axisorder == 'yx': for i, j in zip(ylist, xlist): poslist2.append('%s %s' % (i, j)) else: for i, j in zip(xlist, ylist): poslist2.append('%s %s' % (i, j)) return ', '.join(poslist2) class Geometry(object): """base geometry class""" def __init__(self, element, nsmap): """initialize geometry parser""" self.nsmap = nsmap self.type = None self.wkt = None self.crs = None self._exml = element # return OGC WKT for GML geometry # self.nsmap['gml'] = 'http://www.opengis.net/gml/3.2' operand = element.xpath( '|'.join(TYPES), namespaces={'gml32': 'http://www.opengis.net/gml/3.2'})[0] if 'srsName' in operand.attrib: LOGGER.debug('geometry srsName detected') self.crs = crs.Crs(operand.attrib['srsName']) else: LOGGER.debug('setting default geometry srsName %s', DEFAULT_SRS) self.crs = DEFAULT_SRS self.type = etree.QName(operand).localname if self.type == 'Point': self._get_point() elif self.type == 'LineString': self._get_linestring() elif self.type == 'Polygon': self._get_polygon() elif self.type == 'Envelope': self._get_envelope() else: raise RuntimeError('Unsupported geometry type (Must be one of %s)' % ','.join(TYPES)) # reproject data if needed if self.crs is not None and self.crs.code not in [4326, 'CRS84']: LOGGER.info('transforming geometry to 4326') try: self.wkt = self.transform(self.crs.code, DEFAULT_SRS.code) except Exception as err: LOGGER.exception('Coordinate transformation error') raise RuntimeError('Reprojection error: Invalid srsName') def _get_point(self): """Parse gml32:Point""" tmp = self._exml.find(util.nspath_eval('gml32:Point/gml32:pos', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml32:Point geometry. Missing gml32:pos') else: xypoint = tmp.text.split() if self.crs.axisorder == 'yx': self.wkt = 'POINT(%s %s)' % (xypoint[1], xypoint[0]) else: self.wkt = 'POINT(%s %s)' % (xypoint[0], xypoint[1]) def _get_linestring(self): """Parse gml32:LineString""" tmp = self._exml.find(util.nspath_eval('gml32:LineString/gml32:posList', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml32:LineString geometry.\ Missing gml32:posList') else: self.wkt = 'LINESTRING(%s)' % _poslist2wkt(tmp.text, self.crs.axisorder, 'line') def _get_polygon(self): """Parse gml32:Polygon""" tmp = self._exml.find('.//%s' % util.nspath_eval('gml32:posList', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml32:LineString geometry.\ Missing gml32:posList') else: self.wkt = 'POLYGON((%s))' % _poslist2wkt(tmp.text, self.crs.axisorder, 'polygon') def _get_envelope(self): """Parse gml32:Envelope""" tmp = self._exml.find(util.nspath_eval('gml32:Envelope/gml32:lowerCorner', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml32:Envelope geometry.\ Missing gml32:lowerCorner') else: lower_left = tmp.text tmp = self._exml.find(util.nspath_eval('gml32:Envelope/gml32:upperCorner', self.nsmap)) if tmp is None: raise RuntimeError('Invalid gml32:Envelope geometry.\ Missing gml32:upperCorner') else: upper_right = tmp.text llmin = lower_left.split() urmax = upper_right.split() if len(llmin) < 2 or len(urmax) < 2: raise RuntimeError('Invalid gml32:Envelope geometry. \ gml32:lowerCorner and gml32:upperCorner must hold at least x and y') if self.crs.axisorder == 'yx': self.wkt = util.bbox2wktpolygon('%s,%s,%s,%s' % (llmin[1], llmin[0], urmax[1], urmax[0])) else: self.wkt = util.bbox2wktpolygon('%s,%s,%s,%s' % (llmin[0], llmin[1], urmax[0], urmax[1])) def transform(self, src, dest): """transform coordinates from one CRS to another""" from pyproj import Transformer from shapely.geometry import Point, LineString, Polygon from shapely.wkt import loads LOGGER.info('Transforming geometry from %s to %s', src, dest) vertices = [] try: proj_src = 'epsg:%s' % src proj_dst = 'epsg:%s' % dest transformer = Transformer.from_crs(proj_src, proj_dst, always_xy=True) except Exception as err: msg = f'Invalid projection transformation: {err}' raise RuntimeError(msg) geom = loads(self.wkt) if geom.type == 'Point': newgeom = Point(transformer.transform(geom.x, geom.y)) wkt2 = newgeom.wkt elif geom.type == 'LineString': for vertice in list(geom.coords): newgeom = transformer.transform(vertice[0], vertice[1]) vertices.append(newgeom) linestring = LineString(vertices) wkt2 = linestring.wkt elif geom.type == 'Polygon': for vertice in list(geom.exterior.coords): newgeom = transformer.transform(vertice[0], vertice[1]) vertices.append(newgeom) polygon = Polygon(vertices) wkt2 = polygon.wkt return wkt2 ================================================ FILE: pycsw/ogc/pubsub/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from datetime import datetime, UTC import json import uuid from typing import Union def publish_message(pubsub_client, url: str, action: str, collection: str = None, item: str = None, data: str = None) -> bool: """ Publish broker message :param pubsub_client: `paho.mqtt.client.Client` instance :param url: `str` of server base URL :param action: `str` of action trigger name (create, update, delete) :param collection: `str` of collection identifier :param item: `str` of item identifier :param data: `str` of data payload :returns: `bool` of whether message publishing was successful """ if pubsub_client.channel is not None: channel = f'{pubsub_client.channel}/collections/{collection}' else: channel = f'collections/{collection}' type_ = f'org.ogc.api.collection.item.{action}' if action in ['create', 'update']: media_type = 'application/geo+json' data_ = data elif action == 'delete': media_type = 'text/plain' data_ = item message = generate_ogc_cloudevent(type_, media_type, url, channel, data_) pubsub_client.connect() pubsub_client.pub(channel, json.dumps(message)) def generate_ogc_cloudevent(type_: str, media_type: str, source: str, subject: str, data: Union[dict, str]) -> dict: """ Generate WIS2 Monitoring Event Message of WCMP2 report :param type_: `str` of CloudEvents type :param source: `str` of source :param subject: `str` of subject :param media_type: `str` of media type :param data: `str` or `dict` of data :returns: `dict` of OGC CloudEvent payload """ try: data2 = json.loads(data) except Exception: if isinstance(data, bytes): data2 = data.decode('utf-8') else: data2 = data message = { 'specversion': '1.0', 'type': type_, 'source': source, 'subject': subject, 'id': str(uuid.uuid4()), 'time': datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%SZ'), 'datacontenttype': media_type, # 'dataschema': 'TODO', 'data': data2 } return message ================================================ FILE: pycsw/opensearch.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2024 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging from pycsw.core import util from pycsw.core.etree import etree LOGGER = logging.getLogger(__name__) QUERY_PARAMETERS = [ 'q', 'bbox', 'time', 'start', 'stop', 'eo:parentidentifier', 'eo:processinglevel', 'eo:producttype', 'eo:platform', 'eo:instrument', 'eo:sensortype', 'eo:cloudcover', 'eo:snowcover', 'eo:spectralrange', 'eo:bands', 'eo:orbitnumber', 'eo:orbitdirection', 'eo:illuminationelevationangle' ] class OpenSearch(object): """OpenSearch wrapper class""" def __init__(self, context): """initialize""" self.namespaces = { 'atom': 'http://www.w3.org/2005/Atom', 'eo': 'http://a9.com/-/opensearch/extensions/eo/1.0/', 'geo': 'http://a9.com/-/opensearch/extensions/geo/1.0/', 'os': 'http://a9.com/-/spec/opensearch/1.1/', 'time': 'http://a9.com/-/opensearch/extensions/time/1.0/', # 'georss': 'http://www.georss.org/georss' } self.context = context self.context.namespaces.update(self.namespaces) self.context.keep_ns_prefixes.append('geo') self.context.keep_ns_prefixes.append('eo') self.context.keep_ns_prefixes.append('time') def response_csw2opensearch(self, element, cfg): """transform a CSW response into an OpenSearch response""" root_tag = etree.QName(element).localname if root_tag == 'ExceptionReport': return element LOGGER.debug('RESPONSE: %s', root_tag) try: version = element.xpath('//@version')[0] except Exception as err: version = '3.0.0' self.exml = element self.cfg = cfg self.bind_url = util.bind_url(self.cfg['server'].get('url')) if self.bind_url.endswith(('/opensearch', '/opensearch?')): self.bind_url = self.bind_url.replace('/opensearch', '/csw') if version == '2.0.2': return self._csw2_2_os() elif version == '3.0.0': return self._csw3_2_os() def _csw2_2_os(self): """CSW 2.0.2 Capabilities to OpenSearch Description""" operation_name = etree.QName(self.exml).localname if operation_name == 'GetRecordsResponse': startindex = int(self.exml.xpath('//@nextRecord')[0]) - int( self.exml.xpath('//@numberOfRecordsReturned')[0]) if startindex < 1: startindex = 1 node = etree.Element(util.nspath_eval('atom:feed', self.context.namespaces), nsmap=self.namespaces) etree.SubElement(node, util.nspath_eval('atom:id', self.context.namespaces)).text = self.cfg['server'].get('url') etree.SubElement(node, util.nspath_eval('atom:title', self.context.namespaces)).text = self.cfg['metadata']['identification']['title'] #etree.SubElement(node, util.nspath_eval('atom:updated', # self.context.namespaces)).text = self.exml.xpath('//@timestamp')[0] etree.SubElement(node, util.nspath_eval('os:totalResults', self.context.namespaces)).text = self.exml.xpath( '//@numberOfRecordsMatched')[0] etree.SubElement(node, util.nspath_eval('os:startIndex', self.context.namespaces)).text = str(startindex) etree.SubElement(node, util.nspath_eval('os:itemsPerPage', self.context.namespaces)).text = self.exml.xpath( '//@numberOfRecordsReturned')[0] for rec in self.exml.xpath('//atom:entry', namespaces=self.context.namespaces): LOGGER.debug('Adding Atom entry') node.append(rec) for rec in self.exml.xpath('//csw:Record|//csw:BriefRecord|//csw:SummaryRecord', namespaces=self.context.namespaces): LOGGER.debug('Converting CSW Record to Atom entry') node.append(self.cswrecord2atom(rec)) elif operation_name == 'Capabilities': node = etree.Element(util.nspath_eval('os:OpenSearchDescription', self.namespaces), nsmap=self.namespaces) etree.SubElement(node, util.nspath_eval('os:ShortName', self.namespaces)).text = self.exml.xpath('//ows:Title', namespaces=self.context.namespaces)[0].text etree.SubElement(node, util.nspath_eval('os:LongName', self.namespaces)).text = self.exml.xpath('//ows:Title', namespaces=self.context.namespaces)[0].text etree.SubElement(node, util.nspath_eval('os:Description', self.namespaces)).text = self.exml.xpath('//ows:Abstract', namespaces=self.context.namespaces)[0].text etree.SubElement(node, util.nspath_eval('os:Tags', self.namespaces)).text = ' '.join(x.text for x in self.exml.xpath('//ows:Keyword', namespaces=self.context.namespaces)) node1 = etree.SubElement(node, util.nspath_eval('os:Url', self.namespaces)) node1.set('type', 'application/atom+xml') node1.set('method', 'get') kvps = { 'mode': 'opensearch', 'service': 'CSW', 'version': '2.0.2', 'request': 'GetRecords', 'elementsetname': 'full', 'typenames': 'csw:Record', 'resulttype': 'results', 'q': '{searchTerms?}', 'bbox': '{geo:box?}', 'time': '{time:start?}/{time:end?}', 'start': '{time:start?}', 'stop': '{time:end?}', 'startposition': '{startIndex?}', 'maxrecords': '{count?}', 'eo:cloudCover': '{eo:cloudCover?}', 'eo:instrument': '{eo:instrument?}', 'eo:orbitDirection': '{eo:orbitDirection?}', 'eo:orbitNumber': '{eo:orbitNumber?}', 'eo:parentIdentifier': '{eo:parentIdentifier?}', 'eo:platform': '{eo:platform?}', 'eo:processingLevel': '{eo:processingLevel?}', 'eo:productType': '{eo:productType?}', 'eo:sensorType': '{eo:sensorType?}', 'eo:snowCover': '{eo:snowCover?}', 'eo:spectralRange': '{eo:spectralRange?}', 'eo:illuminationElevationAngle': '{eo:illuminationElevationAngle?}' } node1.set('template', '%s%s' % (self.bind_url, '&'.join([f'{k}={v}' for k, v in kvps.items()])) ) #node1.set('template', '%smode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&startposition={startIndex?}&maxrecords={count?}' % self.bind_url) node1 = etree.SubElement(node, util.nspath_eval('os:Image', self.namespaces)) node1.set('type', 'image/vnd.microsoft.icon') node1.set('width', '16') node1.set('height', '16') node1.text = 'https://pycsw.org/img/favicon.ico' etree.SubElement(node, util.nspath_eval('os:Developer', self.namespaces)).text = self.exml.xpath('//ows:IndividualName', namespaces=self.context.namespaces)[0].text etree.SubElement(node, util.nspath_eval('os:Context', self.namespaces)).text = self.exml.xpath('//ows:ElectronicMailAddress', namespaces=self.context.namespaces)[0].text etree.SubElement(node, util.nspath_eval('os:Attribution', self.namespaces)).text = self.exml.xpath('//ows:ProviderName', namespaces=self.context.namespaces)[0].text elif operation_name == 'ExceptionReport': node = self.exml else: # return Description document node = etree.Element(util.nspath_eval('os:Description', self.context.namespaces)) return node def _csw3_2_os(self): """CSW 3.0.0 Capabilities to OpenSearch Description""" response_name = etree.QName(self.exml).localname if response_name == 'GetRecordsResponse': startindex = int(self.exml.xpath('//@nextRecord')[0]) - int( self.exml.xpath('//@numberOfRecordsReturned')[0]) if startindex < 1: startindex = 1 node = etree.Element(util.nspath_eval('atom:feed', self.context.namespaces), nsmap=self.namespaces) etree.SubElement(node, util.nspath_eval('atom:id', self.context.namespaces)).text = self.cfg['server'].get('url') etree.SubElement(node, util.nspath_eval('atom:title', self.context.namespaces)).text = self.cfg['metadata']['identification']['title'] author = etree.SubElement(node, util.nspath_eval('atom:author', self.context.namespaces)) etree.SubElement(author, util.nspath_eval('atom:name', self.context.namespaces)).text = self.cfg['metadata']['provider']['name'] etree.SubElement(node, util.nspath_eval('atom:link', self.context.namespaces), rel='search', type='application/opensearchdescription+xml', href='%smode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities' % self.bind_url) etree.SubElement(node, util.nspath_eval('atom:updated', self.context.namespaces)).text = self.exml.xpath('//@timestamp')[0] etree.SubElement(node, util.nspath_eval('os:Query', self.context.namespaces), role='request') matched = sum(int(x) for x in self.exml.xpath('//@numberOfRecordsMatched')) etree.SubElement(node, util.nspath_eval('os:totalResults', self.context.namespaces)).text = str(matched) etree.SubElement(node, util.nspath_eval('os:startIndex', self.context.namespaces)).text = str(startindex) returned = sum(int(x) for x in self.exml.xpath('//@numberOfRecordsReturned')) etree.SubElement(node, util.nspath_eval('os:itemsPerPage', self.context.namespaces)).text = str(returned) for rec in self.exml.xpath('//atom:entry', namespaces=self.context.namespaces): LOGGER.debug('Adding Atom entry') node.append(rec) for rec in self.exml.xpath('//csw30:Record|//csw30:BriefRecord|//csw30:SummaryRecord', namespaces=self.context.namespaces): LOGGER.debug('Converting CSW Record to Atom entry') node.append(self.cswrecord2atom(rec)) elif response_name == 'Capabilities': node = etree.Element(util.nspath_eval('os:OpenSearchDescription', self.namespaces), nsmap=self.namespaces) etree.SubElement(node, util.nspath_eval('os:ShortName', self.namespaces)).text = self.exml.xpath('//ows20:Title', namespaces=self.context.namespaces)[0].text[:16] etree.SubElement(node, util.nspath_eval('os:LongName', self.namespaces)).text = self.exml.xpath('//ows20:Title', namespaces=self.context.namespaces)[0].text etree.SubElement(node, util.nspath_eval('os:Description', self.namespaces)).text = self.exml.xpath('//ows20:Abstract', namespaces=self.context.namespaces)[0].text etree.SubElement(node, util.nspath_eval('os:Tags', self.namespaces)).text = ' '.join(x.text for x in self.exml.xpath('//ows20:Keyword', namespaces=self.context.namespaces)) # Requirement-022 node1 = etree.SubElement(node, util.nspath_eval('os:Url', self.namespaces)) node1.set('type', 'application/xml') kvps = { 'service': 'CSW', 'version': '3.0.0', 'request': 'GetRecords', 'elementsetname': 'full', 'typenames': 'csw:Record', 'outputformat': 'application/xml', 'outputschema': 'http://www.opengis.net/cat/csw/3.0', 'recordids': '{geo:uid?}', 'q': '{searchTerms?}', 'bbox': '{geo:box?}', 'time': '{time:start?}/{time:end?}', 'start': '{time:start?}', 'stop': '{time:end?}', 'startposition': '{startIndex?}', 'maxrecords': '{count?}', 'eo:cloudCover': '{eo:cloudCover?}', 'eo:instrument': '{eo:instrument?}', 'eo:orbitDirection': '{eo:orbitDirection?}', 'eo:orbitNumber': '{eo:orbitNumber?}', 'eo:parentIdentifier': '{eo:parentIdentifier?}', 'eo:platform': '{eo:platform?}', 'eo:processingLevel': '{eo:processingLevel?}', 'eo:productType': '{eo:productType?}', 'eo:sensorType': '{eo:sensorType?}', 'eo:snowCover': '{eo:snowCover?}', 'eo:spectralRange': '{eo:spectralRange?}', 'eo:illuminationElevationAngle': '{eo:illuminationElevationAngle?}' } node1.set('template', '%s%s' % (self.bind_url, '&'.join(f'{k}={v}' for k, v in kvps.items()))) # Requirement-023 node1 = etree.SubElement(node, util.nspath_eval('os:Url', self.namespaces)) node1.set('type', 'application/atom+xml') kvps['outputformat'] = r'application%2Fatom%2Bxml' kvps['mode'] = 'opensearch' node1.set('template', '%s%s' % (self.bind_url, '&'.join(f'{k}={v}' for k, v in kvps.items()))) node1 = etree.SubElement(node, util.nspath_eval('os:Image', self.namespaces)) node1.set('type', 'image/vnd.microsoft.icon') node1.set('width', '16') node1.set('height', '16') node1.text = 'https://pycsw.org/img/favicon.ico' os_query = etree.SubElement(node, util.nspath_eval('os:Query', self.namespaces), role='example', searchTerms='cat') etree.SubElement(node, util.nspath_eval('os:Developer', self.namespaces)).text = self.exml.xpath('//ows20:IndividualName', namespaces=self.context.namespaces)[0].text etree.SubElement(node, util.nspath_eval('os:Contact', self.namespaces)).text = self.exml.xpath('//ows20:ElectronicMailAddress', namespaces=self.context.namespaces)[0].text etree.SubElement(node, util.nspath_eval('os:Attribution', self.namespaces)).text = self.exml.xpath('//ows20:ProviderName', namespaces=self.context.namespaces)[0].text elif response_name == 'ExceptionReport': node = self.exml else: # GetRecordById output node = etree.Element(util.nspath_eval('atom:feed', self.context.namespaces), nsmap=self.namespaces) etree.SubElement(node, util.nspath_eval('atom:id', self.context.namespaces)).text = self.cfg['server'].get('url') etree.SubElement(node, util.nspath_eval('atom:title', self.context.namespaces)).text = self.cfg['metadata']['identification']['title'] #etree.SubElement(node, util.nspath_eval('atom:updated', # self.context.namespaces)).text = self.exml.xpath('//@timestamp')[0] etree.SubElement(node, util.nspath_eval('os:totalResults', self.context.namespaces)).text = '1' etree.SubElement(node, util.nspath_eval('os:startIndex', self.context.namespaces)).text = '1' etree.SubElement(node, util.nspath_eval('os:itemsPerPage', self.context.namespaces)).text = '1' for rec in self.exml.xpath('//atom:entry', namespaces=self.context.namespaces): #node.append(rec) node = rec return node def cswrecord2atom(self, rec): entry = etree.Element(util.nspath_eval('atom:entry', self.namespaces)) etree.SubElement(entry, util.nspath_eval('atom:id', self.context.namespaces)).text = rec.xpath('dc:identifier', namespaces=self.context.namespaces)[0].text etree.SubElement(entry, util.nspath_eval('dc:identifier', self.context.namespaces)).text = rec.xpath('dc:identifier', namespaces=self.context.namespaces)[0].text etree.SubElement(entry, util.nspath_eval('atom:title', self.context.namespaces)).text = rec.xpath('dc:title', namespaces=self.context.namespaces)[0].text dc_date = rec.xpath('dc:date', namespaces=self.context.namespaces) if dc_date: etree.SubElement(entry, util.nspath_eval('atom:updated', self.context.namespaces)).text = dc_date[0].text for s in rec.xpath('dc:subject', namespaces=self.context.namespaces): etree.SubElement(entry, util.nspath_eval('atom:category', self.context.namespaces), term=s.text) for d in rec.xpath('dct:references', namespaces=self.context.namespaces): link = etree.SubElement(entry, util.nspath_eval('atom:link', self.context.namespaces)) link.attrib['href'] = d.text scheme = d.attrib.get('scheme') if scheme is not None: if scheme == 'enclosure': link.attrib['rel'] = scheme link.attrib['type'] = 'application/octet-stream' else: link.attrib['type'] = scheme bbox = rec.xpath('ows:BoundingBox|ows20:BoundingBox', namespaces=self.context.namespaces) if bbox: where = etree.SubElement(entry, util.nspath_eval('georss:where', {'georss': 'http://www.georss.org/georss'})) envelope = etree.SubElement(where, util.nspath_eval('gml:Envelope', self.context.namespaces)) envelope.attrib['srsName'] = bbox[0].attrib.get('crs') etree.SubElement(envelope, util.nspath_eval('gml:lowerCorner', self.context.namespaces)).text = bbox[0].xpath('ows:LowerCorner|ows20:LowerCorner', namespaces=self.context.namespaces)[0].text etree.SubElement(envelope, util.nspath_eval('gml:upperCorner', self.context.namespaces)).text = bbox[0].xpath('ows:UpperCorner|ows20:UpperCorner', namespaces=self.context.namespaces)[0].text return entry def kvp2filterxml(kvp, context, profiles, fes_version='1.0'): ''' transform kvp to filter XML string ''' bbox_element = None time_element = None anytext_elements = [] query_temporal_by_iso = False start_stop_elements_only = False eo_parentidentifier_element = None eo_bands_element = None eo_cloudcover_element = None eo_instrument_element = None eo_orbitdirection_element = None eo_orbitnumber_element = None eo_platform_element = None eo_processinglevel_element = None eo_producttype_element = None eo_sensortype_element = None eo_snowcover_element = None eo_illuminationelevationangle_element = None if profiles is not None and 'plugins' in profiles and 'APISO' in profiles['plugins']: query_temporal_by_iso = True # Count parameters par_count = 0 for p in ['q','bbox','time']: if p in kvp and kvp[p] != '': par_count += 1 # Create root element for FilterXML root = etree.Element(util.nspath_eval('ogc:Filter', context.namespaces)) # bbox to FilterXML if 'bbox' in kvp and kvp['bbox'] != '': LOGGER.debug('Detected bbox parameter') bbox_list = [x.strip() for x in kvp['bbox'].split(',')] bbox_element = etree.Element(util.nspath_eval('ogc:BBOX', context.namespaces)) el = etree.Element(util.nspath_eval('ogc:PropertyName', context.namespaces)) el.text = 'ows:BoundingBox' bbox_element.append(el) env = etree.Element(util.nspath_eval('gml:Envelope', context.namespaces)) el = etree.Element(util.nspath_eval('gml:lowerCorner', context.namespaces)) if len(bbox_list) == 5: # add srsName LOGGER.debug('Found CRS') env.attrib['srsName'] = bbox_list[4] else: LOGGER.debug('Assuming 4326') env.attrib['srsName'] = 'urn:ogc:def:crs:OGC:1.3:CRS84' if not validate_4326(bbox_list): msg = '4326 coordinates out of range: %s' % bbox_list LOGGER.error(msg) raise RuntimeError(msg) try: el.text = "%s %s" % (bbox_list[0], bbox_list[1]) except Exception as err: errortext = 'Exception: OpenSearch bbox not valid.\nError: %s.' % str(err) LOGGER.exception(errortext) env.append(el) el = etree.Element(util.nspath_eval('gml:upperCorner', context.namespaces)) try: el.text = "%s %s" % (bbox_list[2], bbox_list[3]) except Exception as err: errortext = 'Exception: OpenSearch bbox not valid.\nError: %s.' % str(err) LOGGER.exception(errortext) env.append(el) bbox_element.append(env) # q to FilterXML if 'q' in kvp and kvp['q'] != '': LOGGER.debug('Detected q parameter') qvals = kvp['q'].split() LOGGER.debug(qvals) if len(qvals) > 1: par_count += 1 for qval in qvals: LOGGER.debug('processing q token') anytext_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces)) el = etree.Element(util.nspath_eval('ogc:PropertyName', context.namespaces)) el.text = 'csw:AnyText' anytext_element.append(el) el = etree.Element(util.nspath_eval('ogc:Literal', context.namespaces)) el.text = qval anytext_element.append(el) anytext_elements.append(anytext_element) if ('start' in kvp or 'stop' in kvp) and 'time' not in kvp: start_stop_elements_only = True LOGGER.debug('Detected start/stop in KVP') kvp['time'] = '' if 'start' in kvp and kvp['start'] != '': kvp['time'] = kvp['start'] + '/' if 'stop' in kvp and kvp['stop'] != '': if len(kvp['time']) > 0: kvp['time'] += kvp['stop'] else: kvp['time'] = '/' + kvp['stop'] LOGGER.debug(f'new KVP time: {kvp["time"]}') # time to FilterXML if 'time' in kvp and kvp['time'] != '': LOGGER.debug('Detected time parameter %s', kvp['time']) time_list = kvp['time'].split("/") LOGGER.debug('TIMELIST: %s', time_list) if len(time_list) == 2: if '' not in time_list: # both dates present LOGGER.debug('Both dates present') if query_temporal_by_iso: LOGGER.debug('Querying by ISO data extent') time_element = etree.Element(util.nspath_eval('ogc:And', context.namespaces)) begin_element = etree.Element(util.nspath_eval('ogc:PropertyIsGreaterThanOrEqualTo', context.namespaces)) etree.SubElement(begin_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:TempExtent_begin' etree.SubElement(begin_element, util.nspath_eval('ogc:Literal', context.namespaces)).text = time_list[0] end_element = etree.Element(util.nspath_eval('ogc:PropertyIsLessThanOrEqualTo', context.namespaces)) etree.SubElement(end_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:TempExtent_end' etree.SubElement(end_element, util.nspath_eval('ogc:Literal', context.namespaces)).text = time_list[1] time_element.append(begin_element) time_element.append(end_element) else: LOGGER.debug('Querying by DC date') time_element = etree.Element(util.nspath_eval('ogc:PropertyIsBetween', context.namespaces)) el = etree.Element(util.nspath_eval('ogc:PropertyName', context.namespaces)) el.text = 'dc:date' time_element.append(el) el = etree.Element(util.nspath_eval('ogc:LowerBoundary', context.namespaces)) el2 = etree.Element(util.nspath_eval('ogc:Literal', context.namespaces)) el2.text = time_list[0] el.append(el2) time_element.append(el) el = etree.Element(util.nspath_eval('ogc:UpperBoundary', context.namespaces)) el2 = etree.Element(util.nspath_eval('ogc:Literal', context.namespaces)) el2.text = time_list[1] el.append(el2) time_element.append(el) else: # one is empty LOGGER.debug('Querying by open-ended date') if time_list == ['', '']: par_count -= 1 # One of two is empty elif time_list[1] == '': # start datetime but no end datetime time_element = etree.Element(util.nspath_eval('ogc:PropertyIsGreaterThanOrEqualTo', context.namespaces)) el = etree.Element(util.nspath_eval('ogc:PropertyName', context.namespaces)) if query_temporal_by_iso: el.text = 'apiso:TempExtent_begin' else: el.text = 'dc:date' time_element.append(el) el = etree.Element(util.nspath_eval('ogc:Literal', context.namespaces)) el.text = time_list[0] time_element.append(el) else: # end datetime but no start datetime time_element = etree.Element(util.nspath_eval('ogc:PropertyIsLessThanOrEqualTo', context.namespaces)) el = etree.Element(util.nspath_eval('ogc:PropertyName', context.namespaces)) if query_temporal_by_iso: el.text = 'apiso:TempExtent_end' else: el.text = 'dc:date' time_element.append(el) el = etree.Element(util.nspath_eval('ogc:Literal', context.namespaces)) el.text = time_list[1] time_element.append(el) elif ((len(time_list) == 1) and ('' not in time_list)): LOGGER.debug('Querying time instant via dc:date') # This is an equal request time_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces)) el = etree.Element(util.nspath_eval('ogc:PropertyName', context.namespaces)) el.text = 'dc:date' time_element.append(el) el = etree.Element(util.nspath_eval('ogc:Literal', context.namespaces)) el.text = time_list[0] time_element.append(el) else: # Error errortext = 'Exception: OpenSearch time not valid: %s.' % str(kvp['time']) LOGGER.error(errortext) if time_element is not None and start_stop_elements_only: par_count += 1 LOGGER.debug('Processing EO queryables') if not util.is_none_or_empty(kvp.get('eo:parentidentifier')): par_count += 1 eo_parentidentifier_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces)) etree.SubElement(eo_parentidentifier_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:ParentIdentifier' etree.SubElement(eo_parentidentifier_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = kvp['eo:parentidentifier'] if not util.is_none_or_empty(kvp.get('eo:producttype')): par_count += 1 eo_producttype_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces), matchCase='false', wildCard='*', singleChar='?', escapeChar='\\') etree.SubElement(eo_producttype_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject' etree.SubElement(eo_producttype_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = '*eo:productType:%s*' % kvp['eo:producttype'] if not util.is_none_or_empty(kvp.get('eo:platform')): par_count += 1 eo_platform_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces)) etree.SubElement(eo_platform_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Platform' etree.SubElement(eo_platform_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = kvp['eo:platform'] if not util.is_none_or_empty(kvp.get('eo:processinglevel')): par_count += 1 eo_processinglevel_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces), matchCase='false', wildCard='*', singleChar='?', escapeChar='\\') etree.SubElement(eo_processinglevel_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject' etree.SubElement(eo_processinglevel_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = '*eo:processingLevel:%s*' % kvp['eo:processinglevel'] if not util.is_none_or_empty(kvp.get('eo:instrument')): par_count += 1 eo_instrument_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces)) etree.SubElement(eo_instrument_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Instrument' etree.SubElement(eo_instrument_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = kvp['eo:instrument'] if not util.is_none_or_empty(kvp.get('eo:sensortype')): par_count += 1 eo_sensortype_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces)) etree.SubElement(eo_sensortype_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:SensorType' etree.SubElement(eo_sensortype_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = kvp['eo:sensortype'] if not util.is_none_or_empty(kvp.get('eo:cloudcover')): par_count += 1 eo_cloudcover_element = evaluate_literal(context, 'apiso:CloudCover', kvp['eo:cloudcover']) if not util.is_none_or_empty(kvp.get('eo:snowcover')): par_count += 1 eo_snowcover_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces), matchCase='false', wildCard='*', singleChar='?', escapeChar='\\') etree.SubElement(eo_snowcover_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject' etree.SubElement(eo_snowcover_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = '*eo:snowCover:%s*' % kvp['eo:snowcover'] if not util.is_none_or_empty(kvp.get('eo:spectralrange')): par_count += 1 eo_bands_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces), matchCase='false', wildCard='*', singleChar='?', escapeChar='\\') etree.SubElement(eo_bands_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Bands' etree.SubElement(eo_bands_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = '*%s*' % kvp['eo:spectralrange'] if not util.is_none_or_empty(kvp.get('eo:illuminationelevationangle')): par_count += 1 eo_illuminationelevationangle_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces), matchCase='false', wildCard='*', singleChar='?', escapeChar='\\') etree.SubElement(eo_illuminationelevationangle_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:IlluminationElevationAngle' etree.SubElement(eo_illuminationelevationangle_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = '*%s*' % kvp['eo:illuminationelevationangle'] if not util.is_none_or_empty(kvp.get('eo:orbitnumber')): par_count += 1 eo_orbitnumber_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces), matchCase='false', wildCard='*', singleChar='?', escapeChar='\\') etree.SubElement(eo_orbitnumber_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject' etree.SubElement(eo_orbitnumber_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = '*eo:orbitNumber:%s*' % kvp['eo:orbitnumber'] if not util.is_none_or_empty(kvp.get('eo:orbitdirection')): par_count += 1 eo_orbitdirection_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces), matchCase='false', wildCard='*', singleChar='?', escapeChar='\\') etree.SubElement(eo_orbitdirection_element, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject' etree.SubElement(eo_orbitdirection_element, util.nspath_eval( 'ogc:Literal', context.namespaces)).text = '*eo:orbitDirection:%s*' % kvp['eo:orbitdirection'] LOGGER.info('Query parameter count: %s', par_count) if par_count == 0: return '' elif par_count == 1: LOGGER.debug('Single predicate filter') # Only one OpenSearch parameter exists if 'bbox' in kvp and kvp['bbox'] != '': LOGGER.debug('Adding bbox') root.append(bbox_element) elif time_element is not None: LOGGER.debug('Adding time') root.append(time_element) elif anytext_elements: LOGGER.debug('Adding anytext') root.extend(anytext_elements) elif par_count > 1: LOGGER.debug('ogc:And query (%d predicates)', par_count) # Since more than 1 parameter, append the AND logical operator logical_and = etree.Element(util.nspath_eval('ogc:And', context.namespaces)) if bbox_element is not None: logical_and.append(bbox_element) if time_element is not None: logical_and.append(time_element) if anytext_elements is not None: logical_and.extend(anytext_elements) root.append(logical_and) if par_count == 1: node_to_append = root elif par_count > 1: node_to_append = logical_and LOGGER.debug('Adding EO queryables') for eo_element in [eo_producttype_element, eo_platform_element, eo_instrument_element, eo_sensortype_element, eo_cloudcover_element, eo_snowcover_element, eo_bands_element, eo_orbitnumber_element, eo_orbitdirection_element, eo_processinglevel_element, eo_parentidentifier_element, eo_illuminationelevationangle_element]: if eo_element is not None: node_to_append.append(eo_element) # Render etree to string XML filterstring = etree.tostring(root, encoding='unicode') if fes_version == '2.0': filterstring = filterstring.replace('PropertyName', 'ValueReference')\ .replace('xmlns:ogc="http://www.opengis.net/ogc"', 'xmlns:fes20="http://www.opengis.net/fes/2.0"')\ .replace('ogc:', 'fes20:')\ .replace('xmlns:gml311="http://www.opengis.net/gml"', 'xmlns:gml32="http://www.opengis.net/gml/3.2"')\ .replace('gml311:', 'gml32:') LOGGER.debug(filterstring) return filterstring def evaluate_literal(context, pname, pvalue): """ Transforms OpenSearch EO mathematical notation to OGC FES syntax :param pname: parameter name :param pvalue: parameter value :returns: lxml Element of predicate """ LOGGER.debug(f'property name: {pname}') LOGGER.debug(f'property value: {pvalue}') if pvalue.startswith('{') and pvalue.endswith('}'): # {n1,n2,…} equals to field=n1 OR field=n2 OR … values = pvalue.lstrip('{').rstrip('}').split(',') el = etree.Element(util.nspath_eval('ogc:Or', context.namespaces)) for value in values: el2 = etree.SubElement(el, util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces)) etree.SubElement(el2, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el2, util.nspath_eval('ogc:Literal', context.namespaces)).text = value elif pvalue.startswith('[') and pvalue.endswith(']'): # [n1,n2] equal to n1 <= field <= n2 values = pvalue.lstrip('[').rstrip(']').split(',') el = etree.Element(util.nspath_eval('ogc:And', context.namespaces)) el2 = etree.SubElement(el, util.nspath_eval('ogc:PropertyIsLessThanOrEqualTo', context.namespaces)) etree.SubElement(el2, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el2, util.nspath_eval('ogc:Literal', context.namespaces)).text = values[0] el3 = etree.SubElement(el, util.nspath_eval('ogc:PropertyIsGreaterThanOrEqualTo', context.namespaces)) etree.SubElement(el3, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el3, util.nspath_eval('ogc:Literal', context.namespaces)).text = values[1] elif pvalue.startswith(']') and pvalue.endswith('['): # ]n1,n2[ equals to n1 < field < n2 values = pvalue.lstrip(']').rstrip('[').split(',') el = etree.Element(util.nspath_eval('ogc:And', context.namespaces)) el2 = etree.SubElement(el, util.nspath_eval('ogc:PropertyIsLessThan', context.namespaces)) etree.SubElement(el2, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el2, util.nspath_eval('ogc:Literal', context.namespaces)).text = values[0] el3 = etree.SubElement(el, util.nspath_eval('ogc:PropertyIsGreaterThan', context.namespaces)) etree.SubElement(el3, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el3, util.nspath_eval('ogc:Literal', context.namespaces)).text = values[1] elif pvalue.startswith('['): # [n1 equals to n1<= field el = etree.Element(util.nspath_eval('ogc:PropertyIsGreaterThanOrEqualTo', context.namespaces)) etree.SubElement(el, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el, util.nspath_eval('ogc:Literal', context.namespaces)).text = pvalue.lstrip('[') elif pvalue.endswith(']'): # n2] equals to field <= n2 el = etree.Element(util.nspath_eval('ogc:PropertyIsLessThanOrEqualTo', context.namespaces)) etree.SubElement(el, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el, util.nspath_eval('ogc:Literal', context.namespaces)).text = pvalue.rstrip(']') elif pvalue.startswith('[') and pvalue.endswith('['): # [n1,n2[ equals to n1 <= field < n2 values = pvalue.lstrip('[').rstrip('[').split(',') el = etree.Element(util.nspath_eval('ogc:And', context.namespaces)) el2 = etree.SubElement(el, util.nspath_eval('ogc:PropertyIsLessThanOrEqualTo', context.namespaces)) etree.SubElement(el2, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el2, util.nspath_eval('ogc:Literal', context.namespaces)).text = values[0] el3 = etree.SubElement(el, util.nspath_eval('ogc:PropertyIsGreaterThan', context.namespaces)) etree.SubElement(el3, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el3, util.nspath_eval('ogc:Literal', context.namespaces)).text = values[1] elif pvalue.startswith(']') and pvalue.endswith(']'): # ]n1,n2] equal to n1 < field <= n2 values = pvalue.lstrip(']').rstrip(']').split(',') el = etree.Element(util.nspath_eval('ogc:And', context.namespaces)) el2 = etree.SubElement(el, util.nspath_eval('ogc:PropertyIsLessThan', context.namespaces)) etree.SubElement(el2, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el2, util.nspath_eval('ogc:Literal', context.namespaces)).text = values[0] el3 = etree.SubElement(el, util.nspath_eval('ogc:PropertyIsGreaterThanOrEqualTo', context.namespaces)) etree.SubElement(el3, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el3, util.nspath_eval('ogc:Literal', context.namespaces)).text = values[1] elif pvalue.startswith(']'): # ]n1 equals to n1 < field el = etree.Element(util.nspath_eval('ogc:PropertyIsGreaterThan', context.namespaces)) etree.SubElement(el, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el, util.nspath_eval('ogc:Literal', context.namespaces)).text = pvalue.lstrip(']') elif pvalue.endswith('['): # n2[ equals to field < n2 el = etree.Element(util.nspath_eval('ogc:PropertyIsLessThan', context.namespaces)) etree.SubElement(el, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el, util.nspath_eval('ogc:Literal', context.namespaces)).text = pvalue.rstrip('[') else: # n1 equal to field = n1 el = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces)) etree.SubElement(el, util.nspath_eval('ogc:PropertyName', context.namespaces)).text = pname etree.SubElement(el, util.nspath_eval('ogc:Literal', context.namespaces)).text = pvalue return el def validate_4326(bbox_list): """Helper function to validate 4326.""" is_valid = False if ((-180.0 <= float(bbox_list[0]) <= 180.0) and (-90.0 <= float(bbox_list[1]) <= 90.0) and (-180.0 <= float(bbox_list[2]) <= 180.0) and (-90.0 <= float(bbox_list[3]) <= 90.0)): is_valid = True return is_valid ================================================ FILE: pycsw/plugins/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/plugins/outputschemas/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= __all__ = ['atom', 'dif', 'fgdc', 'gm03', 'datacite'] ================================================ FILE: pycsw/plugins/outputschemas/atom.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from pycsw.core import util from pycsw.core.etree import etree NAMESPACE = 'http://www.w3.org/2005/Atom' NAMESPACES = {'atom': NAMESPACE, 'georss': 'http://www.georss.org/georss'} XPATH_MAPPINGS = { 'pycsw:Identifier': 'atom:id', 'pycsw:Title': 'atom:title', 'pycsw:Creator': 'atom:author', 'pycsw:Abstract': 'atom:summary', 'pycsw:PublicationDate': 'atom:published', 'pycsw:Keywords': 'atom:category', 'pycsw:Contributor': 'atom:contributor', 'pycsw:AccessConstraints': 'atom:rights', 'pycsw:Modified': 'atom:updated', 'pycsw:Source': 'atom:source', } def write_record(result, esn, context, url=None): ''' Return csw:SearchResults child as lxml.etree.Element ''' typename = util.getqattr(result, context.md_core_model['mappings']['pycsw:Typename']) if esn == 'full' and typename == 'atom:entry': # dump record as is and exit return etree.fromstring(util.getqattr(result, context.md_core_model['mappings']['pycsw:XML']), context.parser) node = etree.Element(util.nspath_eval('atom:entry', NAMESPACES), nsmap=NAMESPACES) node.attrib[util.nspath_eval('xsi:schemaLocation', context.namespaces)] = \ '%s http://www.kbcafe.com/rss/atom.xsd.xml' % NAMESPACES['atom'] # author val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Creator']) if val: author = etree.SubElement(node, util.nspath_eval('atom:author', NAMESPACES)) etree.SubElement(author, util.nspath_eval('atom:name', NAMESPACES)).text = val # category val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Keywords']) if val: for kw in val.split(','): etree.SubElement(node, util.nspath_eval('atom:category', NAMESPACES), term=kw) for qval in ['pycsw:Contributor', 'pycsw:Identifier']: val = util.getqattr(result, context.md_core_model['mappings'][qval]) if val: etree.SubElement(node, util.nspath_eval(XPATH_MAPPINGS[qval], NAMESPACES)).text = val if qval == 'pycsw:Identifier': etree.SubElement(node, util.nspath_eval('dc:identifier', context.namespaces)).text = val rlinks = util.getqattr(result, context.md_core_model['mappings']['pycsw:Links']) if rlinks: for link in util.jsonify_links(rlinks): url2 = etree.SubElement(node, util.nspath_eval('atom:link', NAMESPACES), href=link['url']) if link.get('description') is not None: url2.attrib['title'] = link['description'] if link.get('protocol') is not None: url2.attrib['type'] = link['protocol'] if link.get('function') is not None: url2.attrib['rel'] = link['function'] etree.SubElement(node, util.nspath_eval('atom:link', NAMESPACES), href='%s?service=CSW&version=2.0.2&request=GetRepositoryItem&id=%s' % (url, util.getqattr(result, context.md_core_model['mappings']['pycsw:Identifier']))) # atom:title el = etree.SubElement(node, util.nspath_eval(XPATH_MAPPINGS['pycsw:Title'], NAMESPACES)) val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Title']) if val: el.text =val # atom:updated el = etree.SubElement(node, util.nspath_eval(XPATH_MAPPINGS['pycsw:Modified'], NAMESPACES)) val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Modified']) if val: el.text =val else: val = util.getqattr(result, context.md_core_model['mappings']['pycsw:InsertDate']) el.text = val for qval in ['pycsw:PublicationDate', 'pycsw:AccessConstraints', 'pycsw:Source', 'pycsw:Abstract']: val = util.getqattr(result, context.md_core_model['mappings'][qval]) if val: etree.SubElement(node, util.nspath_eval(XPATH_MAPPINGS[qval], NAMESPACES)).text = val # bbox extent val = util.getqattr(result, context.md_core_model['mappings']['pycsw:BoundingBox']) bboxel = write_extent(val, context.namespaces) if bboxel is not None: node.append(bboxel) return node def write_extent(bbox, nsmap): ''' Generate BBOX extent ''' if bbox is not None: try: bbox2 = util.wkt2geom(bbox) except Exception as err: LOGGER.debug(f'Geometry parsing error: {err}') return None where = etree.Element(util.nspath_eval('georss:where', NAMESPACES)) envelope = etree.SubElement(where, util.nspath_eval('gml:Envelope', nsmap), srsName='http://www.opengis.net/def/crs/EPSG/0/4326') etree.SubElement(envelope, util.nspath_eval('gml:lowerCorner', nsmap)).text = '%s %s' % (bbox2[1], bbox2[0]) etree.SubElement(envelope, util.nspath_eval('gml:upperCorner', nsmap)).text = '%s %s' % (bbox2[3], bbox2[2]) return where return None ================================================ FILE: pycsw/plugins/outputschemas/datacite.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # - pycsw DataCite output plugin - # # Authors: Carl-Fredrik Enell , Paul van Genuchten # Based on pycsw plugins by Tom Kralidis # DataCite schema follows: # https://github.com/inveniosoftware/datacite/blob/master/datacite/schema42.py # https://schema.datacite.org/meta/kernel-4.3/example/datacite-example-full-v4.xml # # This module intends to follow DataCite 4.3 # # PyCSW Copyright (C) 2024 Tom Kralidis # Schema Copyright (C) 2016 CERN # Schema Copyright (C) 2019 Caltech # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from pycsw.core import util from pycsw.core.etree import etree from os.path import basename from datetime import datetime import json import logging """ datacite.py Output plugin for DataCite 4.3 schema output Defines function write_record Input: result, esn, context, url (pycsw query results) Output: XML etree according to DataCite schema """ NAMESPACE = 'http://datacite.org/schema/kernel-4' NAMESPACES = {'xml': 'http://www.w3.org/XML/1998/namespace', 'datacite': NAMESPACE, 'oai': 'http://www.openarchives.org/OAI/2.0/'} LOGGER = logging.getLogger(__name__) XPATH_MAPPINGS = { 'pycsw:Identifier': 'identifier', 'pycsw:Date': 'dates/date', 'pycsw:Creator': 'creators/creator', 'pycsw:Title': 'titles/title', 'pycsw:Abstract': 'descriptions/description', 'pycsw:Publisher': 'publisher', 'pycsw:BoundingBox': 'geoLocations/geoLocation/geoLocationBox', 'pycsw:Format': 'formats/format', 'pycsw:Language': 'Language', 'pycsw:Edition': 'version', 'pycsw:PublicationDate': 'dates/date', 'pycsw:Keywords': 'subjects/subject', 'pycsw:TopicCategory': 'subjects/subject', 'pycsw:Themes': 'subjects/subject', 'pycsw:Lineage': 'lineage', 'pycsw:TempExtent_begin': '', 'pycsw:TempExtent_end': '', 'pycsw:Contributor': '', 'pycsw:AccessConstraints': '', 'pycsw:Contacts': '', 'pycsw:Links': '' } def write_record(result, esn, context, url=None): """ Main function Return csw:SearchResults child as lxml.etree.Element """ typename = util.getqattr(result, context.md_core_model['mappings']['pycsw:Typename']) # Check if we already have DataCite formatted metadata if esn == 'full' and typename == 'datacite': # dump record as is and exit return etree.fromstring(util.getqattr(result, context.md_core_model['mappings']['pycsw:XML']), context.parser) # Otherwise build XML tree from available metadata node = etree.Element(util.nspath_eval('resource', NAMESPACES)) node.attrib[util.nspath_eval('xsi:schemaLocation', context.namespaces)] = \ '%s http://schema.datacite.org/meta/kernel-4.3/metadata.xsd' % NAMESPACE # Type type = etree.SubElement(node, util.nspath_eval('resourceType', NAMESPACES)) resTypeGeneral = basename(util.getqattr(result, context.md_core_model['mappings']['pycsw:Type'])) type.text = resTypeGeneral if resTypeGeneral.lower() in ["dataset","nongeographicdataset","featuretype","transferaggregate","otheraggregate"]: resTypeGeneral = "Dataset" elif resTypeGeneral.lower() in ["software"]: resTypeGeneral = "Software" elif resTypeGeneral.lower() in ["collectionSession","fieldSession"]: resTypeGeneral = "Event" elif resTypeGeneral.lower() in ["service"]: resTypeGeneral = "Service" elif resTypeGeneral.lower() in ["model"]: resTypeGeneral = "Model" elif resTypeGeneral.lower() in ["series"]: resTypeGeneral = "Collection" elif resTypeGeneral.lower() in ["text","document","article"]: resTypeGeneral = "Text" elif resTypeGeneral.lower() in ["image"]: resTypeGeneral = "Image" else: resTypeGeneral = "Other" assert resTypeGeneral in [ "Audiovisual", "Book", "BookChapter", "Collection", "ComputationalNotebook", "ConferencePaper", "ConferenceProceeding", "DataPaper", "Dataset", "Dissertation", "Event", "Image", "InteractiveResource", "Journal", "JournalArticle", "Model", "OutputManagementPlan", "PeerReview", "PhysicalObject", "Preprint", "Report", "Service", "Software", "Sound", "Standard", "Text", "Workflow", "Other" ] type.attrib[util.nspath_eval('resourceTypeGeneral', NAMESPACES)] = resTypeGeneral # Identifier ident = etree.SubElement(node, util.nspath_eval('identifier', NAMESPACES)) ival = util.getqattr(result, context.md_core_model['mappings']['pycsw:Identifier']) ident.text = ival #Identifier type: # NB DOI is mandatory for DataCite proper but we plan to use the schema with other IDs too. Modify as necessary. if ival.lower().startswith("doi"): idType = "DOI" elif ival.lower().startswith("handle"): idType = "Handle" elif ival.lower().startswith("urn"): idType = "URN" else: idType = "URL" ident.attrib[util.nspath_eval('identifierType', NAMESPACES)] = idType or "DOI" # modified mod = util.getqattr(result, context.md_core_model['mappings']['pycsw:Date']) if mod not in [None, '']: dates = etree.SubElement(node, util.nspath_eval('dates', NAMESPACES)) date = etree.SubElement(dates, util.nspath_eval('date', NAMESPACES)) date.attrib['dateType'] = 'Updated' date.text = mod # Title titles = etree.SubElement(node, util.nspath_eval('titles', NAMESPACES)) tval = util.getqattr(result, context.md_core_model['mappings']['pycsw:Title']) title = etree.SubElement(titles, util.nspath_eval('title', NAMESPACES)) title.attrib[util.nspath_eval("xml:lang", NAMESPACES)]= util.getqattr(result, context.md_core_model['mappings']['pycsw:Language']) or "eng" title.text = tval # keywords # example kwval = util.getqattr(result, context.md_core_model['mappings']['pycsw:Keywords']) tcval = util.getqattr(result, context.md_core_model['mappings']['pycsw:TopicCategory']) kws = etree.SubElement(node, util.nspath_eval('subjects', NAMESPACES)) if kwval not in [None, '']: # todo: subject per kw kw = etree.SubElement(kws, util.nspath_eval('subject', NAMESPACES)) kw.attrib[util.nspath_eval("xml:lang", NAMESPACES)]= util.getqattr(result, context.md_core_model['mappings']['pycsw:Language']) or "eng" kw.text = kwval if tcval not in [None, '']: kw = etree.SubElement(kws, util.nspath_eval('subject', NAMESPACES)) kw.attrib['schemaUri'] = 'https://schemas.opengis.net/iso/19139/20070417/resources/codelist/gmxCodelists.xml#MD_TopicCategoryCode' kw.text = tcval # themes # example themes = util.getqattr(result, context.md_core_model['mappings']['pycsw:Themes']) if themes not in [None, '']: try: for t in json.loads(themes): thesaurus = t.get('thesaurus',{}).get('url', t.get('thesaurus',{}).get('title', '')) for k in [c for c in t.get('keywords', []) if c['name'] not in [None, '']]: kw = etree.SubElement(kws, util.nspath_eval('subject', NAMESPACES)) kw.attrib['schemaUri'] = thesaurus kw.text = k.get('name') except Exception as err: LOGGER.exception(f"failed to parse themes json of {themes}: {err}") # publisher, creator, contributor, should have at least 1 creator (use originator else organization else ...) cval = util.getqattr(result, context.md_core_model['mappings']['pycsw:Contacts']) hasCreator = False # requires at least 1 creator creas = etree.SubElement(node, util.nspath_eval('creators', NAMESPACES)) hasPublisher = False # 1 publisher at most if cval not in [None, '', 'null']: conts = etree.SubElement(node, util.nspath_eval('contributors', NAMESPACES)) try: for cnt in json.loads(cval): try: cont = etree.SubElement(conts, util.nspath_eval('contributor', NAMESPACES)) roleMapping = { "resourceProvider": "Distributor", "custodian": "DataCurator", "owner": "RightsHolder", "user": "Other", "distributor": "Distributor", "originator": "Producer", "pointOfContact": "ContactPerson", "principalInvestigator": "Supervisor", "processor": "Other", "publisher": "Distributor", "author": "Researcher" } contnm = etree.SubElement(cont, util.nspath_eval('contributorName', NAMESPACES)) contnm.text = cnt.get('individualname',cnt.get('organization', '')) cont.attrib['contributorType'] = roleMapping.get(cnt.get('role', ''),'Other') if cnt.get('url').startswith('http'): contid = etree.SubElement(cont, util.nspath_eval('nameIdentifier', NAMESPACES)) contid.attrib['nameIdentifierScheme'] = "URL" contid.text = cnt['url'] if cnt['organization']: contaf = etree.SubElement(cont, util.nspath_eval('affiliation', NAMESPACES)) contaf.text = cnt['organization'] if not hasPublisher and cnt.get('role', '').lower() in ['publisher','resourceProvider','distributor']: hasPublisher = True pb = etree.SubElement(node, util.nspath_eval('publisher', NAMESPACES)) pb.text = cnt.get('individualname',cnt.get('organization', '')) elif cnt.get('role', '').lower() in ['originator','author','principalInvestigator']: hasCreator = True crea = etree.SubElement(creas, util.nspath_eval('creator', NAMESPACES)) creanm = etree.SubElement(crea, util.nspath_eval('creatorName', NAMESPACES)) creanm.text = cnt.get('individualname',cnt.get('organization', '')) if cnt['url'] not in [None, '']: creaid = etree.SubElement(crea, util.nspath_eval('nameIdentifier', NAMESPACES)) creaid.attrib['nameIdentifierScheme'] = "URL" creaid.text = cnt['url'] if cnt['organization'] not in [None, '']: creaff = etree.SubElement(crea, util.nspath_eval('affiliation', NAMESPACES)) creaff.text = cnt['organization'] except Exception as err: LOGGER.exception(f"failed to parse contact of {cnt}: {err}") except Exception as err: LOGGER.exception(f"failed to parse contacts json of {cval}: {err}") if not hasCreator: crea = etree.SubElement(creas, util.nspath_eval('creator', NAMESPACES)) creanm = etree.SubElement(crea, util.nspath_eval('creatorName', NAMESPACES)) cval = util.getqattr(result, context.md_core_model['mappings']['pycsw:OrganizationName']) creanm.text = cval # foo descriptions = etree.SubElement(node, util.nspath_eval('descriptions', NAMESPACES)) tval = util.getqattr(result, context.md_core_model['mappings']['pycsw:Abstract']) description = etree.SubElement(descriptions, util.nspath_eval('description', NAMESPACES)) description.attrib[util.nspath_eval("xml:lang", NAMESPACES)]= util.getqattr(result, context.md_core_model['mappings']['pycsw:Language']) or "eng" description.text = tval # https://guidelines.openaire.eu/en/latest/data/field_language.html # eng tval = util.getqattr(result, context.md_core_model['mappings']['pycsw:Language']) if tval not in [None, '']: format = etree.SubElement(node, util.nspath_eval('Language', NAMESPACES)) format.text = tval # https://guidelines.openaire.eu/en/latest/data/field_version.html?highlight=version # 1.0 tval = util.getqattr(result, context.md_core_model['mappings']['pycsw:Edition']) if tval not in [None, '']: format = etree.SubElement(node, util.nspath_eval('version', NAMESPACES)) format.text = tval # https://guidelines.openaire.eu/en/latest/data/field_format.html # PDF tval = util.getqattr(result, context.md_core_model['mappings']['pycsw:Format']) if tval not in [None, '']: formats = etree.SubElement(node, util.nspath_eval('formats', NAMESPACES)) format = etree.SubElement(formats, util.nspath_eval('format', NAMESPACES)) format.text = tval # example rights = etree.SubElement(node, util.nspath_eval('rightsList', NAMESPACES)) for r in ["AccessConstraints","OtherConstraints","Classification","ConditionApplyingToAccessAndUse"]: rval = util.getqattr(result, context.md_core_model['mappings']['pycsw:'+r]) if rval not in [None, '']: right = etree.SubElement(rights, util.nspath_eval('rights', NAMESPACES)) if rval.startswith('http'): right.attrib['rightsURI'] = rval right.text = r+':'+rval # # "IsCitedBy","Cites","IsSupplementTo","IsSupplementedBy","IsContinuedBy","Continues","IsNewVersionOf","IsPreviousVersionOf","IsPartOf","HasPart","IsPublishedIn","IsReferencedBy","References","IsDocumentedBy","Documents","IsCompiledBy","Compiles","IsVariantFormOf","IsOriginalFormOf","IsIdenticalTo","HasMetadata","IsMetadataFor","Reviews","IsReviewedBy","IsDerivedFrom","IsSourceOf","Describes","IsDescribedBy","HasVersion","IsVersionOf","Requires","IsRequiredBy","Obsoletes","IsObsoletedBy" # doi:1234 # alternateIdentifiers/alternateIdentifier/@alternateIdentifierType # Since Datacite is a metadata format related to the DOI to access a piece of content, the schema does not include a link to the actual file # although internally Datacite uses a property `contentUrl`, suggestion to add links to content in the same way rval = util.getqattr(result, context.md_core_model['mappings']['pycsw:Links']) if rval not in [None, '', 'null']: try: for lnk in util.jsonify_links(rval): try: if lnk.get('url', '').startswith('http'): ct = etree.SubElement(node, util.nspath_eval('contentUrl', NAMESPACES)) ct.text = lnk.get('url') except Exception as err: LOGGER.exception(f"failed to parse link of {rval}: {err}") except Exception as err: LOGGER.exception(f"failed to parse links json of {lnk}: {err}") # 41.090 # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from pycsw.core import util from pycsw.core.etree import etree NAMESPACE = 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/' NAMESPACES = {'dif': NAMESPACE} XPATH_MAPPINGS = { 'pycsw:Title': 'dif:Entry_Title', 'pycsw:Creator': 'dif:Data_Set_Citation/dif:Dataset_Creator', 'pycsw:TopicCategory': 'dif:ISO_Topic_Category', 'pycsw:Keywords': 'dif:Keyword', 'pycsw:Abstract': 'dif:Summary', 'pycsw:Publisher': 'dif:Data_Set_Citation/dif:Dataset_Publisher', 'pycsw:OrganizationName': 'dif:Originating_Center', 'pycsw:CreationDate': 'dif:DIF_Creation_Date','pycsw:PublicationDate': 'dif:Data_Set_Citation/dif:Dataset_Release_Date', 'pycsw:Format': 'dif:Data_Set_Citation/dif:Data_Presentation_Form', 'pycsw:ResourceLanguage': 'dif:Data_Set_Language', 'pycsw:Relation': 'dif:Related_URL/dif:URL', 'pycsw:AccessConstraints': 'dif:Access_Constraints', 'pycsw:TempExtent_begin': 'dif:Temporal_Coverage/dif:Start_Date', 'pycsw:TempExtent_end': 'dif:Temporal_Coverage/dif:Stop_Date', } def write_record(result, esn, context, url=None): ''' Return csw:SearchResults child as lxml.etree.Element ''' typename = util.getqattr(result, context.md_core_model['mappings']['pycsw:Typename']) if esn == 'full' and typename == 'dif:DIF': # dump record as is and exit return etree.fromstring(util.getqattr(result, context.md_core_model['mappings']['pycsw:XML']), context.parser) node = etree.Element(util.nspath_eval('dif:DIF', NAMESPACES)) node.attrib[util.nspath_eval('xsi:schemaLocation', context.namespaces)] = \ '%s http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/dif.xsd' % NAMESPACE # identifier etree.SubElement(node, util.nspath_eval('dif:Entry_ID', NAMESPACES)).text = util.getqattr(result, context.md_core_model['mappings']['pycsw:Identifier']) # title val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Title']) if not val: val = '' etree.SubElement(node, util.nspath_eval('dif:Entry_Title', NAMESPACES)).text = val # citation citation = etree.SubElement(node, util.nspath_eval('dif:Data_Set_Citation', NAMESPACES)) # creator val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Creator']) etree.SubElement(citation, util.nspath_eval('dif:Dataset_Creator', NAMESPACES)).text = val # date val = util.getqattr(result, context.md_core_model['mappings']['pycsw:PublicationDate']) etree.SubElement(citation, util.nspath_eval('dif:Dataset_Release_Date', NAMESPACES)).text = val # publisher val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Publisher']) etree.SubElement(citation, util.nspath_eval('dif:Dataset_Publisher', NAMESPACES)).text = val # format val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Format']) etree.SubElement(citation, util.nspath_eval('dif:Data_Presentation_Form', NAMESPACES)).text = val # keywords dif:Parameters val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Keywords']) if val: kws = val.split(',') parameters_indexes = [] for index, kw in enumerate(kws): if "Earth Science".lower() in kw.lower() and len(kw.split(">")) >= 2: values = kw.upper().split(">") parameters = etree.SubElement(node, util.nspath_eval('dif:Parameters', NAMESPACES)) # .text = kw etree.SubElement(parameters, util.nspath_eval('dif:Category', NAMESPACES)).text = values[0].strip().upper() etree.SubElement(parameters, util.nspath_eval('dif:Topic', NAMESPACES)).text = values[1].strip().upper() etree.SubElement(parameters, util.nspath_eval('dif:Term', NAMESPACES)).text = values[2].strip().upper() for i, v in enumerate(values[3:]): etree.SubElement(parameters, util.nspath_eval(f'dif:Variable_Level_{i + 1}', NAMESPACES)).text = v.strip() parameters_indexes.append(index) # kws.pop(index) # iso topic category val = util.getqattr(result, context.md_core_model['mappings']['pycsw:TopicCategory']) etree.SubElement(node, util.nspath_eval('dif:ISO_Topic_Category', NAMESPACES)).text = val # keywords dif:keywords val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Keywords']) if val: kws = val.split(',') kws = [i for j, i in enumerate(kws) if j not in parameters_indexes] for index, kw in enumerate(kws): etree.SubElement(node, util.nspath_eval('dif:Keyword', NAMESPACES)).text = kw.strip() # temporal temporal = etree.SubElement(node, util.nspath_eval('dif:Temporal_Coverage', NAMESPACES)) val = util.getqattr(result, context.md_core_model['mappings']['pycsw:TempExtent_begin']) val2 = util.getqattr(result, context.md_core_model['mappings']['pycsw:TempExtent_end']) etree.SubElement(temporal, util.nspath_eval('dif:Start_Date', NAMESPACES)).text = val etree.SubElement(temporal, util.nspath_eval('dif:End_Date', NAMESPACES)).text = val2 # bbox extent val = util.getqattr(result, context.md_core_model['mappings']['pycsw:BoundingBox']) bboxel = write_extent(val, NAMESPACES) if bboxel is not None: node.append(bboxel) # access constraints val = util.getqattr(result, context.md_core_model['mappings']['pycsw:AccessConstraints']) etree.SubElement(node, util.nspath_eval('dif:Access_Constraints', NAMESPACES)).text = val # language val = util.getqattr(result, context.md_core_model['mappings']['pycsw:ResourceLanguage']) etree.SubElement(node, util.nspath_eval('dif:Data_Set_Language', NAMESPACES)).text = val # contributor val = util.getqattr(result, context.md_core_model['mappings']['pycsw:OrganizationName']) etree.SubElement(node, util.nspath_eval('dif:Originating_Center', NAMESPACES)).text = val # abstract val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Abstract']) if not val: val = '' etree.SubElement(node, util.nspath_eval('dif:Summary', NAMESPACES)).text = val # URL val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Relation']) if val: url = etree.SubElement(node, util.nspath_eval('dif:Related_URL', NAMESPACES)) etree.SubElement(url, util.nspath_eval('dif:URL', NAMESPACES)).text = val rlinks = util.getqattr(result, context.md_core_model['mappings']['pycsw:Links']) if rlinks: for link in util.jsonify_links(rlinks): url2 = etree.SubElement(node, util.nspath_eval('dif:Related_URL', NAMESPACES)) urltype = etree.SubElement(url2, util.nspath_eval('dif:URL_Content_Type', NAMESPACES)) if link['protocol'] == 'download': etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'GET DATA' elif link['protocol'] == 'OPENDAP:OPENDAP': etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'GET DATA' etree.SubElement(urltype, util.nspath_eval('dif:Subtype', NAMESPACES)).text = 'OPENDAP DATA (DODS)' elif link['protocol'] == 'OGC:WMS': etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'GET SERVICE' etree.SubElement(urltype, util.nspath_eval('dif:Subtype', NAMESPACES)).text = 'GET WEB MAP SERVICE (WMS)' else: etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'GET DATA' etree.SubElement(url2, util.nspath_eval('dif:URL', NAMESPACES)).text = link['url'] if link['description']: etree.SubElement(url2, util.nspath_eval('dif:Description', NAMESPACES)).text = link['description'] val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Source']) if val: url2 = etree.SubElement(node, util.nspath_eval('dif:Related_URL', NAMESPACES)) urltype = etree.SubElement(url2, util.nspath_eval('dif:URL_Content_Type', NAMESPACES)) etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'DATASET LANDING PAGE' etree.SubElement(url2, util.nspath_eval('dif:URL', NAMESPACES)).text = val etree.SubElement(node, util.nspath_eval('dif:Metadata_Name', NAMESPACES)).text = 'CEOS IDN DIF' etree.SubElement(node, util.nspath_eval('dif:Metadata_Version', NAMESPACES)).text = '9.7' # date val = util.getqattr(result, context.md_core_model['mappings']['pycsw:CreationDate']) etree.SubElement(node, util.nspath_eval('dif:DIF_Creation_Date', NAMESPACES)).text = val return node def write_extent(bbox, nsmap): ''' Generate BBOX extent ''' if bbox is not None: try: bbox2 = util.wkt2geom(bbox) except Exception as err: LOGGER.debug(f'Geometry parsing error: {err}') return None extent = etree.Element(util.nspath_eval('dif:Spatial_Coverage', nsmap)) etree.SubElement(extent, util.nspath_eval('dif:Southernmost_Latitude', nsmap)).text = str(bbox2[1]) etree.SubElement(extent, util.nspath_eval('dif:Northernmost_Latitude', nsmap)).text = str(bbox2[3]) etree.SubElement(extent, util.nspath_eval('dif:Westernmost_Longitude', nsmap)).text = str(bbox2[0]) etree.SubElement(extent, util.nspath_eval('dif:Easternmost_Longitude', nsmap)).text = str(bbox2[2]) return extent return None ================================================ FILE: pycsw/plugins/outputschemas/fgdc.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from pycsw.core import util from pycsw.core.etree import etree #NAMESPACE = 'http://www.fgdc.gov/metadata/csdgm' NAMESPACE = 'http://www.opengis.net/cat/csw/csdgm' NAMESPACES = {'fgdc': NAMESPACE} XPATH_MAPPINGS = { 'pycsw:Identifier': 'idinfo/datasetid', 'pycsw:Title': 'idinfo/citation/citeinfo/title', 'pycsw:Creator': 'idinfo/citation/citeinfo/origin', 'pycsw:Publisher': 'idinfo/citation/citeinfo/publinfo/publish', 'pycsw:Abstract': 'idinfo/descript/abstract', 'pycsw:Format': 'idinfo/citation/citeinfo/geoform', 'pycsw:PublicationDate': 'idinfo/citation/citeinfo/pubdate', 'pycsw:Keywords': 'idinfo/keywords/theme/themekey', 'pycsw:TempExtent_begin': 'idinfo/timeperd/timeinfo/rngdates/begdate', 'pycsw:TempExtent_end': 'idinfo/timeperd/timeinfo/rngdates/enddate', 'pycsw:Contributor': 'idinfo/datacred', 'pycsw:AccessConstraints': 'idinfo/accconst', 'pycsw:Modified': 'metainfo/metd', 'pycsw:Type': 'spdoinfo/direct', 'pycsw:Source': 'lineage/srcinfo/srccite/citeinfo/title', 'pycsw:Relation': 'idinfo/citation/citeinfo/onlink', } def write_record(recobj, esn, context, url=None): ''' Return csw:SearchResults child as lxml.etree.Element ''' typename = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Typename']) if esn == 'full' and typename == 'fgdc:metadata': # dump record as is and exit return etree.fromstring(util.getqattr(recobj, context.md_core_model['mappings']['pycsw:XML']), context.parser) node = etree.Element('metadata') node.attrib[util.nspath_eval('xsi:noNamespaceSchemaLocation', context.namespaces)] = \ 'http://www.fgdc.gov/metadata/fgdc-std-001-1998.xsd' idinfo = etree.SubElement(node, 'idinfo') # identifier etree.SubElement(idinfo, 'datasetid').text = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Identifier']) citation = etree.SubElement(idinfo, 'citation') citeinfo = etree.SubElement(citation, 'citeinfo') # title val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Title']) etree.SubElement(citeinfo, 'title').text = val # publisher publinfo = etree.SubElement(citeinfo, 'publinfo') val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Publisher']) or '' etree.SubElement(publinfo, 'publish').text = val # origin val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Creator']) or '' etree.SubElement(citeinfo, 'origin').text = val # keywords val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Keywords']) if val: keywords = etree.SubElement(idinfo, 'keywords') theme = etree.SubElement(keywords, 'theme') for v in val.split(','): etree.SubElement(theme, 'themekey').text = v # accessconstraints val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:AccessConstraints']) or '' etree.SubElement(idinfo, 'accconst').text = val # abstract descript = etree.SubElement(idinfo, 'descript') val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Abstract']) or '' etree.SubElement(descript, 'abstract').text = val # time datebegin = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:TempExtent_begin']) dateend = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:TempExtent_end']) if all([datebegin, dateend]): timeperd = etree.SubElement(idinfo, 'timeperd') timeinfo = etree.SubElement(timeperd, 'timeinfo') rngdates = etree.SubElement(timeinfo, 'timeinfo') begdate = etree.SubElement(rngdates, 'begdate').text = datebegin enddate = etree.SubElement(rngdates, 'enddate').text = dateend # bbox extent val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:BoundingBox']) bboxel = write_extent(val) if bboxel is not None: idinfo.append(bboxel) # contributor val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Contributor']) or '' etree.SubElement(idinfo, 'datacred').text = val # direct spdoinfo = etree.SubElement(idinfo, 'spdoinfo') val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Type']) or '' etree.SubElement(spdoinfo, 'direct').text = val # formname distinfo = etree.SubElement(node, 'distinfo') stdorder = etree.SubElement(distinfo, 'stdorder') digform = etree.SubElement(stdorder, 'digform') digtinfo = etree.SubElement(digform, 'digtinfo') val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Format']) or '' etree.SubElement(digtinfo, 'formname').text = val etree.SubElement(citeinfo, 'geoform').text = val # source lineage = etree.SubElement(node, 'lineage') srcinfo = etree.SubElement(lineage, 'srcinfo') srccite = etree.SubElement(srcinfo, 'srccite') sciteinfo = etree.SubElement(srccite, 'citeinfo') val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Source']) or '' etree.SubElement(sciteinfo, 'title').text = val val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Relation']) or '' etree.SubElement(citeinfo, 'onlink').text = val # links rlinks = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Links']) if rlinks: for link in util.jsonify_links(rlinks): etree.SubElement(citeinfo, 'onlink', type=link['protocol']).text = link['url'] # metd metainfo = etree.SubElement(node, 'metainfo') val = util.getqattr(recobj, context.md_core_model['mappings']['pycsw:Modified']) or '' etree.SubElement(metainfo, 'metd').text = val return node def write_extent(bbox): ''' Generate BBOX extent ''' if bbox is not None: try: bbox2 = util.wkt2geom(bbox) except Exception as err: LOGGER.debug(f'Geometry parsing error: {err}') return None spdom = etree.Element('spdom') bounding = etree.SubElement(spdom, 'bounding') etree.SubElement(bounding, 'westbc').text = str(bbox2[0]) etree.SubElement(bounding, 'eastbc').text = str(bbox2[2]) etree.SubElement(bounding, 'northbc').text = str(bbox2[3]) etree.SubElement(bounding, 'southbc').text = str(bbox2[1]) return spdom return None ================================================ FILE: pycsw/plugins/outputschemas/gm03.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from pycsw.core import util from pycsw.core.etree import etree NAMESPACE = 'http://www.interlis.ch/INTERLIS2.3' NAMESPACES = {'gm03': NAMESPACE} XPATH_MAPPINGS = {} def write_record(result, esn, context, url=None): ''' Return csw:SearchResults child as lxml.etree.Element ''' typename = util.getqattr(result, context.md_core_model['mappings']['pycsw:Typename']) if typename == 'gm03:TRANSFER': # dump record as is and exit # TODO: provide brief and summary elementsetname's return etree.fromstring(util.getqattr(result, context.md_core_model['mappings']['pycsw:XML']), context.parser) node = etree.Element(util.nspath_eval('gm03:TRANSFER', NAMESPACES), nsmap=NAMESPACES) header = etree.SubElement(node, util.nspath_eval('gm03:HEADERSECTION', NAMESPACES)) header.attrib['version'] = '2.3' header.attrib['sender'] = 'pycsw' etree.SubElement(header, util.nspath_eval('gm03:MODELS', NAMESPACES)) data = etree.SubElement(node, util.nspath_eval('gm03:DATASECTION', NAMESPACES)) core = etree.SubElement(data, util.nspath_eval('gm03:GM03_2_1Core.Core', NAMESPACES)) core_meta = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_Metadata', NAMESPACES)) val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Identifier']) etree.SubElement(core_meta, util.nspath_eval('gm03:fileIdentifier', NAMESPACES)).text = val language = util.getqattr(result, context.md_core_model['mappings']['pycsw:Language']) etree.SubElement(core_meta, util.nspath_eval('gm03:language', NAMESPACES)).text = language val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Modified']) etree.SubElement(core_meta, util.nspath_eval('gm03:dateStamp', NAMESPACES)).text = val hierarchy_level_val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Type']) # metadata standard name standard = etree.SubElement(core_meta, util.nspath_eval('gm03:metadataStandardName', NAMESPACES)).text = 'GM03' # metadata standard version standardver = etree.SubElement(core_meta, util.nspath_eval('gm03:metadataStandardVersion', NAMESPACES)).text = '2.3' # hierarchy level hierarchy_level = etree.SubElement(core_meta, util.nspath_eval('gm03:hierarchyLevel', NAMESPACES)) scope_code = etree.SubElement(hierarchy_level, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_ScopeCode_', NAMESPACES)) etree.SubElement(scope_code, util.nspath_eval('gm03:value', NAMESPACES)).text = hierarchy_level_val # parent identifier val = util.getqattr(result, context.md_core_model['mappings']['pycsw:ParentIdentifier']) parent_identifier = etree.SubElement(core_meta, util.nspath_eval('gm03:parentIdentifier', NAMESPACES)) scope_code = etree.SubElement(parent_identifier, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_ScopeCode_', NAMESPACES)) etree.SubElement(scope_code, util.nspath_eval('gm03:value', NAMESPACES)).text = val # title val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Title']) citation = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.CI_Citation', NAMESPACES)) title = etree.SubElement(citation, util.nspath_eval('gm03:title', NAMESPACES)) title.append(_get_pt_freetext(val, language)) # abstract val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Abstract']) data_ident = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_DataIdentification', NAMESPACES)) abstract = etree.SubElement(data_ident, util.nspath_eval('gm03:abstract', NAMESPACES)) abstract.append(_get_pt_freetext(val, language)) # resource language val = util.getqattr(result, context.md_core_model['mappings']['pycsw:ResourceLanguage']) if val: topicategory = etree.SubElement(data_ident, util.nspath_eval('gm03:language', NAMESPACES)) cat_code = etree.SubElement(topicategory, util.nspath_eval('gm03:CodeISO.LanguageCodeISO_', NAMESPACES)) etree.SubElement(cat_code, util.nspath_eval('gm03:value', NAMESPACES)).text = val # topic category val = util.getqattr(result, context.md_core_model['mappings']['pycsw:TopicCategory']) if val: topicategory = etree.SubElement(data_ident, util.nspath_eval('gm03:topicCategory', NAMESPACES)) cat_code = etree.SubElement(topicategory, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_TopicCategoryCode_', NAMESPACES)) etree.SubElement(cat_code, util.nspath_eval('gm03:value', NAMESPACES)).text = val # keywords keywords_val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Keywords']) if keywords_val: md_keywords = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_Keywords', NAMESPACES)) val = util.getqattr(result, context.md_core_model['mappings']['pycsw:KeywordType']) if val: etree.SubElement(md_keywords, util.nspath_eval('gm03:type', NAMESPACES)).text = val keyword = etree.SubElement(md_keywords, util.nspath_eval('gm03:keyword', NAMESPACES)) for kw in keywords_val.split(','): keyword.append(_get_pt_freetext(kw, language)) # format val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Format']) if val: md_format = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_Format', NAMESPACES)) etree.SubElement(md_format, util.nspath_eval('gm03:name', NAMESPACES)).text = val # creation date val = util.getqattr(result, context.md_core_model['mappings']['pycsw:CreationDate']) if val: ci_date = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.CI_Date', NAMESPACES)) etree.SubElement(ci_date, util.nspath_eval('gm03:date', NAMESPACES)).text = val etree.SubElement(ci_date, util.nspath_eval('gm03:dateType', NAMESPACES)).text = 'creation' # revision date val = util.getqattr(result, context.md_core_model['mappings']['pycsw:RevisionDate']) if val: ci_date = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.CI_Date', NAMESPACES)) etree.SubElement(ci_date, util.nspath_eval('gm03:date', NAMESPACES)).text = val etree.SubElement(ci_date, util.nspath_eval('gm03:dateType', NAMESPACES)).text = 'revision' # publication date val = util.getqattr(result, context.md_core_model['mappings']['pycsw:PublicationDate']) if val: ci_date = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.CI_Date', NAMESPACES)) etree.SubElement(ci_date, util.nspath_eval('gm03:date', NAMESPACES)).text = val etree.SubElement(ci_date, util.nspath_eval('gm03:dateType', NAMESPACES)).text = 'publication' # bbox extent val = util.getqattr(result, context.md_core_model['mappings']['pycsw:BoundingBox']) bboxel = write_extent(val, context.namespaces) if bboxel is not None: core.append(bboxel) # geographic description val = util.getqattr(result, context.md_core_model['mappings']['pycsw:GeographicDescriptionCode']) if val: geo_desc = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.EX_GeographicDescription', NAMESPACES)) etree.SubElement(geo_desc, util.nspath_eval('gm03:geographicIdentifier', NAMESPACES)).text = val # crs val = util.getqattr(result, context.md_core_model['mappings']['pycsw:CRS']) if val: rs_identifier = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.RS_Identifier', NAMESPACES)) rs_code = etree.SubElement(rs_identifier, util.nspath_eval('gm03:code', NAMESPACES)) rs_code.append(_get_pt_freetext(val, language)) # temporal extent time_begin = util.getqattr(result, context.md_core_model['mappings']['pycsw:TempExtent_begin']) time_end = util.getqattr(result, context.md_core_model['mappings']['pycsw:TempExtent_end']) if time_begin: temp_ext = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.EX_TemporalExtent', NAMESPACES)) extent = etree.SubElement(temp_ext, util.nspath_eval('gm03:extent', NAMESPACES)) tm_primitive = etree.SubElement(extent, util.nspath_eval('gm03:GM03_2_1Core.Core.TM_Primitive', NAMESPACES)) etree.SubElement(tm_primitive, util.nspath_eval('gm03:begin', NAMESPACES)).text = time_begin if time_end: etree.SubElement(tm_primitive, util.nspath_eval('gm03:end', NAMESPACES)).text = time_end # links rlinks = util.getqattr(result, context.md_core_model['mappings']['pycsw:Links']) if rlinks: for link in util.jsonify_links(rlinks): online_resource = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.OnlineResource', NAMESPACES)) if link['protocol']: etree.SubElement(online_resource, util.nspath_eval('gm03:protocol', NAMESPACES)).text = link['protocol'] if link['description']: desc = etree.SubElement(online_resource, util.nspath_eval('gm03:description', NAMESPACES)) desc.append(_get_pt_freetext(link['description'], language)) if link['name']: name_el = etree.SubElement(online_resource, util.nspath_eval('gm03:name', NAMESPACES)) name_el.append(_get_pt_freetext(link['name'], language)) linkage = etree.SubElement(online_resource, util.nspath_eval('gm03:linkage', NAMESPACES)) linkage.append(_get_pt_freeurl(link['url'], language)) return node def _get_pt_freetext(val, language): freetext = etree.Element(util.nspath_eval('gm03:GM03_2_1Core.Core.PT_FreeText', NAMESPACES)) textgroup = etree.SubElement(freetext, util.nspath_eval('gm03:textGroup', NAMESPACES)) ptgroup = etree.SubElement(textgroup, util.nspath_eval('gm03:GM03_2_1Core.Core.PT_Group', NAMESPACES)) if language: etree.SubElement(ptgroup, util.nspath_eval('gm03:language', NAMESPACES)).text = language etree.SubElement(ptgroup, util.nspath_eval('gm03:plainText', NAMESPACES)).text = val return freetext def _get_pt_freeurl(val, language): freeurl = etree.Element(util.nspath_eval('gm03:GM03_2_1Core.Core.PT_FreeURL', NAMESPACES)) urlgroup = etree.SubElement(freeurl, util.nspath_eval('gm03:URLGroup', NAMESPACES)) ptgroup = etree.SubElement(urlgroup, util.nspath_eval('gm03:GM03_2_1Core.Core.PT_URLGroup', NAMESPACES)) if language: etree.SubElement(ptgroup, util.nspath_eval('gm03:language', NAMESPACES)).text = language etree.SubElement(ptgroup, util.nspath_eval('gm03:plainURL', NAMESPACES)).text = val return freeurl def write_extent(bbox, nsmap): ''' Generate BBOX extent ''' if bbox is not None: try: bbox2 = util.wkt2geom(bbox) except Exception as err: LOGGER.debug(f'Geometry parsing error: {err}') return None bounding_box = etree.Element(util.nspath_eval('gm03:GM03_2_1Core.Core.EX_GeographicBoundingBox', NAMESPACES)) etree.SubElement(bounding_box, util.nspath_eval('gm03:northBoundLatitude', nsmap)).text = str(bbox2[3]) etree.SubElement(bounding_box, util.nspath_eval('gm03:southBoundLatitude', nsmap)).text = str(bbox2[1]) etree.SubElement(bounding_box, util.nspath_eval('gm03:eastBoundLongitude', nsmap)).text = str(bbox2[0]) etree.SubElement(bounding_box, util.nspath_eval('gm03:westBoundLongitude', nsmap)).text = str(bbox2[2]) return bounding_box return None ================================================ FILE: pycsw/plugins/profiles/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/plugins/profiles/apiso/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/plugins/profiles/apiso/apiso.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2024 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging import os from pycsw.core import util from pycsw.core.etree import etree from pycsw.plugins.profiles import profile LOGGER = logging.getLogger(__name__) CODELIST = 'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml' CODESPACE = 'ISOTC211/19115' class APISO(profile.Profile): ''' APISO class ''' def __init__(self, model, namespaces, context): self.context = context self.namespaces = { 'apiso': 'http://www.opengis.net/cat/csw/apiso/1.0', 'gco': 'http://www.isotc211.org/2005/gco', 'gmd': 'http://www.isotc211.org/2005/gmd', 'srv': 'http://www.isotc211.org/2005/srv', 'xlink': 'http://www.w3.org/1999/xlink' } self.inspire_namespaces = { 'inspire_ds': 'http://inspire.ec.europa.eu/schemas/inspire_ds/1.0', 'inspire_common': 'http://inspire.ec.europa.eu/schemas/common/1.0' } self.repository = { 'gmd:MD_Metadata': { 'outputschema': 'http://www.isotc211.org/2005/gmd', 'queryables': { 'SupportedISOQueryables': { 'apiso:Subject': {'xpath': 'gmd:identificationInfo/gmd:MD_Identification/gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:keyword/gco:CharacterString|gmd:identificationInfo/gmd:MD_DataIdentification/gmd:topicCategory/gmd:MD_TopicCategoryCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:Keywords']}, 'apiso:Title': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Title']}, 'apiso:Abstract': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:abstract/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Abstract']}, 'apiso:Edition': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:edition/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Edition']}, 'apiso:Format': {'xpath': 'gmd:distributionInfo/gmd:MD_Distribution/gmd:distributionFormat/gmd:MD_Format/gmd:name/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Format']}, 'apiso:Identifier': {'xpath': 'gmd:fileIdentifier/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Identifier']}, 'apiso:Modified': {'xpath': 'gmd:dateStamp/gco:Date', 'dbcol': self.context.md_core_model['mappings']['pycsw:Modified']}, 'apiso:Type': {'xpath': 'gmd:hierarchyLevel/gmd:MD_ScopeCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:Type']}, 'apiso:BoundingBox': {'xpath': 'apiso:BoundingBox', 'dbcol': self.context.md_core_model['mappings']['pycsw:BoundingBox']}, 'apiso:CRS': {'xpath': 'concat("urn:ogc:def:crs:","gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:codeSpace/gco:CharacterString",":","gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:version/gco:CharacterString",":","gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:code/gco:CharacterString")', 'dbcol': self.context.md_core_model['mappings']['pycsw:CRS']}, 'apiso:AlternateTitle': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:alternateTitle/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:AlternateTitle']}, 'apiso:RevisionDate': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:date/gmd:CI_Date[gmd:dateType/gmd:CI_DateTypeCode/@codeListValue="revision"]/gmd:date/gco:Date', 'dbcol': self.context.md_core_model['mappings']['pycsw:RevisionDate']}, 'apiso:CreationDate': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:date/gmd:CI_Date[gmd:dateType/gmd:CI_DateTypeCode/@codeListValue="creation"]/gmd:date/gco:Date', 'dbcol': self.context.md_core_model['mappings']['pycsw:CreationDate']}, 'apiso:PublicationDate': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:date/gmd:CI_Date[gmd:dateType/gmd:CI_DateTypeCode/@codeListValue="publication"]/gmd:date/gco:Date', 'dbcol': self.context.md_core_model['mappings']['pycsw:PublicationDate']}, 'apiso:OrganisationName': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OrganizationName']}, 'apiso:HasSecurityConstraints': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_SecurityConstraints', 'dbcol': self.context.md_core_model['mappings']['pycsw:SecurityConstraints']}, 'apiso:Language': {'xpath': 'gmd:language/gmd:LanguageCode|gmd:language/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Language']}, 'apiso:ParentIdentifier': {'xpath': 'gmd:parentIdentifier/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:ParentIdentifier']}, 'apiso:KeywordType': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:type/gmd:MD_KeywordTypeCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:KeywordType']}, 'apiso:TopicCategory': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:topicCategory/gmd:MD_TopicCategoryCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:TopicCategory']}, 'apiso:ResourceLanguage': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:code/gmd:MD_LanguageTypeCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:ResourceLanguage']}, 'apiso:GeographicDescriptionCode': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:geographicElement/gmd:EX_GeographicDescription/gmd:geographicIdentifier/gmd:MD_Identifier/gmd:code/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:GeographicDescriptionCode']}, 'apiso:Denominator': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:equivalentScale/gmd:MD_RepresentativeFraction/gmd:denominator/gco:Integer', 'dbcol': self.context.md_core_model['mappings']['pycsw:Denominator']}, 'apiso:DistanceValue': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance', 'dbcol': self.context.md_core_model['mappings']['pycsw:DistanceValue']}, 'apiso:DistanceUOM': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance/@uom', 'dbcol': self.context.md_core_model['mappings']['pycsw:DistanceUOM']}, 'apiso:TempExtent_begin': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:beginPosition', 'dbcol': self.context.md_core_model['mappings']['pycsw:TempExtent_begin']}, 'apiso:TempExtent_end': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:endPosition', 'dbcol': self.context.md_core_model['mappings']['pycsw:TempExtent_end']}, 'apiso:AnyText': {'xpath': '//', 'dbcol': self.context.md_core_model['mappings']['pycsw:AnyText']}, 'apiso:ServiceType': {'xpath': 'gmd:identificationInfo/srv:SV_ServiceIdentification/srv:serviceType/gco:LocalName', 'dbcol': self.context.md_core_model['mappings']['pycsw:ServiceType']}, 'apiso:ServiceTypeVersion': {'xpath': 'gmd:identificationInfo/srv:SV_ServiceIdentification/srv:serviceTypeVersion/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:ServiceTypeVersion']}, 'apiso:Operation': {'xpath': 'gmd:identificationInfo/srv:SV_ServiceIdentification/srv:containsOperations/srv:SV_OperationMetadata/srv:operationName/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Operation']}, 'apiso:CouplingType': {'xpath': 'gmd:identificationInfo/srv:SV_ServiceIdentification/srv:couplingType/srv:SV_CouplingType', 'dbcol': self.context.md_core_model['mappings']['pycsw:CouplingType']}, 'apiso:OperatesOn': {'xpath': 'gmd:identificationInfo/srv:SV_ServiceIdentification/srv:operatesOn/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:RS_Identifier/gmd:code/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OperatesOn']}, 'apiso:OperatesOnIdentifier': {'xpath': 'gmd:identificationInfo/srv:SV_ServiceIdentification/srv:coupledResource/srv:SV_CoupledResource/srv:identifier/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OperatesOnIdentifier']}, 'apiso:OperatesOnName': {'xpath': 'gmd:identificationInfo/srv:SV_ServiceIdentification/srv:coupledResource/srv:SV_CoupledResource/srv:operationName/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OperatesOnName']}, }, 'AdditionalQueryables': { 'apiso:Degree': {'xpath': 'gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:pass/gco:Boolean', 'dbcol': self.context.md_core_model['mappings']['pycsw:Degree']}, 'apiso:AccessConstraints': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_RestrictionCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:AccessConstraints']}, 'apiso:OtherConstraints': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:otherConstraints/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OtherConstraints']}, 'apiso:Classification': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:accessConstraints/gmd:MD_ClassificationCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:Classification']}, 'apiso:ConditionApplyingToAccessAndUse': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:useLimitation/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:ConditionApplyingToAccessAndUse']}, 'apiso:Lineage': {'xpath': 'gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:lineage/gmd:LI_Lineage/gmd:statement/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Lineage']}, 'apiso:ResponsiblePartyRole': {'xpath': 'gmd:contact/gmd:CI_ResponsibleParty/gmd:role/gmd:CI_RoleCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:ResponsiblePartyRole']}, 'apiso:SpecificationTitle': {'xpath': 'gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:title/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:SpecificationTitle']}, 'apiso:SpecificationDate': {'xpath': 'gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:date/gco:Date', 'dbcol': self.context.md_core_model['mappings']['pycsw:SpecificationDate']}, 'apiso:SpecificationDateType': {'xpath': 'gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:dateType/gmd:CI_DateTypeCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:SpecificationDateType']}, 'apiso:Creator': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName[gmd:role/gmd:CI_RoleCode/@codeListValue="originator"]/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Creator']}, 'apiso:Publisher': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName[gmd:role/gmd:CI_RoleCode/@codeListValue="publisher"]/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Publisher']}, 'apiso:Contributor': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName[gmd:role/gmd:CI_RoleCode/@codeListValue="contributor"]/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Contributor']}, 'apiso:Relation': {'xpath': 'gmd:identificationInfo/gmd:MD_DataIdentification/gmd:aggregationInfo', 'dbcol': self.context.md_core_model['mappings']['pycsw:Relation']}, # 19115-2 'apiso:Platform': {'xpath': 'gmi:acquisitionInfo/gmi:MI_AcquisitionInformation/gmi:platform/gmi:MI_Platform/gmi:identifier', 'dbcol': self.context.md_core_model['mappings']['pycsw:Platform']}, 'apiso:Instrument': {'xpath': 'gmi:acquisitionInfo/gmi:MI_AcquisitionInformation/gmi:platform/gmi:MI_Platform/gmi:instrument/gmi:MI_Instrument/gmi:identifier', 'dbcol': self.context.md_core_model['mappings']['pycsw:Instrument']}, 'apiso:SensorType': {'xpath': 'gmi:acquisitionInfo/gmi:MI_AcquisitionInformation/gmi:platform/gmi:MI_Platform/gmi:instrument/gmi:MI_Instrument/gmi:type', 'dbcol': self.context.md_core_model['mappings']['pycsw:SensorType']}, 'apiso:CloudCover': {'xpath': 'gmd:contentInfo/gmd:MD_ImageDescription/gmd:cloudCoverPercentage', 'dbcol': self.context.md_core_model['mappings']['pycsw:CloudCover']}, 'apiso:Bands': {'xpath': 'gmd:contentInfo/gmd:MD_ImageDescription/gmd:dimension/MD_Band/@id', 'dbcol': self.context.md_core_model['mappings']['pycsw:Bands']}, 'apiso:IlluminationElevationAngle': {'xpath': 'gmd:contentInfo/gmd:MD_ImageDescription/gmd:illuminationElevationAngle/gco:Real', 'dbcol': self.context.md_core_model['mappings']['pycsw:IlluminationElevationAngle']}, } }, 'mappings': { 'csw:Record': { # map APISO queryables to DC queryables 'apiso:Title': 'dc:title', 'apiso:Creator': 'dc:creator', 'apiso:Subject': 'dc:subject', 'apiso:Abstract': 'dct:abstract', 'apiso:Publisher': 'dc:publisher', 'apiso:Contributor': 'dc:contributor', 'apiso:Modified': 'dct:modified', #'apiso:Date': 'dc:date', 'apiso:Type': 'dc:type', 'apiso:Format': 'dc:format', 'apiso:Language': 'dc:language', 'apiso:Relation': 'dc:relation', 'apiso:AccessConstraints': 'dc:rights', } } } } profile.Profile.__init__(self, name='apiso', version='1.0.0', title='ISO Metadata Application Profile', url='http://portal.opengeospatial.org/files/?artifact_id=21460', namespace=self.namespaces['gmd'], typename='gmd:MD_Metadata', outputschema=self.namespaces['gmd'], prefixes=['apiso', 'gmd'], model=model, core_namespaces=namespaces, added_namespaces=self.namespaces, repository=self.repository['gmd:MD_Metadata']) def extend_core(self, model, namespaces, config): ''' Extend core configuration ''' # update INSPIRE vars self.context.namespaces.update(self.inspire_namespaces) # update harvest resource types with WMS, since WMS is not a typename, if 'Harvest' in model['operations']: model['operations']['Harvest']['parameters']['ResourceType']['values'].append('http://www.isotc211.org/schemas/2005/gmd/') # set INSPIRE config if config['metadata']['inspire']['enabled']: self.inspire_config = {} self.inspire_config['languages_supported'] = config['metadata']['inspire']['languages_supported'] self.inspire_config['default_language'] = config['metadata']['inspire']['default_language'] self.inspire_config['date'] = config['metadata']['inspire']['date'] self.inspire_config['gemet_keywords'] = config['metadata']['inspire']['gemet_keywords'] self.inspire_config['conformity_service'] = config['metadata']['inspire']['conformity_service'] self.inspire_config['contact_name'] = config['metadata']['inspire']['contact_name'] self.inspire_config['contact_email'] = config['metadata']['inspire']['contact_email'] self.inspire_config['temp_extent'] = config['metadata']['inspire']['temp_extent'] else: self.inspire_config = None self.ogc_schemas_base = config['server']['ogc_schemas_base'] self.url = config['server']['url'] def check_parameters(self, kvp): '''Check for Language parameter in GetCapabilities request''' if self.inspire_config is not None: result = None if 'language' not in kvp: self.inspire_config['current_language'] = self.inspire_config['default_language'] else: if kvp['language'] not in self.inspire_config['languages_supported']: text = 'Requested Language not supported, Supported languages: %s' % self.inspire_config['languages_supported'] return {'error': 'true', 'locator': 'language', 'code': 'InvalidParameterValue', 'text': text} else: self.inspire_config['current_language'] = kvp['language'] return None return None return None def get_extendedcapabilities(self): ''' Add child to ows:OperationsMetadata Element ''' if self.inspire_config is not None: ex_caps = etree.Element( util.nspath_eval('inspire_ds:ExtendedCapabilities', self.inspire_namespaces)) ex_caps.attrib[util.nspath_eval('xsi:schemaLocation', self.context.namespaces)] = \ '%s %s/inspire_ds.xsd' % \ (self.inspire_namespaces['inspire_ds'], self.inspire_namespaces['inspire_ds']) # Resource Locator res_loc = etree.SubElement(ex_caps, util.nspath_eval('inspire_common:ResourceLocator', self.inspire_namespaces)) etree.SubElement(res_loc, util.nspath_eval('inspire_common:URL', self.inspire_namespaces)).text = '%sservice=CSW&version=2.0.2&request=GetCapabilities' % (util.bind_url(self.url)) etree.SubElement(res_loc, util.nspath_eval('inspire_common:MediaType', self.inspire_namespaces)).text = 'application/xml' # Resource Type etree.SubElement(ex_caps, util.nspath_eval('inspire_common:ResourceType', self.inspire_namespaces)).text = 'service' # Temporal Reference temp_ref = etree.SubElement(ex_caps, util.nspath_eval('inspire_common:TemporalReference', self.inspire_namespaces)) temp_extent = etree.SubElement(temp_ref, util.nspath_eval('inspire_common:TemporalExtent', self.inspire_namespaces)) val = self.inspire_config['temp_extent'] interval_dates = etree.SubElement(temp_extent, util.nspath_eval('inspire_common:IntervalOfDates', self.inspire_namespaces)) etree.SubElement(interval_dates, util.nspath_eval('inspire_common:StartingDate', self.inspire_namespaces)).text = str(val['begin']) etree.SubElement(interval_dates, util.nspath_eval('inspire_common:EndDate', self.inspire_namespaces)).text = str(val['end']) # Conformity - service cfm = etree.SubElement(ex_caps, util.nspath_eval('inspire_common:Conformity', self.inspire_namespaces)) spec = etree.SubElement(cfm, util.nspath_eval('inspire_common:Specification', self.inspire_namespaces)) spec.attrib[util.nspath_eval('xsi:type', self.context.namespaces)] = 'inspire_common:citationInspireInteroperabilityRegulation_eng' etree.SubElement(spec, util.nspath_eval('inspire_common:Title', self.inspire_namespaces)).text = 'COMMISSION REGULATION (EU) No 1089/2010 of 23 November 2010 implementing Directive 2007/2/EC of the European Parliament and of the Council as regards interoperability of spatial data sets and services' etree.SubElement(spec, util.nspath_eval('inspire_common:DateOfPublication', self.inspire_namespaces)).text = '2010-12-08' etree.SubElement(spec, util.nspath_eval('inspire_common:URI', self.inspire_namespaces)).text = 'OJ:L:2010:323:0011:0102:EN:PDF' spec_loc = etree.SubElement(spec, util.nspath_eval('inspire_common:ResourceLocator', self.inspire_namespaces)) etree.SubElement(spec_loc, util.nspath_eval('inspire_common:URL', self.inspire_namespaces)).text = 'http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2010:323:0011:0102:EN:PDF' etree.SubElement(spec_loc, util.nspath_eval('inspire_common:MediaType', self.inspire_namespaces)).text = 'application/pdf' spec = etree.SubElement(cfm, util.nspath_eval('inspire_common:Degree', self.inspire_namespaces)).text = self.inspire_config['conformity_service'] # Metadata Point of Contact poc = etree.SubElement(ex_caps, util.nspath_eval('inspire_common:MetadataPointOfContact', self.inspire_namespaces)) etree.SubElement(poc, util.nspath_eval('inspire_common:OrganisationName', self.inspire_namespaces)).text = self.inspire_config['contact_name'] etree.SubElement(poc, util.nspath_eval('inspire_common:EmailAddress', self.inspire_namespaces)).text = self.inspire_config['contact_email'] # Metadata Date etree.SubElement(ex_caps, util.nspath_eval('inspire_common:MetadataDate', self.inspire_namespaces)).text = str(self.inspire_config['date']) # Spatial Data Service Type etree.SubElement(ex_caps, util.nspath_eval('inspire_common:SpatialDataServiceType', self.inspire_namespaces)).text = 'discovery' # Mandatory Keyword mkey = etree.SubElement(ex_caps, util.nspath_eval('inspire_common:MandatoryKeyword', self.inspire_namespaces)) mkey.attrib[util.nspath_eval('xsi:type', self.context.namespaces)] = 'inspire_common:classificationOfSpatialDataService' etree.SubElement(mkey, util.nspath_eval('inspire_common:KeywordValue', self.inspire_namespaces)).text = 'infoCatalogueService' # Gemet Keywords for gkw in self.inspire_config['gemet_keywords']: gkey = etree.SubElement(ex_caps, util.nspath_eval('inspire_common:Keyword', self.inspire_namespaces)) gkey.attrib[util.nspath_eval('xsi:type', self.context.namespaces)] = 'inspire_common:inspireTheme_eng' ocv = etree.SubElement(gkey, util.nspath_eval('inspire_common:OriginatingControlledVocabulary', self.inspire_namespaces)) etree.SubElement(ocv, util.nspath_eval('inspire_common:Title', self.inspire_namespaces)).text = 'GEMET - INSPIRE themes' etree.SubElement(ocv, util.nspath_eval('inspire_common:DateOfPublication', self.inspire_namespaces)).text = '2008-06-01' etree.SubElement(gkey, util.nspath_eval('inspire_common:KeywordValue', self.inspire_namespaces)).text = gkw # Languages slang = etree.SubElement(ex_caps, util.nspath_eval('inspire_common:SupportedLanguages', self.inspire_namespaces)) dlang = etree.SubElement(slang, util.nspath_eval('inspire_common:DefaultLanguage', self.inspire_namespaces)) etree.SubElement(dlang, util.nspath_eval('inspire_common:Language', self.inspire_namespaces)).text = self.inspire_config['default_language'] for l in self.inspire_config['languages_supported']: lang = etree.SubElement(slang, util.nspath_eval('inspire_common:SupportedLanguage', self.inspire_namespaces)) etree.SubElement(lang, util.nspath_eval('inspire_common:Language', self.inspire_namespaces)).text = l clang = etree.SubElement(ex_caps, util.nspath_eval('inspire_common:ResponseLanguage', self.inspire_namespaces)) etree.SubElement(clang, util.nspath_eval('inspire_common:Language', self.inspire_namespaces)).text = self.inspire_config['current_language'] return ex_caps def get_schemacomponents(self): ''' Return schema components as lxml.etree.Element list ''' node1 = etree.Element( util.nspath_eval('csw:SchemaComponent', self.context.namespaces), schemaLanguage='XMLSCHEMA', targetNamespace=self.namespace, parentSchema='gmd.xsd') schema_file = os.path.join(self.context.pycsw_home, 'plugins', 'profiles', 'apiso', 'schemas', 'ogc', 'iso', '19139', '20060504', 'gmd', 'identification.xsd') schema = etree.parse(schema_file, self.context.parser).getroot() node1.append(schema) node2 = etree.Element( util.nspath_eval('csw:SchemaComponent', self.context.namespaces), schemaLanguage='XMLSCHEMA', targetNamespace=self.namespace, parentSchema='gmd.xsd') schema_file = os.path.join(self.context.pycsw_home, 'plugins', 'profiles', 'apiso', 'schemas', 'ogc', 'iso', '19139', '20060504', 'srv', 'serviceMetadata.xsd') schema = etree.parse(schema_file, self.context.parser).getroot() node2.append(schema) return [node1, node2] def check_getdomain(self, kvp): '''Perform extra profile specific checks in the GetDomain request''' return None def write_record(self, result, esn, outputschema, queryables, caps=None): ''' Return csw:SearchResults child as lxml.etree.Element ''' typename = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Typename']) is_iso_anyway = False xml_blob = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:XML']) #xml_blob_decoded = bytes.fromhex(xml_blob[2:]).decode('utf-8') if isinstance(xml_blob, bytes): iso_string = b'' else: iso_string = '' if caps is None and xml_blob is not None and xml_blob.startswith(iso_string): is_iso_anyway = True if (esn == 'full' and (typename == 'gmd:MD_Metadata' or is_iso_anyway)): # dump record as is and exit return etree.fromstring(xml_blob, self.context.parser) node = etree.Element(util.nspath_eval('gmd:MD_Metadata', self.namespaces)) node.attrib[util.nspath_eval('xsi:schemaLocation', self.context.namespaces)] = \ '%s %s/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd' % (self.namespace, self.ogc_schemas_base) # identifier idval = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Identifier']) identifier = etree.SubElement(node, util.nspath_eval('gmd:fileIdentifier', self.namespaces)) etree.SubElement(identifier, util.nspath_eval('gco:CharacterString', self.namespaces)).text = idval if esn in ['summary', 'full']: # language val = util.getqattr(result, queryables['apiso:Language']['dbcol']) lang = etree.SubElement(node, util.nspath_eval('gmd:language', self.namespaces)) etree.SubElement(lang, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val # hierarchyLevel mtype = util.getqattr(result, queryables['apiso:Type']['dbcol']) or None if mtype is not None: if mtype == 'http://purl.org/dc/dcmitype/Dataset': mtype = 'dataset' hierarchy = etree.SubElement(node, util.nspath_eval('gmd:hierarchyLevel', self.namespaces)) hierarchy.append(_write_codelist_element('gmd:MD_ScopeCode', mtype, self.namespaces)) if esn in ['summary', 'full']: # contact contact = etree.SubElement(node, util.nspath_eval('gmd:contact', self.namespaces)) if caps is not None: CI_resp = etree.SubElement(contact, util.nspath_eval('gmd:CI_ResponsibleParty', self.namespaces)) if hasattr(caps.provider.contact, 'name'): ind_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:individualName', self.namespaces)) etree.SubElement(ind_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.name if hasattr(caps.provider.contact, 'organization'): if caps.provider.contact.organization is not None: org_val = caps.provider.contact.organization else: org_val = caps.provider.name org_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:organisationName', self.namespaces)) etree.SubElement(org_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = org_val if hasattr(caps.provider.contact, 'position'): pos_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:positionName', self.namespaces)) etree.SubElement(pos_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.position contact_info = etree.SubElement(CI_resp, util.nspath_eval('gmd:contactInfo', self.namespaces)) ci_contact = etree.SubElement(contact_info, util.nspath_eval('gmd:CI_Contact', self.namespaces)) if hasattr(caps.provider.contact, 'phone'): phone = etree.SubElement(ci_contact, util.nspath_eval('gmd:phone', self.namespaces)) ci_phone = etree.SubElement(phone, util.nspath_eval('gmd:CI_Telephone', self.namespaces)) voice = etree.SubElement(ci_phone, util.nspath_eval('gmd:voice', self.namespaces)) etree.SubElement(voice, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.phone if hasattr(caps.provider.contact, 'fax'): fax = etree.SubElement(ci_phone, util.nspath_eval('gmd:facsimile', self.namespaces)) etree.SubElement(fax, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.fax address = etree.SubElement(ci_contact, util.nspath_eval('gmd:address', self.namespaces)) ci_address = etree.SubElement(address, util.nspath_eval('gmd:CI_Address', self.namespaces)) if hasattr(caps.provider.contact, 'address'): delivery_point = etree.SubElement(ci_address, util.nspath_eval('gmd:deliveryPoint', self.namespaces)) etree.SubElement(delivery_point, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.address if hasattr(caps.provider.contact, 'city'): city = etree.SubElement(ci_address, util.nspath_eval('gmd:city', self.namespaces)) etree.SubElement(city, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.city if hasattr(caps.provider.contact, 'region'): admin_area = etree.SubElement(ci_address, util.nspath_eval('gmd:administrativeArea', self.namespaces)) etree.SubElement(admin_area, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.region if hasattr(caps.provider.contact, 'postcode'): postal_code = etree.SubElement(ci_address, util.nspath_eval('gmd:postalCode', self.namespaces)) etree.SubElement(postal_code, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.postcode if hasattr(caps.provider.contact, 'country'): country = etree.SubElement(ci_address, util.nspath_eval('gmd:country', self.namespaces)) etree.SubElement(country, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.country if hasattr(caps.provider.contact, 'email'): email = etree.SubElement(ci_address, util.nspath_eval('gmd:electronicMailAddress', self.namespaces)) etree.SubElement(email, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.email contact_url = None if hasattr(caps.provider, 'url'): contact_url = caps.provider.url if hasattr(caps.provider.contact, 'url') and caps.provider.contact.url is not None: contact_url = caps.provider.contact.url if contact_url is not None: online_resource = etree.SubElement(ci_contact, util.nspath_eval('gmd:onlineResource', self.namespaces)) gmd_linkage = etree.SubElement(online_resource, util.nspath_eval('gmd:linkage', self.namespaces)) etree.SubElement(gmd_linkage, util.nspath_eval('gmd:URL', self.namespaces)).text = contact_url if hasattr(caps.provider.contact, 'role'): role = etree.SubElement(CI_resp, util.nspath_eval('gmd:role', self.namespaces)) role_val = caps.provider.contact.role if role_val is None: role_val = 'pointOfContact' etree.SubElement(role, util.nspath_eval('gmd:CI_RoleCode', self.namespaces), codeListValue=role_val, codeList='%s#CI_RoleCode' % CODELIST).text = role_val else: val = util.getqattr(result, queryables['apiso:OrganisationName']['dbcol']) if val: CI_resp = etree.SubElement(contact, util.nspath_eval('gmd:CI_ResponsibleParty', self.namespaces)) org_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:organisationName', self.namespaces)) etree.SubElement(org_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val # date val = util.getqattr(result, queryables['apiso:Modified']['dbcol']) date = etree.SubElement(node, util.nspath_eval('gmd:dateStamp', self.namespaces)) if val and val.find('T') != -1: dateel = 'gco:DateTime' else: dateel = 'gco:Date' etree.SubElement(date, util.nspath_eval(dateel, self.namespaces)).text = val metadatastandardname = 'ISO19115' metadatastandardversion = '2003/Cor.1:2006' if mtype == 'service': metadatastandardname = 'ISO19119' metadatastandardversion = '2005/PDAM 1' # metadata standard name standard = etree.SubElement(node, util.nspath_eval('gmd:metadataStandardName', self.namespaces)) etree.SubElement(standard, util.nspath_eval('gco:CharacterString', self.namespaces)).text = metadatastandardname # metadata standard version standardver = etree.SubElement(node, util.nspath_eval('gmd:metadataStandardVersion', self.namespaces)) etree.SubElement(standardver, util.nspath_eval('gco:CharacterString', self.namespaces)).text = metadatastandardversion # title val = util.getqattr(result, queryables['apiso:Title']['dbcol']) or '' identification = etree.SubElement(node, util.nspath_eval('gmd:identificationInfo', self.namespaces)) if mtype == 'service': restagname = 'srv:SV_ServiceIdentification' else: restagname = 'gmd:MD_DataIdentification' resident = etree.SubElement(identification, util.nspath_eval(restagname, self.namespaces), id=idval) tmp2 = etree.SubElement(resident, util.nspath_eval('gmd:citation', self.namespaces)) tmp3 = etree.SubElement(tmp2, util.nspath_eval('gmd:CI_Citation', self.namespaces)) tmp4 = etree.SubElement(tmp3, util.nspath_eval('gmd:title', self.namespaces)) etree.SubElement(tmp4, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val # edition val = util.getqattr(result, queryables['apiso:Edition']['dbcol']) if val is not None: tmp4 = etree.SubElement(tmp3, util.nspath_eval('gmd:edition', self.namespaces)) etree.SubElement(tmp4, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val # creation date val = util.getqattr(result, queryables['apiso:CreationDate']['dbcol']) if val is not None: tmp3.append(_write_date(val, 'creation', self.namespaces)) # publication date val = util.getqattr(result, queryables['apiso:PublicationDate']['dbcol']) if val is not None: tmp3.append(_write_date(val, 'publication', self.namespaces)) # revision date val = util.getqattr(result, queryables['apiso:RevisionDate']['dbcol']) if val is not None: tmp3.append(_write_date(val, 'revision', self.namespaces)) if esn in ['summary', 'full']: # abstract val = util.getqattr(result, queryables['apiso:Abstract']['dbcol']) or '' tmp = etree.SubElement(resident, util.nspath_eval('gmd:abstract', self.namespaces)) etree.SubElement(tmp, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val # keywords kw = util.getqattr(result, queryables['apiso:Subject']['dbcol']) if kw is not None: md_keywords = etree.SubElement(resident, util.nspath_eval('gmd:descriptiveKeywords', self.namespaces)) md_keywords.append(write_keywords(kw, self.namespaces)) # spatial resolution val = util.getqattr(result, queryables['apiso:Denominator']['dbcol']) if val: tmp = etree.SubElement(resident, util.nspath_eval('gmd:spatialResolution', self.namespaces)) tmp2 = etree.SubElement(tmp, util.nspath_eval('gmd:MD_Resolution', self.namespaces)) tmp3 = etree.SubElement(tmp2, util.nspath_eval('gmd:equivalentScale', self.namespaces)) tmp4 = etree.SubElement(tmp3, util.nspath_eval('gmd:MD_RepresentativeFraction', self.namespaces)) tmp5 = etree.SubElement(tmp4, util.nspath_eval('gmd:denominator', self.namespaces)) etree.SubElement(tmp5, util.nspath_eval('gco:Integer', self.namespaces)).text = str(val) # resource language val = util.getqattr(result, queryables['apiso:ResourceLanguage']['dbcol']) tmp = etree.SubElement(resident, util.nspath_eval('gmd:language', self.namespaces)) etree.SubElement(tmp, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val # topic category val = util.getqattr(result, queryables['apiso:TopicCategory']['dbcol']) if val: for v in val.split(','): tmp = etree.SubElement(resident, util.nspath_eval('gmd:topicCategory', self.namespaces)) etree.SubElement(tmp, util.nspath_eval('gmd:MD_TopicCategoryCode', self.namespaces)).text = val # bbox extent val = util.getqattr(result, queryables['apiso:BoundingBox']['dbcol']) bboxel = write_extent(val, self.namespaces) if bboxel is not None and mtype != 'service': resident.append(bboxel) # service identification if mtype == 'service': # service type # service type version val = util.getqattr(result, queryables['apiso:ServiceType']['dbcol']) val2 = util.getqattr(result, queryables['apiso:ServiceTypeVersion']['dbcol']) if val is not None: tmp = etree.SubElement(resident, util.nspath_eval('srv:serviceType', self.namespaces)) etree.SubElement(tmp, util.nspath_eval('gco:LocalName', self.namespaces)).text = val tmp = etree.SubElement(resident, util.nspath_eval('srv:serviceTypeVersion', self.namespaces)) etree.SubElement(tmp, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val2 kw = util.getqattr(result, queryables['apiso:Subject']['dbcol']) if kw is not None: srv_keywords = etree.SubElement(resident, util.nspath_eval('srv:keywords', self.namespaces)) srv_keywords.append(write_keywords(kw, self.namespaces)) if bboxel is not None: bboxel.tag = util.nspath_eval('srv:extent', self.namespaces) resident.append(bboxel) val = util.getqattr(result, queryables['apiso:CouplingType']['dbcol']) if val is not None: couplingtype = etree.SubElement(resident, util.nspath_eval('srv:couplingType', self.namespaces)) etree.SubElement(couplingtype, util.nspath_eval('srv:SV_CouplingType', self.namespaces), codeListValue=val, codeList='%s#SV_CouplingType' % CODELIST).text = val if esn in ['summary', 'full']: # all service resources as coupled resources coupledresources = util.getqattr(result, queryables['apiso:OperatesOn']['dbcol']) operations = util.getqattr(result, queryables['apiso:Operation']['dbcol']) if coupledresources: for val2 in coupledresources.split(','): coupledres = etree.SubElement(resident, util.nspath_eval('srv:coupledResource', self.namespaces)) svcoupledres = etree.SubElement(coupledres, util.nspath_eval('srv:SV_CoupledResource', self.namespaces)) opname = etree.SubElement(svcoupledres, util.nspath_eval('srv:operationName', self.namespaces)) etree.SubElement(opname, util.nspath_eval('gco:CharacterString', self.namespaces)).text = _get_resource_opname(operations) sid = etree.SubElement(svcoupledres, util.nspath_eval('srv:identifier', self.namespaces)) etree.SubElement(sid, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val2 # service operations if operations: for i in operations.split(','): oper = etree.SubElement(resident, util.nspath_eval('srv:containsOperations', self.namespaces)) tmp = etree.SubElement(oper, util.nspath_eval('srv:SV_OperationMetadata', self.namespaces)) tmp2 = etree.SubElement(tmp, util.nspath_eval('srv:operationName', self.namespaces)) etree.SubElement(tmp2, util.nspath_eval('gco:CharacterString', self.namespaces)).text = i tmp3 = etree.SubElement(tmp, util.nspath_eval('srv:DCP', self.namespaces)) etree.SubElement(tmp3, util.nspath_eval('srv:DCPList', self.namespaces), codeList='%s#DCPList' % CODELIST, codeListValue='HTTPGet').text = 'HTTPGet' tmp4 = etree.SubElement(tmp, util.nspath_eval('srv:DCP', self.namespaces)) etree.SubElement(tmp4, util.nspath_eval('srv:DCPList', self.namespaces), codeList='%s#DCPList' % CODELIST, codeListValue='HTTPPost').text = 'HTTPPost' connectpoint = etree.SubElement(tmp, util.nspath_eval('srv:connectPoint', self.namespaces)) onlineres = etree.SubElement(connectpoint, util.nspath_eval('gmd:CI_OnlineResource', self.namespaces)) linkage = etree.SubElement(onlineres, util.nspath_eval('gmd:linkage', self.namespaces)) etree.SubElement(linkage, util.nspath_eval('gmd:URL', self.namespaces)).text = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Source']) # operates on resource(s) if coupledresources: for i in coupledresources.split(','): operates_on = etree.SubElement(resident, util.nspath_eval('srv:operatesOn', self.namespaces), uuidref=i) operates_on.attrib[util.nspath_eval('xlink:href', self.namespaces)] = '%sservice=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=%s-%s' % (util.bind_url(self.url), idval, i) rlinks = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Links']) if rlinks: distinfo = etree.SubElement(node, util.nspath_eval('gmd:distributionInfo', self.namespaces)) distinfo2 = etree.SubElement(distinfo, util.nspath_eval('gmd:MD_Distribution', self.namespaces)) transopts = etree.SubElement(distinfo2, util.nspath_eval('gmd:transferOptions', self.namespaces)) dtransopts = etree.SubElement(transopts, util.nspath_eval('gmd:MD_DigitalTransferOptions', self.namespaces)) for link in util.jsonify_links(rlinks): online = etree.SubElement(dtransopts, util.nspath_eval('gmd:onLine', self.namespaces)) online2 = etree.SubElement(online, util.nspath_eval('gmd:CI_OnlineResource', self.namespaces)) linkage = etree.SubElement(online2, util.nspath_eval('gmd:linkage', self.namespaces)) etree.SubElement(linkage, util.nspath_eval('gmd:URL', self.namespaces)).text = link['url'] protocol = etree.SubElement(online2, util.nspath_eval('gmd:protocol', self.namespaces)) etree.SubElement(protocol, util.nspath_eval('gco:CharacterString', self.namespaces)).text = link.get('protocol', 'WWW:LINK') name = etree.SubElement(online2, util.nspath_eval('gmd:name', self.namespaces)) etree.SubElement(name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = link.get('name') desc = etree.SubElement(online2, util.nspath_eval('gmd:description', self.namespaces)) etree.SubElement(desc, util.nspath_eval('gco:CharacterString', self.namespaces)).text = link.get('description') return node def write_keywords(keywords, nsmap): """generate gmd:MD_Keywords construct""" md_keywords = etree.Element(util.nspath_eval('gmd:MD_Keywords', nsmap)) for kw in keywords.split(','): keyword = etree.SubElement(md_keywords, util.nspath_eval('gmd:keyword', nsmap)) etree.SubElement(keyword, util.nspath_eval('gco:CharacterString', nsmap)).text = kw return md_keywords def write_extent(bbox, nsmap): ''' Generate BBOX extent ''' if bbox is not None: try: bbox2 = util.wkt2geom(bbox) except Exception as err: LOGGER.debug(f'Geometry parsing error: {err}') return None extent = etree.Element(util.nspath_eval('gmd:extent', nsmap)) ex_extent = etree.SubElement(extent, util.nspath_eval('gmd:EX_Extent', nsmap)) ge = etree.SubElement(ex_extent, util.nspath_eval('gmd:geographicElement', nsmap)) gbb = etree.SubElement(ge, util.nspath_eval('gmd:EX_GeographicBoundingBox', nsmap)) west = etree.SubElement(gbb, util.nspath_eval('gmd:westBoundLongitude', nsmap)) east = etree.SubElement(gbb, util.nspath_eval('gmd:eastBoundLongitude', nsmap)) south = etree.SubElement(gbb, util.nspath_eval('gmd:southBoundLatitude', nsmap)) north = etree.SubElement(gbb, util.nspath_eval('gmd:northBoundLatitude', nsmap)) etree.SubElement(west, util.nspath_eval('gco:Decimal', nsmap)).text = str(bbox2[0]) etree.SubElement(south, util.nspath_eval('gco:Decimal', nsmap)).text = str(bbox2[1]) etree.SubElement(east, util.nspath_eval('gco:Decimal', nsmap)).text = str(bbox2[2]) etree.SubElement(north, util.nspath_eval('gco:Decimal', nsmap)).text = str(bbox2[3]) return extent return None def _write_date(dateval, datetypeval, nsmap): date1 = etree.Element(util.nspath_eval('gmd:date', nsmap)) date2 = etree.SubElement(date1, util.nspath_eval('gmd:CI_Date', nsmap)) date3 = etree.SubElement(date2, util.nspath_eval('gmd:date', nsmap)) if dateval.find('T') != -1: dateel = 'gco:DateTime' else: dateel = 'gco:Date' etree.SubElement(date3, util.nspath_eval(dateel, nsmap)).text = dateval datetype = etree.SubElement(date2, util.nspath_eval('gmd:dateType', nsmap)) datetype.append(_write_codelist_element('gmd:CI_DateTypeCode', datetypeval, nsmap)) return date1 def _get_resource_opname(operations): for op in operations.split(','): if op in ['GetMap', 'GetFeature', 'GetCoverage', 'GetObservation']: return op return None def _write_codelist_element(codelist_element, codelist_value, nsmap): namespace, codelist = codelist_element.split(':') element = etree.Element(util.nspath_eval(codelist_element, nsmap), codeSpace=CODESPACE, codeList='%s#%s' % (CODELIST, codelist), codeListValue=codelist_value) element.text = codelist_value return element ================================================ FILE: pycsw/plugins/profiles/apiso/docs/apiso.rst ================================================ .. _apiso: ISO Metadata Application Profile (1.0.0) ---------------------------------------- Overview ^^^^^^^^ The ISO Metadata Application Profile (APISO) is a profile of CSW 2.0.2 which enables discovery of geospatial metadata following ISO 19139:2007 and ISO 19119:2005/PDAM 1. Configuration ^^^^^^^^^^^^^ No extra configuration is required. Querying ^^^^^^^^ * **typename**: ``gmd:MD_Metadata`` * **outputschema**: ``http://www.isotc211.org/2005/gmd`` Enabling APISO Support ^^^^^^^^^^^^^^^^^^^^^^ To enable APISO support, add ``apiso`` to ``profiles`` as specified in :ref:`configuration`. Testing ^^^^^^^ A testing interface is available in ``tests/index.html`` which contains tests specific to APISO to demonstrate functionality. See :ref:`tests` for more information. INSPIRE Extension ----------------- Overview ^^^^^^^^ APISO includes an extension for enabling `INSPIRE Discovery Services 3.0`_ support. To enable the INSPIRE extension to APISO, create a ``[metadata:inspire]`` section in the main configuration with ``enabled`` set to ``true``. Configuration ^^^^^^^^^^^^^ INSPIRE configuration is specified within ``metadata.inspire``: **inspire** - **enabled**: whether to enable the INSPIRE extension (``true`` or ``false``) - **languages_supported**: supported languages (see http://inspire.ec.europa.eu/schemas/common/1.0/enums/enum_eng.xsd, simpleType ``euLanguageISO6392B``) - **default_language**: the default language (see http://inspire.ec.europa.eu/schemas/common/1.0/enums/enum_eng.xsd, simpleType ``euLanguageISO6392B``) - **date**: date of INSPIRE metadata offering (in `ISO 8601`_ format) - **gemet_keywords**: list of `GEMET INSPIRE theme keywords`_ about the service (see http://inspire.ec.europa.eu/schemas/common/1.0/enums/enum_eng.xsd, complexType ``inspireTheme_eng``) - **conformity_service**: the level of INSPIRE conformance for spatial data sets and services (``conformant``, ``notConformant``, ``notEvaluated``) - **contact_organization**: the organization name responsible for the INSPIRE metadata - **contact_email**: the email address of entity responsible for the INSPIRE metadata - **temp_extent**: temporal extent of the service (in `ISO 8601`_ format). Either a single date (i.e. ``yyyy-mm-dd``), or an extent (i.e. ``yyyy-mm-dd/yyyy-mm-dd``) .. _`INSPIRE Discovery Services 3.0`: http://inspire.jrc.ec.europa.eu/documents/Network_Services/TechnicalGuidance_DiscoveryServices_v3.0.pdf .. _`GEMET INSPIRE theme keywords`: http://www.eionet.europa.eu/gemet/inspire_themes .. _`ISO 8601`: http://en.wikipedia.org/wiki/ISO_8601 ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/csw/2.0.2/profiles/apiso/1.0.0/ReadMe.txt ================================================ OpenGIS(r) CSW 2.0.2 ISO Metadata Application Profile ReadMe.txt 2007-07-19 Uwe Voges * csw/2.0.2/profiles/apiso/1.0.0: See OGC 07-045 for associated specification * apiso/1.0.0: validated using oXygen XML Editor 8.2 build 2007062515 (Xerces-J 2.9.0) - kstegemoller * apiso/1.0.0: validated using XMLSpy 2007 sp1 - Uwe Voges * iso/19139/20060504: added ISO-19139 used by apiso/1.0.0 * APISO 1.0.0 builds upon the following schemas + OGC csw/2.0.2 + OGC xlink/1.0.0 + ISO iso/19139/20060504 + OGC ows/1.0.0 + OGC filter/1.1.0 + OGC gml/3.1.1/base The Open Geospatial Consortium, Inc. official schema repository is at http://schemas.opengis.net/ . Policies, Procedures, Terms, and Conditions of OGC(r) are available http://www.opengeospatial.org/ogc/policies/ . Additional rights of use are described at http://www.opengeospatial.org/legal/ . Copyright (c) 2007 Open Geospatial Consortium, Inc. All Rights Reserved. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd ================================================ ISO Wrapper to include service related type to GMD ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/ReadMe.txt ================================================ 19139 XSchemas TS RC (2006 May 4) ----------------------------------------------- OGC GML 3.2.0 version => ISO 19136 XSchemas DIS (2005 november) -- http://www.isotc211.org/2005/ These schemas from ISO 19139 version 2005-DIS (Draft International Standard) dated 2006 May 4. For the sake of convenience, GML 3.2 XML schemas (version 19136 DIS - 2005 november) are (temporarily) provided with the 19139 set of schemas. They were retrieved from http://www.isotc211.org/2005/ . Once these schemas are finalized they will become OGC GML 3.2.1 and ISO/TS 19136. Changes made to these ISO 19139 schemas by OGC: * changed xlink references from ../xlink/xlinks.xsd to ../../../../xlink/1.0.0/xlinks.xsd so they use http://schemas.opengis.net/xlink/1.0.0/xlinks.xsd . * removed xlinks directory and schema * replaced 19139-GML_readme.txt with this document. -- Kevin Stegemoller 2007-08-14 ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/Version.txt ================================================ 19139 XSchemas TS RC (2006 May 4) ----------------------------------------------- GML version => 19136 XSchemas DIS (2005 november) ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:00:05 ====== A TypeName is a LocalName that references either a recordType or object type in some form of schema. The stored value "aName" is the returned value for the "aName()" operation. This is the types name. - For parsing from types (or objects) the parsible name normally uses a "." navigation separator, so that it is of the form [class].[member].[memberOfMember]. ...) A MemberName is a LocalName that references either an attribute slot in a record or recordType or an attribute, operation, or association role in an object instance or type description in some form of schema. The stored value "aName" is the returned value for the "aName()" operation. Use to represent the possible cardinality of a relation. Represented by a set of simple multiplicity ranges. A component of a multiplicity, consisting of an non-negative lower bound, and a potentially infinite upper bound. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gco.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:00:06 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd ================================================ This schema provides: 1. tools to handle specific objects like "code lists" and "record"; 2. Some XML types representing that do not follow the general encoding rules. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/applicationSchema.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:03 ====== Information about the application schema used to build the dataset ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/citation.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:04 ====== Identification of, and means of communication with, person(s) and organisations associated with the dataset Standardized resource reference Location of the responsible individual or organisation Information about online sources from which the dataset, specification, or community profile name and extended metadata elements can be obtained. Information required enabling contact with the responsible person and/or organisation Telephone numbers for contacting the responsible individual or organisation ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/constraints.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:01 ====== Restrictions on the access and use of a dataset or metadata Restrictions and legal prerequisites for accessing and using the dataset. Handling restrictions imposed on the dataset because of national security, privacy, or other concerns ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/content.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:03 ====== Information identifing the feature catalogue Information about the domain of the raster cell Information about an image's suitability for use Set of adjacent wavelengths in the electro-magnetic spectrum with a common characteristic, such as the visible band ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/dataQuality.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:01 ====== quantitative_result from Quality Procedures - - renamed to remove implied use limitiation. Quantitative_conformance_measure from Quality Procedures. - - Renamed to remove implied use limitation - - OCL - -- result is type specified by valueDomain - result.tupleType = valueDomain ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/distribution.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:03 ====== Information about the media on which the data can be distributed Technical means and media by which a dataset is obtained from the distributor Common ways in which the dataset may be obtained or received, and related instructions and fee information Information about the distributor Information about the distributor of and options for obtaining the dataset Description of the form of the data to be distributed ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/extent.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:04 ====== Time period covered by the content of the dataset Vertical domain of dataset Boundary enclosing the dataset expressed as the closed set of (x,y) coordinates of the polygon (last point replicates first point) Information about spatial, vertical, and temporal extent Geographic area of the dataset Geographic area of the entire dataset referenced to WGS 84 Extent with respect to date and time ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/freeText.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 03-17-2005 17:21:53 ====== Informative package (concepts are not implementable) - pragmatic approach for encoding ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/gmd.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:04 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/identification.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:05 ====== Basic information about data Graphic that provides an illustration of the dataset (should include a legend for the graphic) See 19119 for further info Brief description of ways in which the dataset is currently used. Keywords, their type and reference source Encapsulates the dataset aggregation information High-level geospatial data thematic classification to assist in the grouping and search of available geospatial datasets ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/maintenance.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:04 ====== Status of the dataset or progress of a review Information about the scope and frequency of updating Description of the class of information covered by the information ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/metadataApplication.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:05 ====== Identifiable collection of datasets Identifiable collection of data ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/metadataEntity.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:00 ====== Information about the metadata ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/metadataExtension.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:03 ====== Method used to represent geographic information in the dataset New metadata element, not found in ISO 19115, which is required to describe geographic data Information describing metadata extensions. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/portrayalCatalogue.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:03 ====== Information identifing the portrayal catalogue used ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/referenceSystem.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:04 ====== Description of the spatial and temporal reference systems used in the dataset ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/spatialRepresentation.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:02 ====== Frequency with which modifications and deletations are made to the data after it is first produced Types and numbers of raster spatial objects in the dataset Information about the vector spatial objects in the dataset Digital mechanism used to represent spatial information ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/ReadMe.txt ================================================ 19139 XSchemas TS RC (2006 May 4) ----------------------------------------------- OGC GML 3.2.0 version => ISO 19136 XSchemas DIS (2005 november) -- http://www.isotc211.org/2005/ These schemas from ISO 19139 version 2005-DIS (Draft International Standard) dated 2006 May 4. For the sake of convenience, GML 3.2 XML schemas (version 19136 DIS - 2005 november) are (temporarily) provided with the 19139 set of schemas. They were retrieved from http://www.isotc211.org/2005/ . Once these schemas are finalized they will become OGC GML 3.2.1 and ISO/TS 19136. Changes made to these ISO 19139 schemas by OGC: * changed xlink references from ../xlink/xlinks.xsd to ../../../../xlink/1.0.0/xlinks.xsd so they use http://schemas.opengis.net/xlink/1.0.0/xlinks.xsd . (see W3C XLink 1.0) * removed xlinks directory and schema * replaced 19139-GML_readme.txt with this document. In Folder "gml": the GML Schema; the root document of the GML Schema is file "gml/gml.xsd" Imported schemas: - Folder "xlink": the W3C XLink schema (see W3C XLink 1.0) - iso19139 schemas: the GMD schema and contained schemas (see ISO/TS 19139) ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/basicTypes.xsd ================================================ basicTypes.xsd See ISO/DIS 19136 8.2. W3C XML Schema provides a set of built-in “simple” types which define methods for representing values as literals without internal markup. These are described in W3C XML Schema Part 2:2001. Because GML is an XML encoding in which instances are described using XML Schema, these simple types shall be used as far as possible and practical for the representation of data types. W3C XML Schema also provides methods for defining - new simple types by restriction and combination of the built-in types, and - complex types, with simple content, but which also have XML attributes. In many places where a suitable built-in simple type is not available, simple content types derived using the XML Schema mechanisms are used for the representation of data types in GML. A set of these simple content types that are required by several GML components are defined in the basicTypes schema, as well as some elements based on them. These are primarily based around components needed to record amounts, counts, flags and terms, together with support for exceptions or null values. gml:NilReasonType defines a content model that allows recording of an explanation for a void value or other exception. gml:NilReasonType is a union of the following enumerated values: - inapplicable there is no value - missing the correct value is not readily available to the sender of this data. Furthermore, a correct value may not exist - template the value will be available later - unknown the correct value is not known to, and not computable by, the sender of this data. However, a correct value probably exists - withheld the value is not divulged - other:text other brief explanation, where text is a string of two or more characters with no included spaces and - anyURI which should refer to a resource which describes the reason for the exception A particular community may choose to assign more detailed semantics to the standard values provided. Alternatively, the URI method enables a specific or more complete explanation for the absence of a value to be provided elsewhere and indicated by-reference in an instance document. gml:NilReasonType is used as a member of a union in a number of simple content types where it is necessary to permit a value from the NilReasonType union as an alternative to the primary type. deprecated gml:SignType is a convenience type with values “+” (plus) and “-“ (minus). Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value. gml:CodeType is a generalized type to be used for a term, keyword or name. It adds a XML attribute codeSpace to a term, where the value of the codeSpace attribute (if present) shall indicate a dictionary, thesaurus, classification scheme, authority, or pattern for the term. gml:CodeWithAuthorityType requires that the codeSpace attribute is provided in an instance. gml:MeasureType supports recording an amount encoded as a value of XML Schema double, together with a units of measure indicated by an attribute uom, short for “units Of measure”. The value of the uom attribute identifies a reference system for the amount, usually a ratio or interval scale. The simple type gml:UomIdentifer defines the syntax and value space of the unit of measure identifier. This type specifies a character string of length at least one, and restricted such that it must not contain any of the following characters: “:” (colon), “ “ (space), (newline), (carriage return), (tab). This allows values corresponding to familiar abbreviations, such as “kg”, “m/s”, etc. It is recommended that the symbol be an identifier for a unit of measure as specified in the “Unified Code of Units of Measure" (UCUM) (http://aurora.regenstrief.org/UCUM). This provides a set of symbols and a grammar for constructing identifiers for units of measure that are unique, and may be easily entered with a keyboard supporting the limited character set known as 7-bit ASCII. ISO 2955 formerly provided a specification with this scope, but was withdrawn in 2001. UCUM largely follows ISO 2955 with modifications to remove ambiguities and other problems. This type specifies a URI, restricted such that it must start with one of the following sequences: “#”, “./”, “../”, or a string of characters followed by a “:”. These patterns ensure that the most common URI forms are supported, including absolute and relative URIs and URIs that are simple fragment identifiers, but prohibits certain forms of relative URI that could be mistaken for unit of measure symbol . NOTE It is possible to re-write such a relative URI to conform to the restriction (e.g. “./m/s”). In an instance document, on elements of type gml:MeasureType the mandatory uom attribute shall carry a value corresponding to either - a conventional unit of measure symbol, - a link to a definition of a unit of measure that does not have a conventional symbol, or when it is desired to indicate a precise or variant definition. This type is deprecated for tuples with ordinate values that are numbers. CoordinatesType is a text string, intended to be used to record an array of tuples or coordinates. While it is not possible to enforce the internal structure of the string through schema validation, some optional attributes have been provided in previous versions of GML to support a description of the internal structure. These attributes are deprecated. The attributes were intended to be used as follows: Decimal symbol used for a decimal point (default=”.” a stop or period) cs symbol used to separate components within a tuple or coordinate string (default=”,” a comma) ts symbol used to separate tuples or coordinate strings (default=” “ a space) Since it is based on the XML Schema string type, CoordinatesType may be used in the construction of tables of tuples or arrays of tuples, including ones that contain mixed text and numeric values. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. A type for a list of values of the respective simple type. gml:CodeListType provides for lists of terms. The values in an instance element shall all be valid according to the rules of the dictionary, classification scheme, or authority identified by the value of its codeSpace attribute. gml:CodeOrNilReasonListType provides for lists of terms. The values in an instance element shall all be valid according to the rules of the dictionary, classification scheme, or authority identified by the value of its codeSpace attribute. An instance element may also include embedded values from NilReasonType. It is intended to be used in situations where a term or classification is expected, but the value may be absent for some reason. gml:MeasureListType provides for a list of quantities. gml:MeasureOrNilReasonListType provides for a list of quantities. An instance element may also include embedded values from NilReasonType. It is intended to be used in situations where a value is expected, but the value may be absent for some reason. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coordinateOperations.xsd ================================================ coordinateOperations.xsd See ISO/DIS 19136 13.6. The spatial or temporal coordinate operations schema components can be divided into five logical parts, which define elements and types for XML encoding of the definitions of: - Multiple abstract coordinate operations - Multiple concrete types of coordinate operations, including Transformations and Conversions - Abstract and concrete parameter values and groups - Operation methods - Abstract and concrete operation parameters and groups These schema component encodes the Coordinate Operation package of the UML Model for ISO 19111 Clause 11. gml:AbstractCoordinateOperation is a mathematical operation on coordinates that transforms or converts coordinates to another coordinate reference system. Many but not all coordinate operations (from CRS A to CRS B) also uniquely define the inverse operation (from CRS B to CRS A). In some cases, the operation method algorithm for the inverse operation is the same as for the forward algorithm, but the signs of some operation parameter values shall be reversed. In other cases, different algorithms are required for the forward and inverse operations, but the same operation parameter values are used. If (some) entirely different parameter values are needed, a different coordinate operation shall be defined. The optional coordinateOperationAccuracy property elements provide estimates of the impact of this coordinate operation on point position accuracy. gml:operationVersion is the version of the coordinate transformation (i.e., instantiation due to the stochastic nature of the parameters). Mandatory when describing a transformation, and should not be supplied for a conversion. gml:coordinateOperationAccuracy is an association role to a DQ_PositionalAccuracy object as encoded in ISO/TS 19139, either referencing or containing the definition of that positional accuracy. That object contains an estimate of the impact of this coordinate operation on point accuracy. That is, it gives position error estimates for the target coordinates of this coordinate operation, assuming no errors in the source coordinates. gml:sourceCRS is an association role to the source CRS (coordinate reference system) of this coordinate operation. gml:targetCRS is an association role to the target CRS (coordinate reference system) of this coordinate operation. gml:CoordinateOperationPropertyType is a property type for association roles to a coordinate operation, either referencing or containing the definition of that coordinate operation. deprecated gml:AbstractSingleOperation is a single (not concatenated) coordinate operation. gml:SingleOperationPropertyType is a property type for association roles to a single operation, either referencing or containing the definition of that single operation. deprecated deprecated deprecated deprecated gm:AbstractGeneralConversion is an abstract operation on coordinates that does not include any change of datum. The best-known example of a coordinate conversion is a map projection. The parameters describing coordinate conversions are defined rather than empirically derived. Note that some conversions have no parameters. The operationVersion, sourceCRS, and targetCRS elements are omitted in a coordinate conversion. This abstract complex type is expected to be extended for well-known operation methods with many Conversion instances, in GML Application Schemas that define operation-method-specialized element names and contents. This conversion uses an operation method, usually with associated parameter values. However, operation methods and parameter values are directly associated with concrete subtypes, not with this abstract type. All concrete types derived from this type shall extend this type to include a "usesMethod" element that references the "OperationMethod" element. Similarly, all concrete types derived from this type shall extend this type to include zero or more elements each named "uses...Value" that each use the type of an element substitutable for the "AbstractGeneralParameterValue" element. gml:GeneralConversionPropertyType is a property type for association roles to a general conversion, either referencing or containing the definition of that conversion. deprecated gml:AbstractGeneralTransformation is an abstract operation on coordinates that usually includes a change of Datum. The parameters of a coordinate transformation are empirically derived from data containing the coordinates of a series of points in both coordinate reference systems. This computational process is usually "over-determined", allowing derivation of error (or accuracy) estimates for the transformation. Also, the stochastic nature of the parameters may result in multiple (different) versions of the same coordinate transformation. The operationVersion, sourceCRS, and targetCRS proeprty elements are mandatory in a coordinate transformation. This abstract complex type is expected to be extended for well-known operation methods with many Transformation instances, in Application Schemas that define operation-method-specialized value element names and contents. This transformation uses an operation method with associated parameter values. However, operation methods and parameter values are directly associated with concrete subtypes, not with this abstract type. All concrete types derived from this type shall extend this type to include a "usesMethod" element that references one "OperationMethod" element. Similarly, all concrete types derived from this type shall extend this type to include one or more elements each named "uses...Value" that each use the type of an element substitutable for the "AbstractGeneralParameterValue" element. gml:GeneralTransformationPropertyType is a property type for association roles to a general transformation, either referencing or containing the definition of that transformation. deprecated gml:ConcatenatedOperation is an ordered sequence of two or more coordinate operations. This sequence of operations is constrained by the requirement that the source coordinate reference system of step (n+1) must be the same as the target coordinate reference system of step (n). The source coordinate reference system of the first step and the target coordinate reference system of the last step are the source and target coordinate reference system associated with the concatenated operation. Instead of a forward operation, an inverse operation may be used for one or more of the operation steps mentioned above, if the inverse operation is uniquely defined by the forward operation. The gml:coordOperation property elements are an ordered sequence of associations to the two or more operations used by this concatenated operation. The AggregationAttributeGroup should be used to specify that the coordOperation associations are ordered. gml:coordOperation is an association role to a coordinate operation. deprecated gml:ConcatenatedOperationPropertyType is a property type for association roles to a concatenated operation, either referencing or containing the definition of that concatenated operation. deprecated gml:PassThroughOperation is a pass-through operation specifies that a subset of a coordinate tuple is subject to a specific coordinate operation. The modifiedCoordinate property elements are an ordered sequence of positive integers defining the positions in a coordinate tuple of the coordinates affected by this pass-through operation. The AggregationAttributeGroup should be used to specify that the modifiedCoordinate elements are ordered. gml:modifiedCoordinate is a positive integer defining a position in a coordinate tuple. gml:usesOperation is deprecated, gml:coordOperation shall be used instead. gml:PassThroughOperationPropertyType is a property type for association roles to a pass through operation, either referencing or containing the definition of that pass through operation. deprecated gml:Conversion is a concrete operation on coordinates that does not include any change of Datum. The best-known example of a coordinate conversion is a map projection. The parameters describing coordinate conversions are defined rather than empirically derived. Note that some conversions have no parameters. This concrete complex type can be used without using a GML Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one Conversion instance. The usesValue property elements are an unordered list of composition associations to the set of parameter values used by this conversion operation. gml:method is an association role to the operation method used by a coordinate operation. deprecated gml:parameterValue is a composition association to a parameter value or group of parameter values used by a coordinate operation. deprecated gml:ConversionPropertyType is a property type for association roles to a concrete general-purpose conversion, either referencing or containing the definition of that conversion. deprecated gml:Transformation is a concrete object element derived from gml:GeneralTransformation (13.6.2.13). This concrete object can be used for all operation methods, without using a GML Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one Transformation instance. The parameterValue elements are an unordered list of composition associations to the set of parameter values used by this conversion operation. gml:TransformationPropertyType is a property type for association roles to a transformation, either referencing or containing the definition of that transformation. deprecated gml:AbstractGeneralParameterValue is an abstract parameter value or group of parameter values. This abstract complexType is expected to be extended and restricted for well-known operation methods with many instances, in Application Schemas that define operation-method-specialized element names and contents. Specific parameter value elements are directly contained in concrete subtypes, not in this abstract type. All concrete types derived from this type shall extend this type to include one "...Value" element with an appropriate type, which should be one of the element types allowed in the ParameterValueType. In addition, all derived concrete types shall extend this type to include a "operationParameter" property element that references one element substitutable for the "OperationParameter" object element. gml:AbstractGeneralParameterValuePropertyType is a property type for inline association roles to a parameter value or group of parameter values, always containing the values. gml:ParameterValue is a parameter value, an ordered sequence of values, or a reference to a file of parameter values. This concrete complex type may be used for operation methods without using an Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one instance. This complex type may be used, extended, or restricted for well-known operation methods, especially for methods with many instances. gml:value is a numeric value of an operation parameter, with its associated unit of measure. deprecated gml:stringValue is a character string value of an operation parameter. A string value does not have an associated unit of measure. gml:integerValue is a positive integer value of an operation parameter, usually used for a count. An integer value does not have an associated unit of measure. gml:booleanValue is a boolean value of an operation parameter. A Boolean value does not have an associated unit of measure. gml:valueList is an ordered sequence of two or more numeric values of an operation parameter list, where each value has the same associated unit of measure. An element of this type contains a space-separated sequence of double values. gml:integerValueList is an ordered sequence of two or more integer values of an operation parameter list, usually used for counts. These integer values do not have an associated unit of measure. An element of this type contains a space-separated sequence of integer values. gml:valueFile is a reference to a file or a part of a file containing one or more parameter values, each numeric value with its associated unit of measure. When referencing a part of a file, that file shall contain multiple identified parts, such as an XML encoded document. Furthermore, the referenced file or part of a file may reference another part of the same or different files, as allowed in XML documents. gml:operationParameter is an association role to the operation parameter of which this is a value. deprecated gml:ParameterValueGroup is a group of related parameter values. The same group can be repeated more than once in a Conversion, Transformation, or higher level ParameterValueGroup, if those instances contain different values of one or more parameterValues which suitably distinquish among those groups. This concrete complex type can be used for operation methods without using an Application Schema that defines operation-method-specialized element names and contents. This complex type may be used, extended, or restricted for well-known operation methods, especially for methods with only one instance. The parameterValue elements are an unordered set of composition association roles to the parameter values and groups of values included in this group. deprecated gml:group is an association role to the operation parameter group for which this element provides parameter values. deprecated gml:OperationMethod is a method (algorithm or procedure) used to perform a coordinate operation. Most operation methods use a number of operation parameters, although some coordinate conversions use none. Each coordinate operation using the method assigns values to these parameters. The generalOperationParameter elements are an unordered list of associations to the set of operation parameters and parameter groups used by this operation method. gml:formula specifies a formula or procedure used by this operation method. The value may be a reference to a publication. Note that the operation method may not be analytic, in which case this element references or contains the procedure, not an analytic formula. deprecated gml:sourceDimensions is the number of dimensions in the source CRS of this operation method. gml:targetDimensions is the number of dimensions in the target CRS of this operation method. gml:generalOperationParameter is an association to an operation parameter or parameter group. deprecated gml:OperationMethodPropertyType is a property type for association roles to a concrete general-purpose operation method, either referencing or containing the definition of that method. deprecated gml:GeneralOperationParameter is the abstract definition of a parameter or group of parameters used by an operation method. gml:minimumOccurs is the minimum number of times that values for this parameter group or parameter are required. If this attribute is omitted, the minimum number shall be one. gml:AbstractGeneralOperationParameterPropertyType is a property type for association roles to an operation parameter or group, either referencing or containing the definition of that parameter or group. deprecated gml:OperationParameter is the definition of a parameter used by an operation method. Most parameter values are numeric, but other types of parameter values are possible. This complex type is expected to be used or extended for all operation methods, without defining operation-method-specialized element names. gml:OperationParameterPropertyType is a property type for association roles to an operation parameter, either referencing or containing the definition of that parameter. deprecated gml:OperationParameterGroup is the definition of a group of parameters used by an operation method. This complex type is expected to be used or extended for all applicable operation methods, without defining operation-method-specialized element names. The generalOperationParameter elements are an unordered list of associations to the set of operation parameters that are members of this group. gml:maximumOccurs is the maximum number of times that values for this parameter group may be included. If this attribute is omitted, the maximum number shall be one. deprecated gml:OperationParameterPropertyType is a property type for association roles to an operation parameter group, either referencing or containing the definition of that parameter group. deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coordinateReferenceSystems.xsd ================================================ coordinateReferenceSystems.xsd See ISO/DIS 19136 13.3. The spatial-temporal coordinate reference systems schema components are divided into two logical parts. One part defines elements and types for XML encoding of abstract coordinate reference systems definitions. The larger part defines specialized constructs for XML encoding of definitions of the multiple concrete types of spatial-temporal coordinate reference systems. These schema components encode the Coordinate Reference System packages of the UML Models of ISO 19111 Clause 8 and ISO/DIS 19136 D.3.10, with the exception of the abstract "SC_CRS" class. gml:AbstractSingleCRS implements a coordinate reference system consisting of one coordinate system and one datum (as opposed to a Compound CRS). gml:SingleCRSPropertyType is a property type for association roles to a single coordinate reference system, either referencing or containing the definition of that coordinate reference system. deprecated gml:AbstractGeneralDerivedCRS is a coordinate reference system that is defined by its coordinate conversion from another coordinate reference system. This abstract complex type shall not be used, extended, or restricted, in a GML Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. gml:conversion is an association role to the coordinate conversion used to define the derived CRS. deprecated gml:CompundCRS is a coordinate reference system describing the position of points through two or more independent coordinate reference systems. It is associated with a non-repeating sequence of two or more instances of SingleCRS. The gml:componentReferenceSystem elements are an ordered sequence of associations to all the component coordinate reference systems included in this compound coordinate reference system. The gml:AggregationAttributeGroup should be used to specify that the gml:componentReferenceSystem properties are ordered. deprecated gml:CompoundCRSPropertyType is a property type for association roles to a compound coordinate reference system, either referencing or containing the definition of that reference system. deprecated gml:GeodeticCRS is a coordinate reference system based on a geodetic datum. gml:ellipsoidalCS is an association role to the ellipsoidal coordinate system used by this CRS. deprecated gml:cartesianCS is an association role to the Cartesian coordinate system used by this CRS. deprecated gml:sphericalCS is an association role to the spherical coordinate system used by this CRS. deprecated gml:geodeticDatum is an association role to the geodetic datum used by this CRS. deprecated gml:GeodeticCRSPropertyType is a property type for association roles to a geodetic coordinate reference system, either referencing or containing the definition of that reference system. gml:VerticalCRS is a 1D coordinate reference system used for recording heights or depths. Vertical CRSs make use of the direction of gravity to define the concept of height or depth, but the relationship with gravity may not be straightforward. By implication, ellipsoidal heights (h) cannot be captured in a vertical coordinate reference system. Ellipsoidal heights cannot exist independently, but only as an inseparable part of a 3D coordinate tuple defined in a geographic 3D coordinate reference system. gml:verticalCS is an association role to the vertical coordinate system used by this CRS. deprecated gml:verticalDatum is an association role to the vertical datum used by this CRS. deprecated gml:VerticalCRSPropertyType is a property type for association roles to a vertical coordinate reference system, either referencing or containing the definition of that reference system. deprecated gml:ProjectedCRS is a 2D coordinate reference system used to approximate the shape of the earth on a planar surface, but in such a way that the distortion that is inherent to the approximation is carefully controlled and known. Distortion correction is commonly applied to calculated bearings and distances to produce values that are a close match to actual field values. gml:baseGeodeticCRS is an association role to the geodetic coordinate reference system used by this projected CRS. deprecated gml:ProjectedCRSPropertyType is a property type for association roles to a projected coordinate reference system, either referencing or containing the definition of that reference system. deprecated gml:DerivedCRS is a single coordinate reference system that is defined by its coordinate conversion from another single coordinate reference system known as the base CRS. The base CRS can be a projected coordinate reference system, if this DerivedCRS is used for a georectified grid coverage as described in ISO 19123, Clause 8. gml:baseCRS is an association role to the coordinate reference system used by this derived CRS. The gml:derivedCRSType property describes the type of a derived coordinate reference system. The required codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property. An association role to the coordinate system used by this CRS. deprecated gml:DerivedCRSPropertyType is a property type for association roles to a non-projected derived coordinate reference system, either referencing or containing the definition of that reference system. deprecated gml:EngineeringCRS is a contextually local coordinate reference system which can be divided into two broad categories: - earth-fixed systems applied to engineering activities on or near the surface of the earth; - CRSs on moving platforms such as road vehicles, vessels, aircraft, or spacecraft, see ISO 19111 8.3. gml:engineeringDatum is an association role to the engineering datum used by this CRS. deprecated gml:EngineeringCRSPropertyType is a property type for association roles to an engineering coordinate reference system, either referencing or containing the definition of that reference system. deprecated gml:ImageCRS is an engineering coordinate reference system applied to locations in images. Image coordinate reference systems are treated as a separate sub-type because the definition of the associated image datum contains two attributes not relevant to other engineering datums. gml:affineCS is an association role to the affine coordinate system used by this CRS. deprecated gml:imageDatum is an association role to the image datum used by this CRS. deprecated deprecated gml:ImageCRSPropertyType is a property type for association roles to an image coordinate reference system, either referencing or containing the definition of that reference system. deprecated gml:TemporalCRS is a 1D coordinate reference system used for the recording of time. gml:timeCS is an association role to the time coordinate system used by this CRS. deprecated deprecated gml:temporalDatum is an association role to the temporal datum used by this CRS. deprecated gml:TemporalCRSPropertyType is a property type for association roles to a temporal coordinate reference system, either referencing or containing the definition of that reference system. deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coordinateSystems.xsd ================================================ coordinateSystems.xsd See ISO/DIS 19136 13.4. The coordinate systems schema components can be divded into three logical parts, which define elements and types for XML encoding of the definitions of: - Coordinate system axes - Abstract coordinate system - Multiple concrete types of spatial-temporal coordinate systems These schema components encode the Coordinate System packages of the UML Models of ISO 19111 Clause 9 and ISO/DIS 19136 D.3.10. gml:CoordinateSystemAxis is a definition of a coordinate system axis. gml:axisAbbrev is the abbreviation used for this coordinate system axis; this abbreviation is also used to identify the coordinates in the coordinate tuple. The codeSpace attribute may reference a source of more information on a set of standardized abbreviations, or on this abbreviation. gml:axisDirection is the direction of this coordinate system axis (or in the case of Cartesian projected coordinates, the direction of this coordinate system axis at the origin). Within any set of coordinate system axes, only one of each pair of terms may be used. For earth-fixed CRSs, this direction is often approximate and intended to provide a human interpretable meaning to the axis. When a geodetic datum is used, the precise directions of the axes may therefore vary slightly from this approximate direction. The codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property. The gml:minimumValue and gml:maximumValue properties allow the specification of minimum and maximum value normally allowed for this axis, in the unit of measure for the axis. For a continuous angular axis such as longitude, the values wrap-around at this value. Also, values beyond this minimum/maximum can be used for specified purposes, such as in a bounding box. A value of minus infinity shall be allowed for the gml:minimumValue element, a value of plus infiniy for the gml:maximumValue element. If these elements are omitted, the value is unspecified. The gml:minimumValue and gml:maximumValue properties allow the specification of minimum and maximum value normally allowed for this axis, in the unit of measure for the axis. For a continuous angular axis such as longitude, the values wrap-around at this value. Also, values beyond this minimum/maximum can be used for specified purposes, such as in a bounding box. A value of minus infinity shall be allowed for the gml:minimumValue element, a value of plus infiniy for the gml:maximumValue element. If these elements are omitted, the value is unspecified. gml:rangeMeaning describes the meaning of axis value range specified by gml:minimumValue and gml:maximumValue. This element shall be omitted when both gml:minimumValue and gml:maximumValue are omitted. This element should be included when gml:minimumValue and/or gml:maximumValue are included. If this element is omitted when the gml:minimumValue and/or gml:maximumValue are included, the meaning is unspecified. The codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property. The uom attribute provides an identifier of the unit of measure used for this coordinate system axis. The value of this coordinate in a coordinate tuple shall be recorded using this unit of measure, whenever those coordinates use a coordinate reference system that uses a coordinate system that uses this axis. gml:CoordinateSystemAxisPropertyType is a property type for association roles to a coordinate system axis, either referencing or containing the definition of that axis. deprecated gml:AbstractCoordinateSystem is a coordinate system (CS) is the non-repeating sequence of coordinate system axes that spans a given coordinate space. A CS is derived from a set of mathematical rules for specifying how coordinates in a given space are to be assigned to points. The coordinate values in a coordinate tuple shall be recorded in the order in which the coordinate system axes associations are recorded. This abstract complex type shall not be used, extended, or restricted, in an Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. The gml:axis property is an association role (ordered sequence) to the coordinate system axes included in this coordinate system. The coordinate values in a coordinate tuple shall be recorded in the order in which the coordinate system axes associations are recorded, whenever those coordinates use a coordinate reference system that uses this coordinate system. The gml:AggregationAttributeGroup should be used to specify that the axis objects are ordered. deprecated gml:CoordinateSystemPropertyType is a property type for association roles to a coordinate system, either referencing or containing the definition of that coordinate system. deprecated gml:EllipsoidalCS is a two- or three-dimensional coordinate system in which position is specified by geodetic latitude, geodetic longitude, and (in the three-dimensional case) ellipsoidal height. An EllipsoidalCS shall have two or three gml:axis property elements; the number of associations shall equal the dimension of the CS. gml:EllipsoidalCSPropertyType is a property type for association roles to an ellipsoidal coordinate system, either referencing or containing the definition of that coordinate system. deprecated gml:CartesianCS is a 1-, 2-, or 3-dimensional coordinate system. In the 1-dimensional case, it contains a single straight coordinate axis. In the 2- and 3-dimensional cases gives the position of points relative to orthogonal straight axes. In the multi-dimensional case, all axes shall have the same length unit of measure. A CartesianCS shall have one, two, or three gml:axis property elements. gml:CartesianCSPropertyType is a property type for association roles to a Cartesian coordinate system, either referencing or containing the definition of that coordinate system. deprecated gml:VerticalCS is a one-dimensional coordinate system used to record the heights or depths of points. Such a coordinate system is usually dependent on the Earth's gravity field, perhaps loosely as when atmospheric pressure is the basis for the vertical coordinate system axis. A VerticalCS shall have one gml:axis property element. gml:VerticalCSPropertyType is a property type for association roles to a vertical coordinate system, either referencing or containing the definition of that coordinate system. deprecated gml:TimeCS is a one-dimensional coordinate system containing a time axis, used to describe the temporal position of a point in the specified time units from a specified time origin. A TimeCS shall have one gml:axis property element. gml:TimeCSPropertyType is a property type for association roles to a time coordinate system, either referencing or containing the definition of that coordinate system. deprecated deprecated deprecated deprecated gml:LinearCS is a one-dimensional coordinate system that consists of the points that lie on the single axis described. The associated coordinate is the distance – with or without offset – from the specified datum to the point along the axis. A LinearCS shall have one gml:axis property element. gml:LinearCSPropertyType is a property type for association roles to a linear coordinate system, either referencing or containing the definition of that coordinate system. deprecated gml:UserDefinedCS is a two- or three-dimensional coordinate system that consists of any combination of coordinate axes not covered by any other coordinate system type. A UserDefinedCS shall have two or three gml:axis property elements; the number of property elements shall equal the dimension of the CS. gml:UserDefinedCSPropertyType is a property type for association roles to a user-defined coordinate system, either referencing or containing the definition of that coordinate system. deprecated gml:SphericalCS is a three-dimensional coordinate system with one distance measured from the origin and two angular coordinates. A SphericalCS shall have three gml:axis property elements. gml:SphericalCSPropertyType is property type for association roles to a spherical coordinate system, either referencing or containing the definition of that coordinate system. deprecated gml:PolarCS ia s two-dimensional coordinate system in which position is specified by the distance from the origin and the angle between the line from the origin to a point and a reference direction. A PolarCS shall have two gml:axis property elements. gml:PolarCSPropertyType is a property type for association roles to a polar coordinate system, either referencing or containing the definition of that coordinate system. deprecated gml:CylindricalCS is a three-dimensional coordinate system consisting of a polar coordinate system extended by a straight coordinate axis perpendicular to the plane spanned by the polar coordinate system. A CylindricalCS shall have three gml:axis property elements. gml:CylindricalCSPropertyType is a property type for association roles to a cylindrical coordinate system, either referencing or containing the definition of that coordinate system. deprecated gml:AffineCS is a two- or three-dimensional coordinate system with straight axes that are not necessarily orthogonal. An AffineCS shall have two or three gml:axis property elements; the number of property elements shall equal the dimension of the CS. gml:AffineCSPropertyType is a property type for association roles to an affine coordinate system, either referencing or containing the definition of that coordinate system. deprecated deprecated deprecated deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coverage.xsd ================================================ coverage.xsd See ISO/DIS 19136 20.3. A coverage incorporates a mapping from a spatiotemporal domain to a range set, the latter providing the set in which the attribute values live. The range set may be an arbitrary set including discrete lists, integer or floating point ranges, and multi-dimensional vector spaces. A coverage can be viewed as the graph of the coverage function f:A à B, that is as the set of ordered pairs {(x, f(x)) | where x is in A}. This view is especially applicable to the GML encoding of a coverage. In the case of a discrete coverage, the domain set A is partitioned into a collection of subsets (typically a disjoint collection) A = UAi and the function f is constant on each Ai. For a spatial domain, the Ai are geometry elements, hence the coverage can be viewed as a collection of (geometry,value) pairs, where the value is an element of the range set. If the spatial domain A is a topological space then the coverage can be viewed as a collection of (topology,value) pairs, where the topology element in the pair is a topological n-chain (in GML terms this is a gml:TopoPoint, gml:TopoCurve, gml:TopoSurface or gml:TopoSolid). A coverage is implemented as a GML feature. We can thus speak of a “temperature distribution feature”, or a “remotely sensed image feature”, or a “soil distribution feature”. As is the case for any GML object, a coverage object may also be the value of a property of a feature. The base type for coverages is gml:AbstractCoverageType. The basic elements of a coverage can be seen in this content model: the coverage contains gml:domainSet and gml:rangeSet properties. The gml:domainSet property describes the domain of the coverage and the gml:rangeSet property describes the range of the coverage. This element serves as the head of a substitution group which may contain any coverage whose type is derived from gml:AbstractCoverageType. It may act as a variable in the definition of content models where it is required to permit any coverage to be valid. A discrete coverage consists of a domain set, range set and optionally a coverage function. The domain set consists of either spatial or temporal geometry objects, finite in number. The range set is comprised of a finite number of attribute values each of which is associated to every direct position within any single spatiotemporal object in the domain. In other words, the range values are constant on each spatiotemporal object in the domain. This coverage function maps each element from the coverage domain to an element in its range. The coverageFunction element describes the mapping function. This element serves as the head of a substitution group which may contain any discrete coverage whose type is derived from gml:AbstractDiscreteCoverageType. A continuous coverage as defined in ISO 19123 is a coverage that can return different values for the same feature attribute at different direct positions within a single spatiotemporal object in its spatiotemporal domain. The base type for continuous coverages is AbstractContinuousCoverageType. The coverageFunction element describes the mapping function. The abstract element gml:AbstractContinuousCoverage serves as the head of a substitution group which may contain any continuous coverage whose type is derived from gml:AbstractContinuousCoverageType. The gml:domainSet property element describes the spatio-temporal region of interest, within which the coverage is defined. Its content model is given by gml:DomainSetType. The value of the domain is thus a choice between a gml:AbstractGeometry and a gml:AbstractTimeObject. In the instance these abstract elements will normally be substituted by a geometry complex or temporal complex, to represent spatial coverages and time-series, respectively. The presence of the gml:AssociationAttributeGroup means that domainSet follows the usual GML property model and may use the xlink:href attribute to point to the domain, as an alternative to describing the domain inline. Ownership semantics may be provided using the gml:OwnershipAttributeGroup. The gml:rangeSet property element contains the values of the coverage (sometimes called the attribute values). Its content model is given by gml:RangeSetType. This content model supports a structural description of the range. The semantic information describing the range set is embedded using a uniform method, as part of the explicit values, or as a template value accompanying the representation using gml:DataBlock and gml:File. The values from each component (or “band”) in the range may be encoded within a gml:ValueArray element or a concrete member of the gml:AbstractScalarValueList substitution group . Use of these elements satisfies the value-type homogeneity requirement. gml:DataBlock describes the Range as a block of text encoded values similar to a Common Separated Value (CSV) representation. The range set parameterization is described by the property gml:rangeParameters. gml:RangeParameterType is a framework for the description of the range parameters each of which is a gml:AbstractValue. Specific range parameters are defined through the creation of a GML Application Schema that provides elements that are substitutable for gml:AbstractValue. gml:CoordinatesType consists of a list of coordinate tuples, with each coordinate tuple separated by the ts or tuple separator (whitespace), and each coordinate in the tuple by the cs or coordinate separator (comma). The gml:tupleList encoding is effectively “band-interleaved”. gml:doubleOrNilReasonList consists of a list of gml:doubleOrNilReason values, each separated by a whitespace. The gml:doubleOrNilReason values are grouped into tuples where the dimension of each tuple in the list is equal to the number of range parameters. for efficiency reasons, GML also provides a means of encoding the range set in an arbitrary external encoding, such as a binary file. This encoding may be “well-known” but this is not required. This mode uses the gml:File element. The values of the coverage (attribute values in the range set) are transmitted in a external file that is referenced from the XML structure described by gml:FileType. The external file is referenced by the gml:fileReference property that is an anyURI (the gml:fileName property has been deprecated). This means that the external file may be located remotely from the referencing GML instance. The gml:compression property points to a definition of a compression algorithm through an anyURI. This may be a retrievable, computable definition or simply a reference to an unambiguous name for the compression method. The gml:mimeType property points to a definition of the file mime type. The gml:fileStructure property is defined by the gml:FileValueModelType. This is simple enumerated type restriction on string. The only value supported in GML is “Record Interleaved”. Additional values may be supported in future releases of GML. Note further that all values shall be enclosed in a single file. Multi-file structures for values are not supported in GML. The semantics of the range set is described as above using the gml:rangeParameters property. Note that if any compression algorithm is applied, the structure above applies only to the pre-compression or post-decompression structure of the file. Note that the fields within a record match the gml:valueComponents of the gml:CompositeValue in document order. The gml:coverageFunction property describes the mapping function from the domain to the range of the coverage. The value of the CoverageFunction is one of gml:CoverageMappingRule and gml:GridFunction. If the gml:coverageFunction property is omitted for a gridded coverage (including rectified gridded coverages) the gml:startPoint is assumed to be the value of the gml:low property in the gml:Grid geometry, and the gml:sequenceRule is assumed to be linear and the gml:axisOrder property is assumed to be “+1 +2”. gml:CoverageMappingRule provides a formal or informal description of the coverage function. The mapping rule may be defined as an in-line string (gml:ruleDefinition) or via a remote reference through xlink:href (gml:ruleReference). If no rule name is specified, the default is ‘Linear’ with respect to members of the domain in document order. deprecated gml:GridFunction provides an explicit mapping rule for grid geometries, i.e. the domain shall be a geometry of type grid. It describes the mapping of grid posts (discrete point grid coverage) or grid cells (discrete surface coverage) to the values in the range set. The gml:startPoint is the index position of a point in the grid that is mapped to the first point in the range set (this is also the index position of the first grid post). If the gml:startPoint property is omitted the gml:startPoint is assumed to be equal to the value of gml:low in the gml:Grid geometry. Subsequent points in the mapping are determined by the value of the gml:sequenceRule. The gml:SequenceRuleType is derived from the gml:SequenceRuleEnumeration through the addition of an axisOrder attribute. The gml:SequenceRuleEnumeration is an enumerated type. The rule names are defined in ISO 19123. If no rule name is specified the default is “Linear”. deprecated The different values in a gml:AxisDirectionList indicate the incrementation order to be used on all axes of the grid. Each axis shall be mentioned once and only once. The value of a gml:AxisDirection indicates the incrementation order to be used on an axis of the grid. deprecated In a gml:MultiPointCoverage the domain set is a gml:MultiPoint, that is a collection of arbitrarily distributed geometric points. The content model is derived by restriction from gml:AbstractDiscreteCoverageType. Note that the restriction replaces the generic gml:domainSet by the specific gml:multiPointDomain whose value is a gml:MultiPoint. In a gml:MultiPointCoverage the mapping from the domain to the range is straightforward. - For gml:DataBlock encodings the points of the gml:MultiPoint are mapped in document order to the tuples of the data block. - For gml:CompositeValue encodings the points of the gml:MultiPoint are mapped to the members of the composite value in document order. - For gml:File encodings the points of the gml:MultiPoint are mapped to the records of the file in sequential order. In a gml:MultiCurveCoverage the domain is partioned into a collection of curves comprising a gml:MultiCurve. The coverage function then maps each curve in the collection to a value in the range set. The content model is derived by restriction from gml:AbstractDiscreteCoverageType. Note that the restriction replaces the generic gml:domainSet by the specific gml:multiCurveDomain whose value is a gml:MultiCurve. In a gml:MultiCurveCoverage the mapping from the domain to the range is straightforward. - For gml:DataBlock encodings the curves of the gml:MultiCurve are mapped in document order to the tuples of the data block. - For gml:CompositeValue encodings the curves of the gml:MultiCurve are mapped to the members of the composite value in document order. - For gml:File encodings the curves of the gml:MultiCurve are mapped to the records of the file in sequential order. In a gml:MultiSurfaceCoverage the domain is partioned into a collection of surfaces comprising a gml:MultiSurface. The coverage function than maps each surface in the collection to a value in the range set. The content model is derived by restriction from gml:AbstractDiscreteCoverageType. Note that the restriction replaces the generic gml:domainSet by the specific gml:multiSurfaceDomain whose value is a gml:MultiSurface. In a gml:MultiSurfaceCoverage the mapping from the domain to the range is straightforward. - For gml:DataBlock encodings the surfaces of the gml:MultiSurface are mapped in document order to the tuples of the data block. - For gml:CompositeValue encodings the surfaces of the gml:MultiSurface are mapped to the members of the composite value in document order. - For gml:File encodings the surfaces of the gml:MultiSurface are mapped to the records of the file in sequential order. In a gml:MultiSolidCoverage the domain is partioned into a collection of solids comprising a gml:MultiSolid. The coverage function than maps each solid in the collection to a value in the range set. The content model is derived by restriction from gml:AbstractDiscreteCoverageType. Note that the restriction replaces the generic gml:domainSet by the specific gml:multiSolidDomain whose value is a gml:MultiSolid. In a gml:MultiSolidCoverage the mapping from the domain to the range is straightforward. - For gml:DataBlock encodings the solids of the gml:MultiSolid are mapped in document order to the tuples of the data block. - For gml:CompositeValue encodings the solids of the gml:MultiSolid are mapped to the members of the composite value in document order. - For gml:File encodings the solids of the gml:MultiSolid are mapped to the records of the file in sequential order. A gml:GriddedCoverage is a discrete point coverage in which the domain set is a geometric grid of points. Note that this is the same as the gml:MultiPointCoverage except that we have a gml:gridDomain property to describe the domain. The simple gridded coverage is not geometrically referenced and hence no geometric positions are assignable to the points in the grid. Such geometric positioning is introduced in the gml:RectifiedGridCoverage. The gml:RectifiedGridCoverage is a discrete point coverage based on a rectified grid. It is similar to the grid coverage except that the points of the grid are geometrically referenced. The rectified grid coverage has a domain that is a gml:RectifiedGrid geometry. The coverage domain is described by gml:rectifiedGridDomain. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/datums.xsd ================================================ datums.xsd See ISO/DIS 19136 13.5 The datums schema components can be divided into three logical parts, which define elements and types for XML encoding of the definitions of: - Abstract datum - Geodetic datums, including ellipsoid and prime meridian - Multiple other concrete types of spatial or temporal datums These schema components encode the Datum packages of the UML Models of ISO 19111 Clause 10 and ISO/DIS 19136 D.3.10. A gml:AbstractDatum specifies the relationship of a coordinate system to the earth, thus creating a coordinate reference system. A datum uses a parameter or set of parameters that determine the location of the origin of the coordinate reference system. Each datum subtype may be associated with only specific types of coordinate systems. This abstract complex type shall not be used, extended, or restricted, in a GML Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. gml:anchorDefinition is a description, possibly including coordinates, of the definition used to anchor the datum to the Earth. Also known as the "origin", especially for engineering and image datums. The codeSpace attribute may be used to reference a source of more detailed on this point or surface, or on a set of such descriptions. - For a geodetic datum, this point is also known as the fundamental point, which is traditionally the point where the relationship between geoid and ellipsoid is defined. In some cases, the "fundamental point" may consist of a number of points. In those cases, the parameters defining the geoid/ellipsoid relationship have been averaged for these points, and the averages adopted as the datum definition. - For an engineering datum, the anchor definition may be a physical point, or it may be a point with defined coordinates in another CRS.may - For an image datum, the anchor definition is usually either the centre of the image or the corner of the image. - For a temporal datum, this attribute is not defined. Instead of the anchor definition, a temporal datum carries a separate time origin of type DateTime. deprecated gml:realizationEpoch is the time after which this datum definition is valid. See ISO 19111 Table 32 for details. gml:DatumPropertyType is a property type for association roles to a datum, either referencing or containing the definition of that datum. deprecated gml:GeodeticDatum is a geodetic datum defines the precise location and orientation in 3-dimensional space of a defined ellipsoid (or sphere), or of a Cartesian coordinate system centered in this ellipsoid (or sphere). gml:primeMeridian is an association role to the prime meridian used by this geodetic datum. deprecated gml:ellipsoid is an association role to the ellipsoid used by this geodetic datum. deprecated gml:GeodeticDatumPropertyType is a property type for association roles to a geodetic datum, either referencing or containing the definition of that datum. deprecated A gml:Ellipsoid is a geometric figure that may be used to describe the approximate shape of the earth. In mathematical terms, it is a surface formed by the rotation of an ellipse about its minor axis. gml:semiMajorAxis specifies the length of the semi-major axis of the ellipsoid, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a length, such as metres or feet. gml:secondDefiningParameter is a property containing the definition of the second parameter that defines the shape of an ellipsoid. An ellipsoid requires two defining parameters: semi-major axis and inverse flattening or semi-major axis and semi-minor axis. When the reference body is a sphere rather than an ellipsoid, only a single defining parameter is required, namely the radius of the sphere; in that case, the semi-major axis "degenerates" into the radius of the sphere. The inverseFlattening element contains the inverse flattening value of the ellipsoid. This value is a scale factor (or ratio). It uses gml:LengthType with the restriction that the unit of measure referenced by the uom attribute must be suitable for a scale factor, such as percent, permil, or parts-per-million. The semiMinorAxis element contains the length of the semi-minor axis of the ellipsoid. When the isSphere element is included, the ellipsoid is degenerate and is actually a sphere. The sphere is completely defined by the semi-major axis, which is the radius of the sphere. gml:EllipsoidPropertyType is a property type for association roles to an ellipsoid, either referencing or containing the definition of that ellipsoid. deprecated A gml:PrimeMeridian defines the origin from which longitude values are determined. The default value for the prime meridian gml:identifier value is "Greenwich". gml:greenwichLongitude is the longitude of the prime meridian measured from the Greenwich meridian, positive eastward. If the value of the prime meridian “name” is "Greenwich" then the value of greenwichLongitude shall be 0 degrees. gml:PrimeMeridianPropertyType is a property type for association roles to a prime meridian, either referencing or containing the definition of that meridian. deprecated gml:EngineeringDatum defines the origin of an engineering coordinate reference system, and is used in a region around that origin. This origin may be fixed with respect to the earth (such as a defined point at a construction site), or be a defined point on a moving vehicle (such as on a ship or satellite). gml:EngineeringDatumPropertyType is a property type for association roles to an engineering datum, either referencing or containing the definition of that datum. deprecated gml:ImageDatum defines the origin of an image coordinate reference system, and is used in a local context only. For an image datum, the anchor definition is usually either the centre of the image or the corner of the image. For more information, see ISO 19111 B.3.5. gml:pixelInCell is a specification of the way an image grid is associated with the image data attributes. The required codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property. gml:ImageDatumPropertyType is a property type for association roles to an image datum, either referencing or containing the definition of that datum. deprecated gml:VerticalDatum is a textual description and/or a set of parameters identifying a particular reference level surface used as a zero-height surface, including its position with respect to the Earth for any of the height types recognized by this International Standard. gml:VerticalDatumPropertyType is property type for association roles to a vertical datum, either referencing or containing the definition of that datum. deprecated A gml:TemporalDatum defines the origin of a Temporal Reference System. This type omits the "anchorDefinition" and "realizationEpoch" elements and adds the "origin" element with the dateTime type. The TemporalDatumBaseType partially defines the origin of a temporal coordinate reference system. This type restricts the AbstractDatumType to remove the "anchorDefinition" and "realizationEpoch" elements. gml:origin is the date and time origin of this temporal datum. gml:TemporalDatumPropertyType is a property type for association roles to a temporal datum, either referencing or containing the definition of that datum. deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/dictionary.xsd ================================================ dictionary.xsd See ISO/DIS 19136 Clause 16. Many applications require definitions of terms which are used within instance documents as the values of certain properties or as reference information to tie properties to standard information values in some way. Units of measure and descriptions of measurable phenomena are two particular examples. It will often be convenient to use definitions provided by external authorities. These may already be packaged for delivery in various ways, both online and offline. In order that they may be referred to from GML documents it is generally necessary that a URI be available for each definition. Where this is the case then it is usually preferable to refer to these directly. Alternatively, it may be convenient or necessary to capture definitions in XML, either embedded within an instance document containing features or as a separate document. The definitions may be transcriptions from an external source, or may be new definitions for a local purpose. In order to support this case, some simple components are provided in GML in the form of - a generic gml:Definition, which may serve as the basis for more specialized definitions - a generic gml:Dictionary, which allows a set of definitions or references to definitions to be collected These components may be used directly, but also serve as the basis for more specialised definition elements in GML, in particular: coordinate operations, coordinate reference systems, datums, temporal reference systems, and units of measure. Note that the GML definition and dictionary components implement a simple nested hierarchy of definitions with identifiers. The latter provide handles which may be used in the description of more complex relationships between terms. However, the GML dictionary components are not intended to provide direct support for complex taxonomies, ontologies or thesauri. Specialised XML tools are available to satisfy the more sophisticated requirements. The basic gml:Definition element specifies a definition, which can be included in or referenced by a dictionary. The content model for a generic definition is a derivation from gml:AbstractGMLType. The gml:description property element shall hold the definition if this can be captured in a simple text string, or the gml:descriptionReference property element may carry a link to a description elsewhere. The gml:identifier element shall provide one identifier identifying this definition. The identifier shall be unique within the dictionaries using this definition. The gml:name elements shall provide zero or more terms and synonyms for which this is the definition. The gml:remarks element shall be used to hold additional textual information that is not conceptually part of the definition but is useful in understanding the definition. Sets of definitions may be collected into dictionaries or collections. A gml:Dictionary is a non-abstract collection of definitions. The gml:Dictionary content model adds a list of gml:dictionaryEntry properties that contain or reference gml:Definition objects. A database handle (gml:id attribute) is required, in order that this collection may be referred to. The standard gml:identifier, gml:description, gml:descriptionReference and gml:name properties are available to reference or contain more information about this dictionary. The gml:description and gml:descriptionReference property elements may be used for a description of this dictionary. The derived gml:name element may be used for the name(s) of this dictionary. for remote definiton references gml:dictionaryEntry shall be used. If a Definition object contained within a Dictionary uses the descriptionReference property to refer to a remote definition, then this enables the inclusion of a remote definition in a local dictionary, giving a handle and identifier in the context of the local dictionary. deprecated This property element contains or refers to the definitions which are members of a dictionary. The content model follows the standard GML property pattern, so a gml:dictionaryEntry may either contain or refer to a single gml:Definition. Since gml:Dictionary is substitutable for gml:Definition, the content of an entry may itself be a lower level dictionary. Note that if the value is provided by reference, this definition does not carry a handle (gml:id) in this context, so does not allow external references to this specific definition in this context. When used in this way the referenced definition will usually be in a dictionary in the same XML document. deprecated deprecated deprecated deprecated deprecated deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/direction.xsd ================================================ direction.xsd See ISO/DIS 19136 Clause 18. The direction schema components provide the GML Application Schema developer with a standard property element to describe direction, and associated objects that may be used to express orientation, direction, heading, bearing or other directional aspects of geographic features. The property gml:direction is intended as a pre-defined property expressing a direction to be assigned to features defined in a GML application schema. Direction vectors are specified by providing components of a vector. deprecated direction descriptions are specified by a compass point code, a keyword, a textual description or a reference to a description. A gml:compassPoint is specified by a simple enumeration. In addition, thre elements to contain text-based descriptions of direction are provided. If the direction is specified using a term from a list, gml:keyword should be used, and the list indicated using the value of the codeSpace attribute. if the direction is decribed in prose, gml:direction or gml:reference should be used, allowing the value to be included inline or by reference. These directions are necessarily approximate, giving direction with a precision of 22.5°. It is thus generally unnecessary to specify the reference frame, though this may be detailed in the definition of a GML application language. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/dynamicFeature.xsd ================================================ dynamicFeature.xsd See ISO/DIS 19136 15.6. A number of types and relationships are defined to represent the time-varying properties of geographic features. In a comprehensive treatment of spatiotemporal modeling, Langran (see Bibliography) distinguished three principal temporal entities: states, events, and evidence; the schema specified in the following Subclauses incorporates elements for each. Evidence is represented by a simple gml:dataSource or gml:dataSourceReference property that indicates the source of the temporal data. The remote link attributes of the gml:dataSource element have been deprecated along with its current type. Evidence is represented by a simple gml:dataSource or gml:dataSourceReference property that indicates the source of the temporal data. A convenience group. This allows an application schema developer to include dynamic properties in a content model in a standard fashion. States are captured by time-stamped instances of a feature. The content model extends the standard gml:AbstractFeatureType with the gml:dynamicProperties model group. Each time-stamped instance represents a ‘snapshot’ of a feature. The dynamic feature classes will normally be extended to suit particular applications. A dynamic feature bears either a time stamp or a history. A gml:DynamicFeatureCollection is a feature collection that has a gml:validTime property (i.e. is a snapshot of the feature collection) or which has a gml:history property that contains one or more gml:AbstractTimeSlices each of which contain values of the time varying properties of the feature collection. Note that the gml:DynamicFeatureCollection may be one of the following: 1. A feature collection which consists of static feature members (members do not change in time) but which has properties of the collection object as a whole that do change in time . 2. A feature collection which consists of dynamic feature members (the members are gml:DynamicFeatures) but which also has properties of the collection as a whole that vary in time. To describe an event — an action that occurs at an instant or over an interval of time — GML provides the gml:AbtractTimeSlice element. A timeslice encapsulates the time-varying properties of a dynamic feature -- it shall be extended to represent a time stamped projection of a specific feature. The gml:dataSource property describes how the temporal data was acquired. A gml:AbstractTimeSlice instance is a GML object that encapsulates updates of the dynamic—or volatile—properties that reflect some change event; it thus includes only those feature properties that have actually changed due to some process. gml:AbstractTimeSlice basically provides a facility for attribute-level time stamping, in contrast to the object-level time stamping of dynamic feature instances. The time slice can thus be viewed as event or process-oriented, whereas a snapshot is more state or structure-oriented. A timeslice has richer causality, whereas a snapshot merely portrays the status of the whole. gml:MovingObjectStatus is one example of how gml:AbstractTimeSlice may be extended. This element provides a standard method to capture a record of the status of a moving object. A gml:MovingObjectStatus element allows the user to describe the present location, along with the speed, bearing, acceleration and elevation of an object in a particular time slice. Additional information about the current status of the object may be recorded in the gml:status or gml:statusReference property elements. The remote link attributes of the gml:status element have been deprecated along with its current type. A generic sequence of events constitute a gml:history of an object. The gml:history element contains a set of elements in the substitution group headed by the abstract element gml:AbstractTimeSlice, representing the time-varying properties of interest. The history property of a dynamic feature associates a feature instance with a sequence of time slices (i.e. change events) that encapsulate the evolution of the feature. deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/feature.xsd ================================================ feature.xsd See ISO/DIS 19136 Clause 9. A GML feature is a (representation of a) identifiable real-world object in a selected domain of discourse. The feature schema provides a framework for the creation of GML features and feature collections. The basic feature model is given by the gml:AbstractFeatureType. The content model for gml:AbstractFeatureType adds two specific properties suitable for geographic features to the content model defined in gml:AbstractGMLType. The value of the gml:boundedBy property describes an envelope that encloses the entire feature instance, and is primarily useful for supporting rapid searching for features that occur in a particular location. The value of the gml:location property describes the extent, position or relative location of the feature. This abstract element serves as the head of a substitution group which may contain any elements whose content model is derived from gml:AbstractFeatureType. This may be used as a variable in the construction of content models. gml:AbstractFeature may be thought of as “anything that is a GML feature” and may be used to define variables or templates in which the value of a GML property is “any feature”. This occurs in particular in a GML feature collection where the feature member properties contain one or multiple copies of gml:AbstractFeature respectively. This property describes the minimum bounding box or rectangle that encloses the entire feature. gml:EnvelopeWithTimePeriod is provided for envelopes that include a temporal extent. It adds two time position properties, gml:beginPosition and gml:endPosition, which describe the extent of a time-envelope. Since gml:EnvelopeWithTimePeriod is assigned to the substitution group headed by gml:Envelope, it may be used whenever gml:Envelope is valid. deprecated deprecated deprecated deprecated The gml:locationName property element is a convenience property where the text value describes the location of the feature. If the location names are selected from a controlled list, then the list shall be identified in the codeSpace attribute. The gml:locationReference property element is a convenience property where the text value referenced by the xlink:href attribute describes the location of the feature. deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated To create a collection of GML features, a property type shall be derived by extension from gml:AbstractFeatureMemberType. By default, this abstract property type does not imply any ownership of the features in the collection. The owns attribute of gml:OwnershipAttributeGroup may be used on a property element instance to assert ownership of a feature in the collection. A collection shall not own a feature already owned by another object. deprecated deprecated deprecated deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryAggregates.xsd ================================================ geometryAggregates.xsd See ISO/DIS 19136 12.3. Geometric aggregates (i.e. instances of a subtype of gml:AbstractGeometricAggregateType) are arbitrary aggregations of geometry elements. They are not assumed to have any additional internal structure and are used to "collect" pieces of geometry of a specified type. Application schemas may use aggregates for features that use multiple geometric objects in their representations. gml:AbstractGeometricAggregate is the abstract head of the substitution group for all geometric aggregates. gml:MultiGeometry is a collection of one or more GML geometry objects of arbitrary type. The members of the geometric aggregate may be specified either using the "standard" property (gml:geometryMember) or the array property (gml:geometryMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element either references a geometry element via the XLink-attributes or contains the geometry element. This property element contains a list of geometry elements. The order of the elements is significant and shall be preserved when processing the array. A property that has a geometric aggregate as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a geometric aggregate via the XLink-attributes or contains the "multi geometry" element. multiGeometryProperty is the predefined property, which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractGeometricAggregate. A gml:MultiPoint consists of one or more gml:Points. The members of the geometric aggregate may be specified either using the "standard" property (gml:pointMember) or the array property (gml:pointMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element either references a Point via the XLink-attributes or contains the Point element. This property element contains a list of points. The order of the elements is significant and shall be preserved when processing the array. A property that has a collection of points as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a point aggregate via the XLink-attributes or contains the "multi point" element. multiPointProperty is the predefined property, which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for MultiPoint. A gml:MultiCurve is defined by one or more gml:AbstractCurves. The members of the geometric aggregate may be specified either using the "standard" property (gml:curveMember) or the array property (gml:curveMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element contains a list of curves. The order of the elements is significant and shall be preserved when processing the array. A property that has a collection of curves as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a curve aggregate via the XLink-attributes or contains the "multi curve" element. multiCurveProperty is the predefined property, which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for MultiCurve. A gml:MultiSurface is defined by one or more gml:AbstractSurfaces. The members of the geometric aggregate may be specified either using the "standard" property (gml:surfaceMember) or the array property (gml:surfaceMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element contains a list of surfaces. The order of the elements is significant and shall be preserved when processing the array. A property that has a collection of surfaces as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a surface aggregate via the XLink-attributes or contains the "multi surface" element. multiSurfaceProperty is the predefined property, which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for MultiSurface. A gml:MultiSolid is defined by one or more gml:AbstractSolids. The members of the geometric aggregate may be specified either using the "standard" property (gml:solidMember) or the array property (gml:solidMembers). It is also valid to use both the "standard" and the array properties in the same collection. This property element either references a solid via the XLink-attributes or contains the solid element. A solid element is any element, which is substitutable for gml:AbstractSolid. This property element contains a list of solids. The order of the elements is significant and shall be preserved when processing the array. A property that has a collection of solids as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a solid aggregate via the XLink-attributes or contains the "multi solid" element. multiSolidProperty is the predefined property, which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for MultiSolid. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryBasic0d1d.xsd ================================================ geometryBasic0d1d.xsd See ISO/DIS 19136 Clause 10. Any geometry element that inherits the semantics of AbstractGeometryType may be viewed as a set of direct positions. All of the classes derived from AbstractGeometryType inherit an optional association to a coordinate reference system. All direct positions shall directly or indirectly be associated with a coordinate reference system. When geometry elements are aggregated in another geometry element (such as a MultiGeometry or GeometricComplex), which already has a coordinate reference system specified, then these elements are assumed to be in that same coordinate reference system unless otherwise specified. The geometry model distinguishes geometric primitives, aggregates and complexes. Geometric primitives, i.e. instances of a subtype of AbstractGeometricPrimitiveType, will be open, that is, they will not contain their boundary points; curves will not contain their end points, surfaces will not contain their boundary curves, and solids will not contain their bounding surfaces. All geometry elements are derived directly or indirectly from this abstract supertype. A geometry element may have an identifying attribute (gml:id), one or more names (elements identifier and name) and a description (elements description and descriptionReference) . It may be associated with a spatial reference system (attribute group gml:SRSReferenceGroup). The following rules shall be adhered to: - Every geometry type shall derive from this abstract type. - Every geometry element (i.e. an element of a geometry type) shall be directly or indirectly in the substitution group of AbstractGeometry. The attribute group SRSReferenceGroup is an optional reference to the CRS used by this geometry, with optional additional information to simplify the processing of the coordinates when a more complete definition of the CRS is not needed. In general the attribute srsName points to a CRS instance of gml:AbstractCoordinateReferenceSystem. For well-known references it is not required that the CRS description exists at the location the URI points to. If no srsName attribute is given, the CRS shall be specified as part of the larger context this geometry element is part of. The attributes uomLabels and axisLabels, defined in the SRSInformationGroup attribute group, are optional additional and redundant information for a CRS to simplify the processing of the coordinate values when a more complete definition of the CRS is not needed. This information shall be the same as included in the complete definition of the CRS, referenced by the srsName attribute. When the srsName attribute is included, either both or neither of the axisLabels and uomLabels attributes shall be included. When the srsName attribute is omitted, both of these attributes shall be omitted. The attribute axisLabels is an ordered list of labels for all the axes of this CRS. The gml:axisAbbrev value should be used for these axis labels, after spaces and forbidden characters are removed. When the srsName attribute is included, this attribute is optional. When the srsName attribute is omitted, this attribute shall also be omitted. The attribute uomLabels is an ordered list of unit of measure (uom) labels for all the axes of this CRS. The value of the string in the gml:catalogSymbol should be used for this uom labels, after spaces and forbidden characters are removed. When the axisLabels attribute is included, this attribute shall also be included. When the axisLabels attribute is omitted, this attribute shall also be omitted. The AbstractGeometry element is the abstract head of the substitution group for all geometry elements of GML. This includes pre-defined and user-defined geometry elements. Any geometry element shall be a direct or indirect extension/restriction of AbstractGeometryType and shall be directly or indirectly in the substitution group of AbstractGeometry. A geometric property may either be any geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same or another document). Note that either the reference or the contained element shall be given, but not both or none. If a feature has a property that takes a geometry element as its value, this is called a geometry property. A generic type for such a geometry property is GeometryPropertyType. If a feature has a property which takes an array of geometry elements as its value, this is called a geometry array property. A generic type for such a geometry property is GeometryArrayPropertyType. The elements are always contained inline in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported. Direct position instances hold the coordinates for a position within some coordinate reference system (CRS). Since direct positions, as data types, will often be included in larger objects (such as geometry elements) that have references to CRS, the srsName attribute will in general be missing, if this particular direct position is included in a larger element with such a reference to a CRS. In this case, the CRS is implicitly assumed to take on the value of the containing object's CRS. if no srsName attribute is given, the CRS shall be specified as part of the larger context this geometry element is part of, typically a geometric object like a point, curve, etc. The presence of a dimension attribute implies the presence of the srsName attribute. The presence of an axisLabels attribute implies the presence of the srsName attribute. The presence of an uomLabels attribute implies the presence of the srsName attribute. The presence of an uomLabels attribute implies the presence of the axisLabels attribute and vice versa. posList instances (and other instances with the content model specified by DirectPositionListType) hold the coordinates for a sequence of direct positions within the same coordinate reference system (CRS). if no srsName attribute is given, the CRS shall be specified as part of the larger context this geometry element is part of, typically a geometric object like a point, curve, etc. The optional attribute count specifies the number of direct positions in the list. If the attribute count is present then the attribute srsDimension shall be present, too. The number of entries in the list is equal to the product of the dimensionality of the coordinate reference system (i.e. it is a derived value of the coordinate reference system definition) and the number of direct positions. GML supports two different ways to specify a geometric position: either by a direct position (a data type) or a point (a geometric object). pos elements are positions that are “owned” by the geometric primitive encapsulating this geometric position. pointProperty elements contain a point that may be referenced from other geometry elements or reference another point defined elsewhere (reuse of existing points). GML supports two different ways to specify a list of geometric positions: either by a sequence of geometric positions (by reusing the group definition) or a sequence of direct positions (element posList). The posList element allows for a compact way to specify the coordinates of the positions, if all positions are represented in the same coordinate reference system. deprecated For some applications the components of the position may be adjusted to yield a unit vector. deprecated Envelope defines an extent using a pair of positions defining opposite corners in arbitrary dimensions. The first direct position is the "lower corner" (a coordinate position consisting of all the minimal ordinates for each dimension for all points within the envelope), the second one the "upper corner" (a coordinate position consisting of all the maximal ordinates for each dimension for all points within the envelope). The use of the properties “coordinates” and “pos” has been deprecated. The explicitly named properties “lowerCorner” and “upperCorner” shall be used instead. gml:AbstractGeometricPrimitiveType is the abstract root type of the geometric primitives. A geometric primitive is a geometric object that is not decomposed further into other primitives in the system. All primitives are oriented in the direction implied by the sequence of their coordinate tuples. The AbstractGeometricPrimitive element is the abstract head of the substitution group for all (pre- and user-defined) geometric primitives. A property that has a geometric primitive as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. A Point is defined by a single coordinate tuple. The direct position of a point is specified by the pos element which is of type DirectPositionType. A property that has a point as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a point via the XLink-attributes or contains the point element. pointProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for Point. deprecated gml:PointArrayPropertyType is a container for an array of points. The elements are always contained inline in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported. This property element contains a list of point elements. pointArrayProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for a list of points. gml:AbstractCurveType is an abstraction of a curve to support the different levels of complexity. The curve may always be viewed as a geometric primitive, i.e. is continuous. The AbstractCurve element is the abstract head of the substitution group for all (continuous) curve elements. A property that has a curve as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a curve via the XLink-attributes or contains the curve element. curveProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractCurve. A container for an array of curves. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported. This property element contains a list of curve elements. curveArrayProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for a list of curves. A LineString is a special curve that consists of a single segment with linear interpolation. It is defined by two or more coordinate tuples, with linear interpolation between them. The number of direct positions in the list shall be at least two. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryBasic2d.xsd ================================================ geometryBasic2d.xsd See ISO/DIS 19136 Clause 10. gml:AbstractSurfaceType is an abstraction of a surface to support the different levels of complexity. A surface is always a continuous region of a plane. The AbstractSurface element is the abstract head of the substitution group for all (continuous) surface elements. A property that has a surface as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a surface via the XLink-attributes or contains the surface element. surfaceProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractSurface. gml:SurfaceArrayPropertyType is a container for an array of surfaces. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported. This property element contains a list of surface elements. surfaceArrayProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for a list of AbstractSurfaces. A Polygon is a special surface that is defined by a single surface patch (see D.3.6). The boundary of this patch is coplanar and the polygon uses planar interpolation in its interior. The elements exterior and interior describe the surface boundary of the polygon. A boundary of a surface consists of a number of rings. In the normal 2D case, one of these rings is distinguished as being the exterior boundary. In a general manifold this is not always possible, in which case all boundaries shall be listed as interior boundaries, and the exterior will be empty. A boundary of a surface consists of a number of rings. The "interior" rings separate the surface / surface patch from the area enclosed by the rings. An abstraction of a ring to support surface boundaries of different complexity. The AbstractRing element is the abstract head of the substituition group for all closed boundaries of a surface patch. A property with the content model of gml:AbstractRingPropertyType encapsulates a ring to represent the surface boundary property of a surface. A LinearRing is defined by four or more coordinate tuples, with linear interpolation between them; the first and last coordinates shall be coincident. The number of direct positions in the list shall be at least four. A property with the content model of gml:LinearRingPropertyType encapsulates a linear ring to represent a component of a surface boundary. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryComplexes.xsd ================================================ geometryComplexes.xsd See ISO/DIS 19136 12.2. Geometric complexes (i.e. instances of gml:GeometricComplexType) are closed collections of geometric primitives, i.e. they will contain their boundaries. A geometric complex (gml:GeometricComplex) is defined by ISO 19107:2003, 6.6.1 as “a set of primitive geometric objects (in a common coordinate system) whose interiors are disjoint. Further, if a primitive is in a geometric complex, then there exists a set of primitives in that complex whose point-wise union is the boundary of this first primitive.” A geometric composite (gml:CompositeCurve, gml:CompositeSurface and gml:CompositeSolid) represents a geometric complex with an underlying core geometry that is isomorphic to a primitive, i.e. it can be viewed as a primitive and as a complex. See ISO 19107:2003, 6.1 and 6.6.3 for more details on the nature of composite geometries. Geometric complexes and composites are intended to be used in application schemas where the sharing of geometry is important. A property that has a geometric complex as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. A gml:CompositeCurve is represented by a sequence of (orientable) curves such that each curve in the sequence terminates at the start point of the subsequent curve in the list. curveMember references or contains inline one curve in the composite curve. The curves are contiguous, the collection of curves is ordered. Therefore, if provided, the aggregationType attribute shall have the value “sequence”. A gml:CompositeSurface is represented by a set of orientable surfaces. It is geometry type with all the geometric properties of a (primitive) surface. Essentially, a composite surface is a collection of surfaces that join in pairs on common boundary curves and which, when considered as a whole, form a single surface. surfaceMember references or contains inline one surface in the composite surface. The surfaces are contiguous. gml:CompositeSolid implements ISO 19107 GM_CompositeSolid (see ISO 19107:2003, 6.6.7) as specified in D.2.3.6. A gml:CompositeSolid is represented by a set of orientable surfaces. It is a geometry type with all the geometric properties of a (primitive) solid. Essentially, a composite solid is a collection of solids that join in pairs on common boundary surfaces and which, when considered as a whole, form a single solid. solidMember references or contains one solid in the composite solid. The solids are contiguous. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryPrimitives.xsd ================================================ geometryPrimitives.xsd See ISO/DIS 19136 Clause 11. Beside the “simple” geometric primitives specified in the previous Clause, this Clause specifies additional primitives to describe real world situations which require a more expressive geometry model. A curve is a 1-dimensional primitive. Curves are continuous, connected, and have a measurable length in terms of the coordinate system. A curve is composed of one or more curve segments. Each curve segment within a curve may be defined using a different interpolation method. The curve segments are connected to one another, with the end point of each segment except the last being the start point of the next segment in the segment list. The orientation of the curve is positive. The element segments encapsulates the segments of the curve. The property baseCurve references or contains the base curve, i.e. it either references the base curve via the XLink-attributes or contains the curve element. A curve element is any element which is substitutable for AbstractCurve. The base curve has positive orientation. OrientableCurve consists of a curve and an orientation. If the orientation is "+", then the OrientableCurve is identical to the baseCurve. If the orientation is "-", then the OrientableCurve is related to another AbstractCurve with a parameterization that reverses the sense of the curve traversal. A curve segment defines a homogeneous segment of a curve. The attributes numDerivativesAtStart, numDerivativesAtEnd and numDerivativesInterior specify the type of continuity as specified in ISO 19107:2003, 6.4.9.3. The AbstractCurveSegment element is the abstract head of the substituition group for all curve segment elements, i.e. continuous segments of the same interpolation mechanism. All curve segments shall have an attribute interpolation with type gml:CurveInterpolationType specifying the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment. gml:CurveSegmentArrayPropertyType is a container for an array of curve segments. This property element contains a list of curve segments. The order of the elements is significant and shall be preserved when processing the array. gml:CurveInterpolationType is a list of codes that may be used to identify the interpolation mechanisms specified by an application schema. A LineStringSegment is a curve segment that is defined by two or more control points including the start and end point, with linear interpolation between them. The content model follows the general pattern for the encoding of curve segments. An ArcString is a curve segment that uses three-point circular arc interpolation (“circularArc3Points”). The number of arcs in the arc string may be explicitly stated in the attribute numArc. The number of control points in the arc string shall be 2 * numArc + 1. The content model follows the general pattern for the encoding of curve segments. An Arc is an arc string with only one arc unit, i.e. three control points including the start and end point. As arc is an arc string consisting of a single arc, the attribute “numArc” is fixed to "1". A Circle is an arc whose ends coincide to form a simple closed loop. The three control points shall be distinct non-co-linear points for the circle to be unambiguously defined. The arc is simply extended past the third control point until the first control point is encountered. This variant of the arc computes the mid points of the arcs instead of storing the coordinates directly. The control point sequence consists of the start and end points of each arc plus the bulge (see ISO 19107:2003, 6.4.17.2). The normal is a vector normal (perpendicular) to the chord of the arc (see ISO 19107:2003, 6.4.17.4). The interpolation is fixed as "circularArc2PointWithBulge". The number of arcs in the arc string may be explicitly stated in the attribute numArc. The number of control points in the arc string shall be numArc + 1. The content model follows the general pattern for the encoding of curve segments. An ArcByBulge is an arc string with only one arc unit, i.e. two control points, one bulge and one normal vector. As arc is an arc string consisting of a single arc, the attribute “numArc” is fixed to "1". This variant of the arc requires that the points on the arc shall be computed instead of storing the coordinates directly. The single control point is the center point of the arc plus the radius and the bearing at start and end. This representation can be used only in 2D. The element radius specifies the radius of the arc. The element startAngle specifies the bearing of the arc at the start. The element endAngle specifies the bearing of the arc at the end. The interpolation is fixed as "circularArcCenterPointWithRadius". Since this type describes always a single arc, the attribute “numArc” is fixed to "1". The content model follows the general pattern for the encoding of curve segments. A gml:CircleByCenterPoint is an gml:ArcByCenterPoint with identical start and end angle to form a full circle. Again, this representation can be used only in 2D. The number of control points shall be at least three. vectorAtStart is the unit tangent vector at the start point of the spline. vectorAtEnd is the unit tangent vector at the end point of the spline. Only the direction of the vectors shall be used to determine the shape of the cubic spline, not their length. interpolation is fixed as "cubicSpline". degree shall be the degree of the polynomial used for the interpolation in this spline. Therefore the degree for a cubic spline is fixed to "3". The content model follows the general pattern for the encoding of curve segments. A B-Spline is a piecewise parametric polynomial or rational curve described in terms of control points and basis functions as specified in ISO 19107:2003, 6.4.30. Therefore, interpolation may be either "polynomialSpline" or "rationalSpline" depending on the interpolation type; default is "polynomialSpline". degree shall be the degree of the polynomial used for interpolation in this spline. knot shall be the sequence of distinct knots used to define the spline basis functions (see ISO 19107:2003, 6.4.26.2). The attribute isPolynomial shall be set to “true” if this is a polynomial spline (see ISO 19107:2003, 6.4.30.5). The attribute knotType shall provide the type of knot distribution used in defining this spline (see ISO 19107:2003, 6.4.30.4). The content model follows the general pattern for the encoding of curve segments. gml:KnotPropertyType encapsulates a knot to use it in a geometric type. A knot is a breakpoint on a piecewise spline curve. value is the value of the parameter at the knot of the spline (see ISO 19107:2003, 6.4.24.2). multiplicity is the multiplicity of this knot used in the definition of the spline (with the same weight). weight is the value of the averaging weight used for this knot of the spline. This enumeration type specifies values for the knots’ type (see ISO 19107:2003, 6.4.25). Bezier curves are polynomial splines that use Bezier or Bernstein polynomials for interpolation purposes. It is a special case of the B-Spline curve with two knots. degree shall be the degree of the polynomial used for interpolation in this spline. knot shall be the sequence of distinct knots used to define the spline basis functions. interpolation is fixed as "polynomialSpline". isPolynomial is fixed as “true”. knotType is not relevant for Bezier curve segments. An offset curve is a curve at a constant distance from the basis curve. offsetBase is the base curve from which this curve is defined as an offset. distance and refDirection have the same meaning as specified in ISO 19107:2003, 6.4.23. The content model follows the general pattern for the encoding of curve segments. location, refDirection, inDimension and outDimension have the same meaning as specified in ISO 19107:2003, 6.4.21. A clothoid, or Cornu's spiral, is plane curve whose curvature is a fixed function of its length. refLocation, startParameter, endParameter and scaleFactor have the same meaning as specified in ISO 19107:2003, 6.4.22. interpolation is fixed as "clothoid". The content model follows the general pattern for the encoding of curve segments. A sequence of geodesic segments. The number of control points shall be at least two. interpolation is fixed as "geodesic". The content model follows the general pattern for the encoding of curve segments. A Surface is a 2-dimensional primitive and is composed of one or more surface patches as specified in ISO 19107:2003, 6.3.17.1. The surface patches are connected to one another. patches encapsulates the patches of the surface. The property baseSurface references or contains the base surface. The property baseSurface either references the base surface via the XLink-attributes or contains the surface element. A surface element is any element which is substitutable for gml:AbstractSurface. The base surface has positive orientation. OrientableSurface consists of a surface and an orientation. If the orientation is "+", then the OrientableSurface is identical to the baseSurface. If the orientation is "-", then the OrientableSurface is a reference to a gml:AbstractSurface with an up-normal that reverses the direction for this OrientableSurface, the sense of "the top of the surface". A surface patch defines a homogenuous portion of a surface. The AbstractSurfacePatch element is the abstract head of the substituition group for all surface patch elements describing a continuous portion of a surface. All surface patches shall have an attribute interpolation (declared in the types derived from gml:AbstractSurfacePatchType) specifying the interpolation mechanism used for the patch using gml:SurfaceInterpolationType. gml:SurfacePatchArrayPropertyType is a container for a sequence of surface patches. The patches property element contains the sequence of surface patches. The order of the elements is significant and shall be preserved when processing the array. gml:SurfaceInterpolationType is a list of codes that may be used to identify the interpolation mechanisms specified by an application schema. A gml:PolygonPatch is a surface patch that is defined by a set of boundary curves and an underlying surface to which these curves adhere. The curves shall be coplanar and the polygon uses planar interpolation in its interior. interpolation is fixed to "planar", i.e. an interpolation shall return points on a single plane. The boundary of the patch shall be contained within that plane. gml:Triangle represents a triangle as a surface patch with an outer boundary consisting of a linear ring. Note that this is a polygon (subtype) with no inner boundaries. The number of points in the linear ring shall be four. The ring (element exterior) shall be a gml:LinearRing and shall form a triangle, the first and the last position shall be coincident. interpolation is fixed to "planar", i.e. an interpolation shall return points on a single plane. The boundary of the patch shall be contained within that plane. gml:Rectangle represents a rectangle as a surface patch with an outer boundary consisting of a linear ring. Note that this is a polygon (subtype) with no inner boundaries. The number of points in the linear ring shall be five. The ring (element exterior) shall be a gml:LinearRing and shall form a rectangle; the first and the last position shall be coincident. interpolation is fixed to "planar", i.e. an interpolation shall return points on a single plane. The boundary of the patch shall be contained within that plane. A ring is used to represent a single connected component of a surface boundary as specified in ISO 19107:2003, 6.3.6. Every gml:curveMember references or contains one curve, i.e. any element which is substitutable for gml:AbstractCurve. In the context of a ring, the curves describe the boundary of the surface. The sequence of curves shall be contiguous and connected in a cycle. If provided, the aggregationType attribute shall have the value “sequence”. A property with the content model of gml:RingPropertyType encapsulates a ring to represent a component of a surface boundary. A gml:PointGrid group contains or references points or positions which are organised into sequences or grids. All rows shall have the same number of positions (columns). The element provides a substitution group head for the surface patches based on parametric curves. All properties are specified in the derived subtypes. All derived subtypes shall conform to the constraints specified in ISO 19107:2003, 6.4.40. If provided, the aggregationType attribute shall have the value “set”. if provided, rows gives the number of rows, columns the number of columns in the parameter grid. The parameter grid is represented by an instance of the gml:PointGrid group. The element provides a substitution group head for the surface patches based on a grid. All derived subtypes shall conform to the constraints specified in ISO 19107:2003, 6.4.41. A polyhedral surface is a surface composed of polygon patches connected along their common boundary curves. This differs from the surface type only in the restriction on the types of surface patches acceptable. polygonPatches encapsulates the polygon patches of the polyhedral surface. gml:PolygonPatchArrayPropertyType provides a container for an array of polygon patches. A triangulated surface is a polyhedral surface that is composed only of triangles. There is no restriction on how the triangulation is derived. trianglePatches encapsulates the triangles of the triangulated surface. gml:TrianglePatchArrayPropertyType provides a container for an array of triangle patches. A tin is a triangulated surface that uses the Delauny algorithm or a similar algorithm complemented with consideration of stoplines (stopLines), breaklines (breakLines), and maximum length of triangle sides (maxLength). controlPoint shall contain a set of the positions (three or more) used as posts for this TIN (corners of the triangles in the TIN). See ISO 19107:2003, 6.4.39 for details. gml:LineStringSegmentArrayPropertyType provides a container for line strings. gml:AbstractSolidType is an abstraction of a solid to support the different levels of complexity. The solid may always be viewed as a geometric primitive, i.e. is contiguous. The AbstractSolid element is the abstract head of the substituition group for all (continuous) solid elements. A property that has a solid as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none. This property element either references a solid via the XLink-attributes or contains the solid element. solidProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractSolid. gml:SolidArrayPropertyType is a container for an array of solids. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements is not supported. This property element contains a list of solid elements. solidArrayProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for a list of AbstractSolid. A solid is the basis for 3-dimensional geometry. The extent of a solid is defined by the boundary surfaces as specified in ISO 19107:2003, 6.3.18. exterior specifies the outer boundary, interior the inner boundary of the solid. A shell is used to represent a single connected component of a solid boundary as specified in ISO 19107:2003, 6.3.8. Every gml:surfaceMember references or contains one surface, i.e. any element which is substitutable for gml:AbstractSurface. In the context of a shell, the surfaces describe the boundary of the solid. If provided, the aggregationType attribute shall have the value “set”. This property element either references a surface via the XLink-attributes or contains the surface element. A surface element is any element, which is substitutable for gml:AbstractSurface. A property with the content model of gml:ShellPropertyType encapsulates a shell to represent a component of a solid boundary. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gml.xsd ================================================ gml.xsd ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd ================================================ gmlBase.xsd Schematron validation Property element may not carry both a reference to an object and contain an object. Property element must either carry a reference to an object or contain an object. See ISO/DIS 19136 7.2. The gmlBase schema components establish the GML model and syntax, in particular - a root XML type from which XML types for all GML objects should be derived, - a pattern and components for GML properties, - patterns for collections and arrays, and components for generic collections and arrays, - components for associating metadata with GML objects, - components for constructing definitions and dictionaries. This element has no type defined, and is therefore implicitly (according to the rules of W3C XML Schema) an XML Schema anyType. It is used as the head of an XML Schema substitution group which unifies complex content and certain simple content elements used for datatypes in GML, including the gml:AbstractGML substitution group. The abstract element gml:AbstractGML is “any GML object having identity”. It acts as the head of an XML Schema substitution group, which may include any element which is a GML feature, or other object, with identity. This is used as a variable in content models in GML core and application schemas. It is effectively an abstract superclass for all GML objects. XLink components are the standard method to support hypertext referencing in XML. An XML Schema attribute group, gml:AssociationAttributeGroup, is provided to support the use of Xlinks as the method for indicating the value of a property by reference in a uniform manner in GML. deprecated Applying this pattern shall restrict the multiplicity of objects in a property element using this content model to exactly one. An instance of this type shall contain an element representing an object, or serve as a pointer to a remote object. Applying the pattern to define an application schema specific property type allows to restrict - the inline object to specified object types, - the encoding to „by-reference only“ (see 7.2.3.7), - the encoding to „inline only“ (see 7.2.3.8). Encoding a GML property inline vs. by-reference shall not imply anything about the “ownership” of the contained or referenced GML Object, i.e. the encoding style shall not imply any “deep-copy” or “deep-delete” semantics. To express ownership over the contained or referenced GML Object, the gml:OwnershipAttributeGroup attribute group may be added to object-valued property elements. If the attribute group is not part of the content model of such a property element, then the value may not be “owned”. When the value of the owns attribute is "true", the existence of inline or referenced object(s) depends upon the existence of the parent object. This element shows how an element declaration may include a Schematron constraint to limit the property to act in either inline or by-reference mode, but not both. gml:abstractReference may be used as the head of a subtitution group of more specific elements providing a value by-reference. gml:ReferenceType is intended to be used in application schemas directly, if a property element shall use a “by-reference only” encoding. gml:abstractInlineProperty may be used as the head of a subtitution group of more specific elements providing a value inline. If the value of an object property is another object and that object contains also a property for the association between the two objects, then this name of the reverse property may be encoded in a gml:reversePropertyName element in an appinfo annotation of the property element to document the constraint between the two properties. The value of the element shall contain the qualified name of the property element. deprecated deprecated deprecated deprecated deprecated The value of this property is a text description of the object. gml:description uses gml:StringOrRefType as its content model, so it may contain a simple text string content, or carry a reference to an external description. The use of gml:description to reference an external description has been deprecated and replaced by the gml:descriptionReference property. The value of this property is a remote text description of the object. The xlink:href attribute of the gml:descriptionReference property references the external description. The gml:name property provides a label or identifier for the object, commonly a descriptive name. An object may have several names, typically assigned by different authorities. gml:name uses the gml:CodeType content model. The authority for a name is indicated by the value of its (optional) codeSpace attribute. The name may or may not be unique, as determined by the rules of the organization responsible for the codeSpace. In common usage there will be one name per authority, so a processing application may select the name from its preferred codeSpace. Often, a special identifier is assigned to an object by the maintaining authority with the intention that it is used in references to the object For such cases, the codeSpace shall be provided. That identifier is usually unique either globally or within an application domain. gml:identifier is a pre-defined property for such identifiers. The attribute gml:id supports provision of a handle for the XML element representing a GML Object. Its use is mandatory for all GML objects. It is of XML type ID, so is constrained to be unique in the XML document within which it occurs. To create a collection of GML Objects that are not all features, a property type shall be derived by extension from gml:AbstractMemberType. This abstract property type is intended to be used only in object types where software shall be able to identify that an instance of such an object type is to be interpreted as a collection of objects. By default, this abstract property type does not imply any ownership of the objects in the collection. The owns attribute of gml:OwnershipAttributeGroup may be used on a property element instance to assert ownership of an object in the collection. A collection shall not own an object already owned by another object. A GML Object Collection is any GML Object with a property element in its content model whose content model is derived by extension from gml:AbstractMemberType. In addition, the complex type describing the content model of the GML Object Collection may also include a reference to the attribute group gml:AggregationAttributeGroup to provide additional information about the semantics of the object collection. This information may be used by applications to group GML objects, and optionally to order and index them. The allowed values for the aggregationType attribute are defined by gml:AggregationType. See 8.4 of ISO/IEC 11404:1996 for the meaning of the values in the enumeration. deprecated deprecated deprecated deprecated To associate metadata described by any XML Schema with a GML object, a property element shall be defined whose content model is derived by extension from gml:AbstractMetadataPropertyType. The value of such a property shall be metadata. The content model of such a property type, i.e. the metadata application schema shall be specified by the GML Application Schema. By default, this abstract property type does not imply any ownership of the metadata. The owns attribute of gml:OwnershipAttributeGroup may be used on a metadata property element instance to assert ownership of the metadata. If metadata following the conceptual model of ISO 19115 is to be encoded in a GML document, the corresponding Implementation Specification specified in ISO/TS 19139 shall be used to encode the metadata information. deprecated deprecated deprecated deprecated deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/grids.xsd ================================================ grids.xsd See ISO/DIS 19136 20.2. An implicit description of geometry is one in which the items of the geometry do not explicitly appear in the encoding. Instead, a compact notation records a set of parameters, and a set of objects may be generated using a rule with these parameters. This Clause provides grid geometries that are used in the description of gridded coverages and other applications. In GML two grid structures are defined, namely gml:Grid and gml:RectifiedGrid. The gml:Grid implicitly defines an unrectified grid, which is a network composed of two or more sets of curves in which the members of each set intersect the members of the other sets in an algorithmic way. The region of interest within the grid is given in terms of its gml:limits, being the grid coordinates of diagonally opposed corners of a rectangular region. gml:axisLabels is provided with a list of labels of the axes of the grid (gml:axisName has been deprecated). gml:dimension specifies the dimension of the grid. The gml:limits element contains a single gml:GridEnvelope. The gml:low and gml:high property elements of the envelope are each integerLists, which are coordinate tuples, the coordinates being measured as offsets from the origin of the grid along each axis, of the diagonally opposing corners of a “rectangular” region of interest. A rectified grid is a grid for which there is an affine transformation between the grid coordinates and the coordinates of an external coordinate reference system. It is defined by specifying the position (in some geometric space) of the grid “origin” and of the vectors that specify the post locations. Note that the grid limits (post indexes) and axis name properties are inherited from gml:GridType and that gml:RectifiedGrid adds a gml:origin property (contains or references a gml:Point) and a set of gml:offsetVector properties. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/measures.xsd ================================================ measures.xsd See ISO/DIS 19136 17.3. gml:MeasureType is defined in the basicTypes schema. The measure types defined here correspond with a set of convenience measure types described in ISO/TS 19103. The XML implementation is based on the XML Schema simple type “double” which supports both decimal and scientific notation, and includes an XML attribute “uom” which refers to the units of measure for the value. Note that, there is no requirement to store values using any particular format, and applications receiving elements of this type may choose to coerce the data to any other type as convenient. The value of a physical quantity, together with its unit. This is a prototypical definition for a specific measure type defined as a vacuous extension (i.e. aliases) of gml:MeasureType. In this case, the content model supports the description of a length (or distance) quantity, with its units. The unit of measure referenced by uom shall be suitable for a length, such as metres or feet. The gml:angle property element is used to record the value of an angle quantity as a single number, with its units. deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/observation.xsd ================================================ observation.xsd See ISO/DIS 19136 Clause 19. A GML observation models the act of observing, often with a camera, a person or some form of instrument. An observation feature describes the “metadata” associated with an information capture event, together with a value for the result of the observation. This covers a broad range of cases, from a tourist photo (not the photo but the act of taking the photo), to images acquired by space borne sensors or the measurement of a temperature 5 meters below the surfaces of a lake. The basic structures introduced in this schema are intended to serve as the foundation for more comprehensive schemas for scientific, technical and engineering measurement schemas. The content model is a straightforward extension of gml:AbstractFeatureType; it automatically has the gml:identifier, gml:description, gml:descriptionReference, gml:name, and gml:boundedBy properties. The gml:validTime element describes the time of the observation. Note that this may be a time instant or a time period. The gml:using property contains or references a description of a sensor, instrument or procedure used for the observation. The gml:target property contains or references the specimen, region or station which is the object of the observation. This property is particularly useful for remote observations, such as photographs, where a generic location property might apply to the location of the camera or the location of the field of view, and thus may be ambiguous. The gml:subject element is provided as a convenient synonym for gml:target. This is the term commonly used in phtotography. The gml:resultOf property indicates the result of the observation. The value may be inline, or a reference to a value elsewhere. If the value is inline, it shall be a member of the gml:AbstractObject substitution group. A gml:DirectedObservation is the same as an observation except that it adds an additional gml:direction property. This is the direction in which the observation was acquired. Clearly this applies only to certain types of observations such as visual observations by people, or observations obtained from terrestrial cameras. gml:DirectedObservationAtDistance adds an additional distance property. This is the distance from the observer to the subject of the observation. Clearly this applies only to certain types of observations such as visual observations by people, or observations obtained from terrestrial cameras. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/referenceSystems.xsd ================================================ referenceSystems.xsd See ISO/DIS 19136 13.2. The reference systems schema components have two logical parts, which define elements and types for XML encoding of the definitions of: - Identified Object, inherited by the ten types of GML objects used for coordinate reference systems and coordinate operations - High-level part of the definitions of coordinate reference systems This schema encodes the Identified Object and Reference System packages of the UML Model for ISO 19111. gml:IdentifiedObjectType provides identification properties of a CRS-related object. In gml:DefinitionType, the gml:identifier element shall be the primary name by which this object is identified, encoding the "name" attribute in the UML model. Zero or more of the gml:name elements can be an unordered set of "identifiers", encoding the "identifier" attribute in the UML model. Each of these gml:name elements can reference elsewhere the object's defining information or be an identifier by which this object can be referenced. Zero or more other gml:name elements can be an unordered set of "alias" alternative names by which this CRS related object is identified, encoding the "alias" attributes in the UML model. An object may have several aliases, typically used in different contexts. The context for an alias is indicated by the value of its (optional) codeSpace attribute. Any needed version information shall be included in the codeSpace attribute of a gml:identifier and gml:name elements. In this use, the gml:remarks element in the gml:DefinitionType shall contain comments on or information about this object, including data source information. gml:AbstractCRS specifies a coordinate reference system which is usually single but may be compound. This abstract complex type shall not be used, extended, or restricted, in a GML Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document. The gml:domainOfValidity property implements an association role to an EX_Extent object as encoded in ISO/TS 19139, either referencing or containing the definition of that extent. The gml:scope property provides a description of the usage, or limitations of usage, for which this CRS-related object is valid. If unknown, enter "not known". gml:CRSPropertyType is a property type for association roles to a CRS abstract coordinate reference system, either referencing or containing the definition of that CRS. gml:crsRef is an association role either referencing or containing the definition of a CRS. This property element has been deprecated. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/temporal.xsd ================================================ temporal.xsd See ISO/DIS 19136 15.2. The GML temporal schemas include components for describing temporal geometry and topology, temporal reference systems, and the temporal characteristics of geographic data. The model underlying the representation constitutes a profile of the conceptual schema described in ISO 19108. The underlying spatiotemporal model strives to accommodate both feature-level and attribute-level time stamping; basic support for tracking moving objects is also included. Time is measured on two types of scales: interval and ordinal. An interval scale offers a basis for measuring duration, an ordinal scale provides information only about relative position in time. Two other ISO standards are relevant to describing temporal objects: ISO 8601 describes encodings for time instants and time periods, as text strings with particular structure and punctuation; ISO 11404 provides a detailed description of time intervals as part of a general discussion of language independent datatypes. The temporal schemas cover two interrelated topics and provide basic schema components for representing temporal instants and periods, temporal topology, and reference systems; more specialized schema components defines components used for dynamic features. Instances of temporal geometric types are used as values for the temporal properties of geographic features. gml:AbstractTimeObject acts as the head of a substitution group for all temporal primitives and complexes. gml:AbstractTimePrimitive acts as the head of a substitution group for geometric and topological temporal primitives. gml:TimePrimitivePropertyType provides a standard content model for associations between an arbitrary member of the substitution group whose head is gml:AbstractTimePrimitive and another object. gml:validTime is a convenience property element. gml:RelatedTimeType provides a content model for indicating the relative position of an arbitrary member of the substitution group whose head is gml:AbstractTimePrimitive. It extends the generic gml:TimePrimitivePropertyType with an XML attribute relativePosition, whose value is selected from the set of 13 temporal relationships identified by Allen (1983) gml:AbstractTimeComplex is an aggregation of temporal primitives and acts as the head of a substitution group for temporal complexes. gml:TimeGeometricPrimitive acts as the head of a substitution group for geometric temporal primitives. A temporal geometry shall be associated with a temporal reference system through the frame attribute that provides a URI reference that identifies a description of the reference system. Following ISO 19108, the Gregorian calendar with UTC is the default reference system, but others may also be used. The GPS calendar is an alternative reference systems in common use. The two geometric primitives in the temporal dimension are the instant and the period. GML components are defined to support these as follows. gml:TimeInstant acts as a zero-dimensional geometric primitive that represents an identifiable position in time. gml:TimeInstantPropertyType provides for associating a gml:TimeInstant with an object. gml:TimePeriod acts as a one-dimensional geometric primitive that represents an identifiable extent in time. The location in of a gml:TimePeriod is described by the temporal positions of the instants at which it begins and ends. The length of the period is equal to the temporal distance between the two bounding temporal positions. Both beginning and end may be described in terms of their direct position using gml:TimePositionType which is an XML Schema simple content type, or by reference to an indentifiable time instant using gml:TimeInstantPropertyType. Alternatively a limit of a gml:TimePeriod may use the conventional GML property model to make a reference to a time instant described elsewhere, or a limit may be indicated as a direct position. gml:TimePeriodPropertyType provides for associating a gml:TimePeriod with an object. The method for identifying a temporal position is specific to each temporal reference system. gml:TimePositionType supports the description of temporal position according to the subtypes described in ISO 19108. Values based on calendars and clocks use lexical formats that are based on ISO 8601, as described in XML Schema Part 2:2001. A decimal value may be used with coordinate systems such as GPS time or UNIX time. A URI may be used to provide a reference to some era in an ordinal reference system . In common with many of the components modelled as data types in the ISO 19100 series of International Standards, the corresponding GML component has simple content. However, the content model gml:TimePositionType is defined in several steps. Three XML attributes appear on gml:TimePositionType: A time value shall be associated with a temporal reference system through the frame attribute that provides a URI reference that identifies a description of the reference system. Following ISO 19108, the Gregorian calendar with UTC is the default reference system, but others may also be used. Components for describing temporal reference systems are described in 14.4, but it is not required that the reference system be described in this, as the reference may refer to anything that may be indentified with a URI. For time values using a calendar containing more than one era, the (optional) calendarEraName attribute provides the name of the calendar era. Inexact temporal positions may be expressed using the optional indeterminatePosition attribute. This takes a value from an enumeration. These values are interpreted as follows: - “unknown” indicates that no specific value for temporal position is provided. - “now” indicates that the specified value shall be replaced with the current temporal position whenever the value is accessed. - “before” indicates that the actual temporal position is unknown, but it is known to be before the specified value. - “after” indicates that the actual temporal position is unknown, but it is known to be after the specified value. A value for indeterminatePosition may - be used either alone, or - qualify a specific value for temporal position. The simple type gml:TimePositionUnion is a union of XML Schema simple types which instantiate the subtypes for temporal position described in ISO 19108. An ordinal era may be referenced via URI. A decimal value may be used to indicate the distance from the scale origin . time is used for a position that recurs daily (see ISO 19108:2002 5.4.4.2). Finally, calendar and clock forms that support the representation of time in systems based on years, months, days, hours, minutes and seconds, in a notation following ISO 8601, are assembled by gml:CalDate This element is used directly as a property of gml:TimeInstant (see 15.2.2.3), and may also be used in application schemas. The length of a time period. gml:duration conforms to the ISO 8601 syntax for temporal length as implemented by the XML Schema duration type. gml:timeInterval conforms to ISO 11404 which is based on floating point values for temporal length. ISO 11404 syntax specifies the use of a positiveInteger together with appropriate values for radix and factor. The resolution of the time interval is to one radix ^(-factor) of the specified time unit. The value of the unit is either selected from the units for time intervals from ISO 31-1:1992, or is another suitable unit. The encoding is defined for GML in gml:TimeUnitType. The second component of this union type provides a method for indicating time units other than the six standard units given in the enumeration. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/temporalReferenceSystems.xsd ================================================ temporalReferenceSystems.xsd See ISO/DIS 19136 15.5. A value in the time domain is measured relative to a temporal reference system. Common types of reference systems include calendars, ordinal temporal reference systems, and temporal coordinate systems (time elapsed since some epoch). The primary temporal reference system for use with geographic information is the Gregorian Calendar and 24 hour local or Coordinated Universal Time (UTC), but special applications may entail the use of alternative reference systems. The Julian day numbering system is a temporal coordinate system that has an origin earlier than any known calendar, at noon on 1 January 4713 BC in the Julian proleptic calendar, and is useful in transformations between dates in different calendars. In GML seven concrete elements are used to describe temporal reference systems: gml:TimeReferenceSystem, gml:TimeCoordinateSystem, gml:TimeCalendar, gml:TimeCalendarEra, gml:TimeClock, gml:TimeOrdinalReferenceSystem, and gml:TimeOrdinalEra. A reference system is characterized in terms of its domain of validity: the spatial and temporal extent over which it is applicable. The basic GML element for temporal reference systems is gml:TimeReferenceSystem. Its content model extends gml:DefinitionType with one additional property, gml:domainOfValidity. A temporal coordinate system shall be based on a continuous interval scale defined in terms of a single time interval. The differences to ISO 19108 TM_CoordinateSystem are: - the origin is specified either using the property gml:originPosition whose value is a direct time position, or using the property gml:origin whose model is gml:TimeInstantPropertyType; this permits more flexibility in representation and also supports referring to a value fixed elsewhere; - the interval uses gml:TimeIntervalLengthType. A calendar is a discrete temporal reference system that provides a basis for defining temporal position to a resolution of one day. gml:TimeCalendar adds one property to those inherited from gml:TimeReferenceSystem. A gml:referenceFrame provides a link to a gml:TimeCalendarEra that it uses. A gml:TimeCalendar may reference more than one calendar era. The referenceFrame element follows the standard GML property model, allowing the association to be instantiated either using an inline description using the gml:TimeCalendarEra element, or a link to a gml:TimeCalendarEra which is explicit elsewhere. gml:TimeCalendarEra inherits basic properties from gml:DefinitionType and has the following additional properties: - gml:referenceEvent is the name or description of a mythical or historic event which fixes the position of the base scale of the calendar era. This is given as text or using a link to description held elsewhere. - gml:referenceDate specifies the date of the referenceEvent expressed as a date in the given calendar. In most calendars, this date is the origin (i.e., the first day) of the scale, but this is not always true. - gml:julianReference specifies the Julian date that corresponds to the reference date. The Julian day number is an integer value; the Julian date is a decimal value that allows greater resolution. Transforming calendar dates to and from Julian dates provides a relatively simple basis for transforming dates from one calendar to another. - gml:epochOfUse is the period for which the calendar era was used as a basis for dating. gml:TimeCalendarPropertyType provides for associating a gml:TimeCalendar with an object. gml:TimeCalendarEraPropertyType provides for associating a gml:TimeCalendarEra with an object. A clock provides a basis for defining temporal position within a day. A clock shall be used with a calendar in order to provide a complete description of a temporal position within a specific day. gml:TimeClock adds the following properties to those inherited from gml:TimeReferenceSystemType: - gml:referenceEvent is the name or description of an event, such as solar noon or sunrise, which fixes the position of the base scale of the clock. - gml:referenceTime specifies the time of day associated with the reference event expressed as a time of day in the given clock. The reference time is usually the origin of the clock scale. - gml:utcReference specifies the 24 hour local or UTC time that corresponds to the reference time. - gml:dateBasis contains or references the calendars that use this clock. gml:TimeClockPropertyType provides for associating a gml:TimeClock with an object. In some applications of geographic information — such as geology and archaeology — relative position in time is known more precisely than absolute time or duration. The order of events in time can be well established, but the magnitude of the intervals between them cannot be accurately determined; in such cases, the use of an ordinal temporal reference system is appropriate. An ordinal temporal reference system is composed of a sequence of named coterminous eras, which may in turn be composed of sequences of member eras at a finer scale, giving the whole a hierarchical structure of eras of verying resolution. An ordinal temporal reference system whose component eras are not further subdivided is effectively a temporal topological complex constrained to be a linear graph. An ordinal temporal reference system some or all of whose component eras are subdivided is effectively a temporal topological complex with the constraint that parallel branches may only be constructed in pairs where one is a single temporal ordinal era and the other is a sequence of temporal ordinal eras that are called "members" of the "group". This constraint means that within a single temporal ordinal reference system, the relative position of all temporal ordinal eras is unambiguous. The positions of the beginning and end of a given era may calibrate the relative time scale. gml:TimeOrdinalReferenceSystem adds one or more gml:component properties to the generic temporal reference system model. Its content model follows the pattern of gml:TimeEdge, inheriting standard properties from gml:DefinitionType, and adding gml:start, gml:end and gml:extent properties, a set of gml:member properties which indicate ordered gml:TimeOrdinalEra elements, and a gml:group property which points to the parent era. The recursive inclusion of gml:TimeOrdinalEra elements allow the construction of an arbitrary depth hierarchical ordinal reference schema, such that an ordinal era at a given level of the hierarchy includes a sequence of shorter, coterminous ordinal eras. gml:TimeOrdinalEraPropertyType provides for associating a gml:TimeOrdinalEra with an object. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/temporalTopology.xsd ================================================ temporalTopology.xsd See ISO/DIS 19136 15.3. Temporal topology is described in terms of time complexes, nodes, and edges, and the connectivity between these. Temporal topology does not directly provide information about temporal position. It is used in the case of describing a lineage or a history (e.g. a family tree expressing evolution of species, an ecological cycle, a lineage of lands or buildings, or a history of separation and merger of administrative boundaries). The following Subclauses specifies the temporal topology as temporal characteristics of features in compliance with ISO 19108. gml:TimeTopologyPrimitive acts as the head of a substitution group for topological temporal primitives. Temporal topology primitives shall imply the ordering information between features or feature properties. The temporal connection of features can be examined if they have temporal topology primitives as values of their properties. Usually, an instantaneous feature associates with a time node, and a static feature associates with a time edge. A feature with both modes associates with the temporal topology primitive: a supertype of time nodes and time edges. A topological primitive is always connected to one or more other topological primitives, and is, therefore, always a member of a topological complex. In a GML instance, this will often be indicated by the primitives being described by elements that are descendents of an element describing a complex. However, in order to support the case where a temporal topological primitive is described in another context, the optional complex property is provided, which carries a reference to the parent temporal topological complex. gml:TimeTopologyPrimitivePropertyType provides for associating a gml:AbstractTimeTopologyPrimitive with an object. A temporal topology complex shall be the connected acyclic directed graph composed of temporal topological primitives, i.e. time nodes and time edges. Because a time edge may not exist without two time nodes on its boundaries, static features have time edges from a temporal topology complex as the values of their temporal properties, regardless of explicit declarations. A temporal topology complex expresses a linear or a non-linear graph. A temporal linear graph, composed of a sequence of time edges, provides a lineage described only by “substitution” of feature instances or feature element values. A time node as the start or the end of the graph connects with at least one time edge. A time node other than the start and the end shall connect to at least two time edges: one of starting from the node, and another ending at the node. A temporal topological complex is a set of connected temporal topological primitives. The member primtives are indicated, either by reference or by value, using the primitive property. gml:TimeTopologyComplexPropertyType provides for associating a gml:TimeTopologyComplex with an object. A time node is a zero-dimensional topological primitive that represents an identifiable node in time (it is equivalent to a point in space). A node may act as the termination or initiation of any number of time edges. A time node may be realised as a geometry, its position, whose value is a time instant. gml:TimeNodePropertyType provides for associating a gml:TimeNode with an object A time edge is a one-dimensional topological primitive. It is an open interval that starts and ends at a node. The edge may be realised as a geometry whose value is a time period. gml:TimeEdgePropertyType provides for associating a gml:TimeEdge with an object. deprecated ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/topology.xsd ================================================ topology.xsd See ISO/DIS 19136 Clause 14. Topology is the branch of mathematics describing the properties of objects which are invariant under continuous deformation. For example, a circle is topologically equivalent to an ellipse because one can be transformed into the other by stretching. In geographic modelling, the foremost use of topology is in accelerating computational geometry. The constructs of topology allow characterisation of the spatial relationships between objects using simple combinatorial or algebraic algorithms. Topology, realised by the appropriate geometry, also allows a compact and unambiguous mechanism for expressing shared geometry among geographic features. There are four instantiable classes of primitive topology objects, one for each dimension up to 3D. In addition, topological complexes are supported, too. There is strong symmetry in the (topological boundary and coboundary) relationships between topology primitives of adjacent dimensions. Topology primitives are bounded by directed primitives of one lower dimension. The coboundary of each topology primitive is formed from directed topology primitives of one higher dimension. This abstract type supplies the root or base type for all topological elements including primitives and complexes. It inherits AbstractGMLType and hence can be identified using the gml:id attribute. gml:AbstractTopoPrimitive acts as the base type for all topological primitives. Topology primitives are the atomic (smallest possible) units of a topology complex. Each topology primitive may contain references to other topology primitives of codimension 2 or more (gml:isolated). Conversely, nodes may have faces as containers and nodes and edges may have solids as containers (gml:container). The gml:isolated property element implements the role of the same name of the ISO 19107 “Isolated In” association (see ISO 19107:2003, 7.3.10.4). The gml:container property element implements the role of the same name of the ISO 19107 “Isolated In” association (see ISO 19107:2003, 7.3.10.4). gml:Node represents the 0-dimensional primitive. The optional coboundary of a node (gml:directedEdge) is a sequence of directed edges which are incident on this node. Edges emanating from this node appear in the node coboundary with a negative orientation. If provided, the aggregationType attribute shall have the value “sequence”. A node may optionally be realised by a 0-dimensional geometric primitive (gml:pointProperty). A gml:directedNode property element describes the boundary of topology edges and is used in the support of topological point features via the gml:TopoPoint expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included node is used: start (“-“) or end (“+”) node. gml:Edge represents the 1-dimensional primitive. The topological boundary of an Edge (gml:directedNode) consists of a negatively directed start Node and a positively directed end Node. The optional coboundary of an edge (gml:directedFace) is a circular sequence of directed faces which are incident on this edge in document order. In the 2D case, the orientation of the face on the left of the edge is "+"; the orientation of the face on the right on its right is "-". If provided, the aggregationType attribute shall have the value “sequence”. An edge may optionally be realised by a 1-dimensional geometric primitive (gml:curveProperty). A gml:directedEdge property element describes the boundary of topology faces, the coBoundary of topology nodes and is used in the support of topological line features via the gml:TopoCurve expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included edge is used, i.e. forward or reverse. gml:Face represents the 2-dimensional topology primitive. The topological boundary of a face (gml:directedEdge) consists of a sequence of directed edges. If provided, the aggregationType attribute shall have the value “sequence”. The optional coboundary of a face (gml:directedTopoSolid) is a pair of directed solids which are bounded by this face. A positively directed solid corresponds to a solid which lies in the direction of the negatively directed normal to the face in any geometric realisation. A face may optionally be realised by a 2-dimensional geometric primitive (gml:surfaceProperty). The gml:directedFace property element describes the boundary of topology solids, in the coBoundary of topology edges and is used in the support of surface features via the gml:TopoSurface expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included face is used i.e. inward or outward with respect to the surface normal in any geometric realisation. gml:TopoSolid represents the 3-dimensional topology primitive. The topological boundary of a solid (gml:directedFace) consists of a set of directed faces. A solid may optionally be realised by a 3-dimensional geometric primitive (gml:solidProperty). The gml:directedSolid property element describes the coBoundary of topology faces and is used in the support of volume features via the gml:TopoVolume expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included solid appears in the face coboundary. In the context of a gml:TopoVolume the orientation attribute has no meaning. The intended use of gml:TopoPoint is to appear within a point feature to express the structural and possibly geometric relationships of this feature to other features via shared node definitions. The gml:topoPointProperty property element may be used in features to express their relationship to the referenced topology node. gml:TopoCurve represents a homogeneous topological expression, a sequence of directed edges, which if realised are isomorphic to a geometric curve primitive. The intended use of gml:TopoCurve is to appear within a line feature to express the structural and geometric relationships of this feature to other features via the shared edge definitions. If provided, the aggregationType attribute shall have the value “sequence”. The gml:topoCurveProperty property element may be used in features to express their relationship to the referenced topology edges. gml:TopoSurface represents a homogeneous topological expression, a set of directed faces, which if realised are isomorphic to a geometric surface primitive. The intended use of gml:TopoSurface is to appear within a surface feature to express the structural and possibly geometric relationships of this surface feature to other features via the shared face definitions. The gml:topoSurfaceProperty property element may be used in features to express their relationship to the referenced topology faces. gml:TopoVolume represents a homogeneous topological expression, a set of directed topologic solids, which if realised are isomorphic to a geometric solid primitive. The intended use of gml:TopoVolume is to appear within a solid feature to express the structural and geometric relationships of this solid feature to other features via the shared solid definitions. The gml:topoVolumeProperty element may be used in features to express their relationship to the referenced topology volume. gml:TopoComplex is a collection of topological primitives. Each complex holds a reference to its maximal complex (gml:maximalComplex) and optionally to sub- or super-complexes (gml:subComplex, gml:superComplex). A topology complex contains its primitive and sub-complex members. The property elements gml:subComplex, gml:superComplex and gml:maximalComplex provide an encoding for relationships between topology complexes as described for gml:TopoComplex above. The property elements gml:subComplex, gml:superComplex and gml:maximalComplex provide an encoding for relationships between topology complexes as described for gml:TopoComplex above. The property elements gml:subComplex, gml:superComplex and gml:maximalComplex provide an encoding for relationships between topology complexes as described for gml:TopoComplex above. The gml:topoPrimitiveMember property element encodes for the relationship between a topology complex and a single topology primitive. The gml:topoPrimitiveMembers property element encodes the relationship between a topology complex and an arbitrary number of topology primitives. The gml:topoComplexProperty property element encodes the relationship between a GML object and a topological complex. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/units.xsd ================================================ units.xsd See ISO/DIS 17.2. Several GML Schema components concern or require a reference scale or units of measure. Units are required for quantities that may occur as values of properties of feature types, as the results of observations, in the range parameters of a coverage, and for measures used in Coordinate Reference System definitions. The basic unit definition is an extension of the general gml:Definition element defined in 16.2.1. Three specialized elements for unit definition are further derived from this. This model is based on the SI system of units [ISO 1000], which distinguishes between Base Units and Derived Units. - Base Units are the preferred units for a set of orthogonal fundamental quantities which define the particular system of units, which may not be derived by combination of other base units. - Derived Units are the preferred units for other quantities in the system, which may be defined by algebraic combination of the base units. In some application areas Conventional units are used, which may be converted to the preferred units using a scaling factor or a formula which defines a re-scaling and offset. The set of preferred units for all physical quantity types in a particular system of units is composed of the union of its base units and derived units. Unit definitions are substitutable for the gml:Definition element declared as part of the dictionary model. A dictionary that contains only unit definitions and references to unit definitions is a units dictionary. The element gml:unitOfMeasure is a property element to refer to a unit of measure. This is an empty element which carries a reference to a unit of measure definition. A gml:UnitDefinition is a general definition of a unit of measure. This generic element is used only for units for which no relationship with other units or units systems is known. The content model of gml:UnitDefinition adds three additional properties to gml:Definition, gml:quantityType, gml:quantityTypeReference and gml:catalogSymbol. The gml:catalogSymbol property optionally gives the short symbol used for this unit. This element is usually used when the relationship of this unit to other units or units systems is unknown. The gml:quantityType property indicates the phenomenon to which the units apply. This element contains an informal description of the phenomenon or type of physical quantity that is measured or observed. When the physical quantity is the result of an observation or measurement, this term is known as observable type or measurand. The use of gml:quantityType for references to remote values is deprecated. The gml:quantityTypeReference property indicates the phenomenon to which the units apply. The content is a reference to a remote value. The catalogSymbol is the preferred lexical symbol used for this unit of measure. The codeSpace attribute in gml:CodeType identifies a namespace for the catalog symbol value, and might reference the external catalog. The string value in gml:CodeType contains the value of a symbol that should be unique within this catalog namespace. This symbol often appears explicitly in the catalog, but it could be a combination of symbols using a specified algebra of units. A base unit is a unit of measure that cannot be derived by combination of other base units within a particular system of units. For example, in the SI system of units, the base units are metre, kilogram, second, Ampere, Kelvin, mole, and candela, for the physical quantity types length, mass, time interval, electric current, thermodynamic temperature, amount of substance and luminous intensity, respectively. gml:BaseUnit extends generic gml:UnitDefinition with the property gml:unitsSystem, which carries a reference to the units system to which this base unit is asserted to belong. Derived units are defined by combination of other units. Derived units are used for quantities other than those corresponding to the base units, such as hertz (s-1) for frequency, Newton (kg.m/s2) for force. Derived units based directly on base units are usually preferred for quantities other than the fundamental quantities within a system. If a derived unit is not the preferred unit, the gml:ConventionalUnit element should be used instead. The gml:DerivedUnit extends gml:UnitDefinition with the property gml:derivationUnitTerms. A set of gml:derivationUnitTerm elements describes a derived unit of measure. Each element carries an integer exponent. The terms are combined by raising each referenced unit to the power of its exponent and forming the product. This unit term references another unit of measure (uom) and provides an integer exponent applied to that unit in defining the compound unit. The exponent may be positive or negative, but not zero. Conventional units that are neither base units nor defined by direct combination of base units are used in many application domains. For example electronVolt for energy, feet and nautical miles for length. In most cases there is a known, usually linear, conversion to a preferred unit which is either a base unit or derived by direct combination of base units. The gml:ConventionalUnit extends gml:UnitDefinition with a property that describes a conversion to a preferred unit for this physical quantity. When the conversion is exact, the element gml:conversionToPreferredUnit should be used, or when the conversion is not exact the element gml:roughConversionToPreferredUnit is available. Both of these elements have the same content model. The gml:derivationUnitTerm property defined above is included to allow a user to optionally record how this unit may be derived from other (“more primitive”) units. The elements gml:conversionToPreferredUnit and gml:roughConversionToPreferredUnit represent parameters used to convert conventional units to preferred units for this physical quantity type. A preferred unit is either a Base Unit or a Derived Unit that is selected for all values of one physical quantity type. The elements gml:conversionToPreferredUnit and gml:roughConversionToPreferredUnit represent parameters used to convert conventional units to preferred units for this physical quantity type. A preferred unit is either a Base Unit or a Derived Unit that is selected for all values of one physical quantity type. The inherited attribute uom references the preferred unit that this conversion applies to. The conversion of a unit to the preferred unit for this physical quantity type is specified by an arithmetic conversion (scaling and/or offset). The content model extends gml:UnitOfMeasureType, which has a mandatory attribute uom which identifies the preferred unit for the physical quantity type that this conversion applies to. The conversion is specified by a choice of - gml:factor, which defines the scale factor, or - gml:formula, which defines a formula by which a value using the conventional unit of measure can be converted to obtain the corresponding value using the preferred unit of measure. The formula defines the parameters of a simple formula by which a value using the conventional unit of measure can be converted to the corresponding value using the preferred unit of measure. The formula element contains elements a, b, c and d, whose values use the XML Schema type double. These values are used in the formula y = (a + bx) / (c + dx), where x is a value using this unit, and y is the corresponding value using the base unit. The elements a and d are optional, and if values are not provided, those parameters are considered to be zero. If values are not provided for both a and d, the formula is equivalent to a fraction with numerator and denominator parameters. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/valueObjects.xsd ================================================ valueObjects.xsd See ISO/DIS 19136 17.5. The elements declared in this Clause build on other GML schema components, in particular gml:AbstractTimeObject, gml:AbstractGeometry, and the following types: gml:MeasureType, gml:MeasureListType, gml:CodeType, gml:CodeOrNilReasonListType, gml:BooleanOrNilReasonListType, gml:IntegerOrNilReasonList. Of particular interest are elements that are the heads of substitution groups, and one named choice group. These are the primary reasons for the value objects schema, since they may act as variables in the definition of content models, such as Observations, when it is desired to permit alternative value types to occur some of which may have complex content such as arrays, geometry and time objects, and where it is useful not to prescribe the actual value type in advance. The members of the groups include quantities, category classifications, boolean, count, temporal and spatial values, and aggregates of these. The value objects are defined in a hierarchy. The following relationships are defined: - Concrete elements gml:Quantity, gml:Category, gml:Count and gml:Boolean are substitutable for the abstract element gml:AbstractScalarValue. - Concrete elements gml:QuantityList, gml:CategoryList, gml:CountList and gml:BooleanList are substitutable for the abstract element gml:AbstractScalarValueList. - Concrete element gml:ValueArray is substitutable for the concrete element gml:CompositeValue. - Abstract elements gml:AbstractScalarValue and gml:AbstractScalarValueList, and concrete elements gml:CompositeValue, gml:ValueExtent, gml:CategoryExtent, gml:CountExtent and gml:QuantityExtent are substitutable for abstract element gml:AbstractValue. - Abstract elements gml:AbstractValue, gml:AbstractTimeObject and gml:AbstractGeometry are all in a choice group named gml:Value, which is used for compositing in gml:CompositeValue and gml:ValueExtent. - Schemas which need values may use the abstract element gml:AbstractValue in a content model in order to permit any of the gml:AbstractScalarValues, gml:AbstractScalarValueLists, gml:CompositeValue or gml:ValueExtent to occur in an instance, or the named group gml:Value to also permit gml:AbstractTimeObjects, gml:AbstractGeometrys. A gml:Category has an optional XML attribute codeSpace, whose value is a URI which identifies a dictionary, codelist or authority for the term. An XML attribute uom (“unit of measure”) is required, whose value is a URI which identifies the definition of a ratio scale or units by which the numeric value shall be multiplied, or an interval or position scale on which the value occurs. gml:AbstractValue is an abstract element which acts as the head of a substitution group which contains gml:AbstractScalarValue, gml:AbstractScalarValueList, gml:CompositeValue and gml:ValueExtent, and (transitively) the elements in their substitution groups. These elements may be used in an application schema as variables, so that in an XML instance document any member of its substitution group may occur. gml:AbstractScalarValue is an abstract element which acts as the head of a substitution group which contains gml:Boolean, gml:Category, gml:Count and gml:Quantity, and (transitively) the elements in their substitution groups. gml:AbstractScalarValueList is an abstract element which acts as the head of a substitution group which contains gml:BooleanList, gml:CategoryList, gml:CountList and gml:QuantityList, and (transitively) the elements in their substitution groups. This is a convenience choice group which unifies generic values defined in this Clause with spatial and temporal objects and the measures described above, so that any of these may be used within aggregate values. Property that refers to, or contains, a Value. Convenience element for general use. Property that refers to, or contains, a Value. Property that contains Values. gml:CompositeValue is an aggregate value built from other values . It contains zero or an arbitrary number of gml:valueComponent elements, and zero or one gml:valueComponents property elements. It may be used for strongly coupled aggregates (vectors, tensors) or for arbitrary collections of values. A Value Array is used for homogeneous arrays of primitive and aggregate values. The member values may be scalars, composites, arrays or lists. ValueArray has the same content model as CompositeValue, but the member values shall be homogeneous. The element declaration contains a Schematron constraint which expresses this restriction precisely. Since the members are homogeneous, the gml:referenceSystem (uom, codeSpace) may be specified on the gml:ValueArray itself and inherited by all the members if desired. ValueArray may not carry both a reference to a codeSpace and a uom All components of shall be of the same type All components of shall be of the same type ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/catalogues.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 04-27-2005 17:16:11 ====== Handcrafted ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/codelistItem.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 03-15-2005 09:14:50 ====== Constraints: - 1) metadataProperty.card = 0 - 2) dictionaryEntry.card = 0 Constraint: codeEntry.type = ML_CodeListDefinition XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/crsItem.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 03-15-2005 09:15:11 ====== XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 03-14-2005 12:00:20 ====== Handcrafted ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/gmx.xsd ================================================  This file was generated from ISO TC/211 UML class diagrams == 03-18-2005 11:12:17 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/gmxUsage.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 04-27-2005 17:15:30 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/uomItem.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 03-15-2005 09:15:02 ====== XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gsr/gsr.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:24:48 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gsr/spatialReferencing.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:24:48 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gss/geometry.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:14:37 ====== The geometry packages (Figure 4) contain the various classes for coordinate geometry. All of these classes through the root class GM_Object inherit an optional association to a coordinate reference system. All direct positions exposed through the interfaces defined in this standard shall be in the coordinate reference system of the geometric object accessed. All elements of a geometric complex, composite, or aggregate shall be associated to the same coordinate reference system. When instances of GM_Object are aggregated in another GM_Object (such as a GM_Aggregate, or GM_Complex) which already has a coordinate reference system specified, then these elements are assumed to be in that same coordinate reference system unless otherwise specified. - The geometry package has several internal packages that separate primitive geometric objects, aggregates and complexes, which have a more elaborate internal structure than simple aggregates. Figure 4 shows the dependencies between the geometry packages as well as a list of classes for each package - Figure 5 shows the basic classes defined in the geometry packages. Any object that inherits the semantics of the GM_Object acts as a set of direct positions. Its behavior will be determined by which direct positions it contains. Objects under GM_Primitive will be open, that is, they will not contain their boundary points; curves will not contain their end points, surfaces will not contain their boundary curves, and solids will not contain their bounding surfaces. Objects under GM_Complex will be closed, that is, they will contain their boundary points. This leads to some apparent ambiguity. A representation of a line as a primitive must reference its end points, but will not contain these points as a set of direct positions. A representation of a line as a complex will also reference its end points, and will contain these points as a set of direct positions. This means that identical digital representations will have slightly different semantics depending on whether they are accessed as primitives or complexes. - This difference of semantics is most striking in the GM_CompositeCurve. Composite curves are used to represent features whose geometry could also be represented as curve primitives. From a cartographic point of view, these two representations are not different. From a topological point of view, they are different. This distinction appears in the inheritance diagram (Figure 5) as an inheritance relationship between GM_CompositeCurve and GM_OrientableCurve. The primary semantics of a GM_CompositeCurve (see 6.6.5) is as a closed GM_Object, but it may also act as an open GM_Object under GM_Primitive operations (see 6.3.10). Interface protocols depending upon the topological details of this object will have to be distinguished as to whether they have been inherited from GM_Primitive or GM_Complex, where the distinction first occurs. Even though these protocols have been inherited from the same operations defined at GM_Object, they will act differently depending upon the branch of the inheritance tree from which they have inherited semantics. Creators of implementation profiles may take this into account and use a proxy mechanism for realization relationships that cause semantic dissonance. Such a procedure will be necessary in object-oriented programming and databases in systems that disallow multiple inheritance or make limiting assumptions about method binding. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gss/gss.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:14:37 ====== This package contains the normative (Geometry and Topology) parts of the model for ISO 19107. This document should be referred to as the official description of the Model. If there are any differences, then ISO 19107 takes precedence. - - This packages also contains example (informative) of applications of 19107. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gts/gts.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:18:09 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gts/temporalObjects.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:18:09 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/ML_gmxCodelists.xml ================================================ ML_gmxCodelists Codelists for description of metadata datasets compliant with ISO/TC 211 19115:2003 and 19139 Listes de codes pour la description de lots de métadonnées conforme ISO TC/211 19115:2003 et 19139 GMX (and imported) namespace 0.0 2005-03-18 English UTF 8 French France UTF 8 identification of when a given event occurred CI_DateTypeCode date identifies when the resource was brought into existence creation creation date identifiant la création de la ressource creation création date identifies when the resource was issued publication publication date identifiant la publication de la ressource publication publication date identifies when the resource was examined or re-examined and imporved or amended revision revision amélioration ou amendement de la ressource revision révision identification de quand un événement s'est produit CI_DateTypeCode function performed by the resource CI_OnLineFunctionCode online instructions for transferring data from one storage device or system to another download Download transfert de la ressource d'un système à un autre download Téléchargement online information about the resource information Information description de la ressource en ligne information Information online instructions for requesting the resource from the provider offlineAccess Off line access information pour requérir la ressource offlineAccess Accès hors ligne online order process for obtening the resource order Order formulaire pour obtenir la ressource order commande en ligne online search interface for seeking out information about the resource search Search interface de recherche d'information sur la ressource search Moteur de recherche Fonctionnalité offerte par la ressource CI_OnLineFunctionCode name of the character coding standard used in the resource MD_CharacterSetCode 16-bit fixed size Universal Character Set, based on ISO/IEC 10646 ucs2 16 bits ISO/IEC 10646 ucs2 32-bit fixed size Universal Character Set, based on ISO/IEC 10646 ucs4 32 bits ISO/IEC 10646 ucs4 7-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf7 7 bits ISO/IEC 10646 utf7 8-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf8 8 bits ISO/IEC 10646 utf8 16-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf16 16 bits ISO/IEC 10646 utf16 ISO/IEC 8859-1, Information technology - 8-bit single byte coded graphic character sets - Part 1 : Latin alphabet No.1 8859part1 ISO/IEC 8859-1, alphabet latin 1 8859part1 ISO/IEC 8859-2, Information technology - 8-bit single byte coded graphic character sets - Part 2 : Latin alphabet No.2 8859part2 ISO/IEC 8859-2, alphabet latin 2 8859part2 ISO/IEC 8859-3, Information technology - 8-bit single byte coded graphic character sets - Part 3 : Latin alphabet No.3 8859part3 ISO/IEC 8859-3, alphabet latin 3 8859part3 ISO/IEC 8859-4, Information technology - 8-bit single byte coded graphic character sets - Part 4 : Latin alphabet No.4 8859part4 ISO/IEC 8859-4, alphabet latin 4 8859part4 ISO/IEC 8859-5, Information technology - 8-bit single byte coded graphic character sets - Part 5 : Latin/Cyrillic alphabet 8859part5 ISO/IEC 8859-5, alphabet latin/cyrillique 8859part5 ISO/IEC 8859-6, Information technology - 8-bit single byte coded graphic character sets - Part 6 : Latin/Arabic alphabet 8859part6 ISO/IEC 8859-6, alphabet latin/arabe 8859part6 ISO/IEC 8859-7, Information technology - 8-bit single byte coded graphic character sets - Part 7 : Latin/Greek alphabet 8859part7 ISO/IEC 8859-7, alphabet latin/grec 8859part7 ISO/IEC 8859-8, Information technology - 8-bit single byte coded graphic character sets - Part 8 : Latin/Hebrew alphabet 8859part8 ISO/IEC 8859-8, alphabet latin/hébreu 8859part8 ISO/IEC 8859-9, Information technology - 8-bit single byte coded graphic character sets - Part 9 : Latin alphabet No.5 8859part9 ISO/IEC 8859-9, alphabet latin 5 8859part9 ISO/IEC 8859-10, Information technology - 8-bit single byte coded graphic character sets - Part 10 : Latin alphabet No.6 8859part10 ISO/IEC 8859-10, alphabet latin 6 8859part10 ISO/IEC 8859-11, Information technology - 8-bit single byte coded graphic character sets - Part 11 : Latin/Thai alphabet 8859part11 ISO/IEC 8859-11, alphabet latin/Thaï 8859part11 ISO/IEC 8859-13, Information technology - 8-bit single byte coded graphic character sets - Part 13 : Latin alphabet No.7 8859part13 ISO/IEC 8859-13, alphabet latin 7 8859part13 ISO/IEC 8859-14, Information technology - 8-bit single byte coded graphic character sets - Part 14 : Latin alphabet No.8 (Celtic) 8859part14 ISO/IEC 8859-14, alphabet latin 8 (celtique) 8859part14 ISO/IEC 8859-15, Information technology - 8-bit single byte coded graphic character sets - Part 15 : Latin alphabet No.9 8859part15 ISO/IEC 8859-15, alphabet latin 9 8859part15 ISO/IEC 8859-16, Information technology - 8-bit single byte coded graphic character sets - Part 16 : Latin alphabet No.10 8859part16 ISO/IEC 8859-16, alphabet latin 10 8859part16 japanese code set used for electronic transmission jis Japonais jis japanese code set used on MS-DOS machines shiftJIS Japonais pour MS-DOS shiftJIS japanese code set used on UNIX based machines eucJP Japonais pour UNIX eucJP United States ASCII code set (ISO 646 US) usAscii ISO 646 US usAscii IBM mainframe code set ebcdic IBM ebcdic Korean code set eucKR Koréen eucKR traditional Chinese code set used in Taiwan, Hong Kong of China and other areas big5 Chinois traditionel (Taiwan, Hong Kong, Chine) big5 simplified Chinese code set GB2312 Chinois simplifié GB2312 Jeu de caractères MD_CharacterSetCode class of information to which the referencing entity applies MD_ScopeCode Information applies to the attribute class attribute Attribute Information qui s’applique à une classe d’attributs attribute Attribut Information applies to the characteristic of a feature attributeType Attribute type Information qui s’applique à la caractéristique d’une entité géographique attributeType Type d’attribut Information applies to the dataset dataset Dataset Information qui s’applique au jeu de données dataset Jeu de données Information applies to the dataset dataset 005 Information applies to the series series Series Information qui s’applique à une série series Série Information applies to non-geographic data nonGeographicDataset Non geographic dataset Information qui s’applique à des données non-géographiques nonGeographicDataset Jeu de données non géographiques Information applies to a feature feature Feature Information qui s’applique à un élément (entité géographique) feature Elément Information applies to a feature type featureType Feature type Information qui s’applique à un type d’élément featureType Type d’élément Information applies to a property type propertyType Property type Information qui s’applique à un type de propriété propertyType Type de propriété Information applies to a tile, a spatial subset of geographic data tile Tile Information qui s’applique à une tuile, un sous-ensemble spatial de données géographiques tile Tuile information sur l'entité sur laquelle les métadonnées s'appliquent MD_ScopeCode Language : ISO 639-2 (3 characters) LanguageCode English eng English Anglais eng Anglais French fra French Français fra Français Langue : ISO 639-2 (3 caractères) LanguageCode Country : ISO 3166-2 (2 characters) Country United Kingdom UK United Kingdom Royaume-Uni UK Royaume-Uni France FR France France FR France Pays : ISO 3166-2 (2 caractères) Country ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/gmxCodelists.xml ================================================ gmxCodelists Codelists for description of metadata datasets compliant with ISO/TC 211 19115:2003 and 19139 GMX (and imported) namespace 0.0 2005-03-18 identification of when a given event occurred CI_DateTypeCode date identifies when the resource was brought into existence creation date identifies when the resource was issued publication date identifies when the resource was examined or re-examined and imporved or amended revision function performed by the resource CI_OnLineFunctionCode online instructions for transferring data from one storage device or system to another download online information about the resource information online instructions for requesting the resource from the provider offlineAccess online order process for obtening the resource order online search interface for seeking out information about the resource search mode in which the data is represented CI_PresentationFormCode digital representation of a primarily textual item (can contain illustrations also) documentDigital representation of a primarily textual item (can contain illustrations also) on paper, photograhic material, or other media imageDigital likeness of natural or man-made features, objects, and activities acquired through the sensing of visual or any other segment of the electromagnetic spectrum by sensors, such as thermal infrared, and high resolution radar and stored in digital format documentHardcopy likeness of natural or man-made features, objects, and activities acquired through the sensing of visual or any other segment of the electromagnetic spectrum by sensors, such as thermal infrared, and high resolution radar and reproduced on paper, photographic material, or other media for use directly by the human user imageHardcopy map represented in raster or vector form mapDigital map printed on paper, photographic material, or other media for use directly by the human user mapHardcopy multi-dimensional digital representation of a feature, process, etc. modelDigital 3-dimensional, physical model modelHardcopy vertical cross-section in digital form profileDigital vertical cross-section printed on paper, etc. profileHardcopy digital representation of facts or figures systematically displayed, especially in columns tableDigital representation of facts or figures systematically displayed, especially in columns, printed onpapers, photographic material, or other media tableHardcopy digital video recording videoDigital video recording on film videoHardcopy function performed by the responsible party CI_RoleCode party that supplies the resource resourceProvider party that accepts accountability and responsability for the data and ensures appropriate care and maintenance of the resource custodian party that owns the resource owner party who uses the resource user party who distributes the resource distributor party who created the resource originator party who can be contacted for acquiring knowledge about or acquisition of the resource pointOfContact key party responsible for gathering information and conducting research principalInvestigator party wha has processed the data in a manner such that the resource has been modified processor party who published the resource publisher party who authored the resource author type or method for evaluating an identified data quality measure DQ_EvaluationMethodTypeCode method of evaluating the quality of a dataset based on inspection of items within the dataset, where all data required is internal to the dataset being evaluated directInternal method of evaluating the quality of a dataset based on inspection of items within the dataset, where reference data external to the dataset being evaluated is required directExternal method of evaluating the quality of a dataset based on external knowledge indirect justification for the correlation of two datasets DS_AssociationTypeCode reference from one dataset to another crossReference reference to a master dataset of which this one is a part largerWorkCitation part of the same structured set of data held in a computer partOfSeamlessDatabase mapping and charting information from which the dataset content originates source part of a set of imagery that when used together, provides three-dimensional images stereoMate type of aggregation activity in which datasets are related DS_InitiativeTypeCode series of organized planned actions campaign accumulation of datasets assembled for a specific purpose collection specific performance of a function or group of functions exercise process designed to find if something is effective or valid experiment search or systematic inquiry investigation specific operation of a data collection system mission device or piece of equipment which detects or records sensor action that is part of a series of actions operation vehicle or other support base that holds a sensor platform method of doing something involving a number of steps process specific planned activity program organized undertaking, research, or development project examination or investigation study piece of work task process of testing to discover or demonstrate something trial code indicating whether grid data is point or area MD_CellGeometryCode each cell represents a point point each cell represents an area area name of the character coding standard used in the resource MD_CharacterSetCode 16-bit fixed size Universal Character Set, based on ISO/IEC 10646 ucs2 32-bit fixed size Universal Character Set, based on ISO/IEC 10646 ucs4 7-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf7 8-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf8 16-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf16 ISO/IEC 8859-1, Information technology - 8-bit single byte coded graphic character sets - Part 1 : Latin alphabet No.1 8859part1 ISO/IEC 8859-2, Information technology - 8-bit single byte coded graphic character sets - Part 2 : Latin alphabet No.2 8859part2 ISO/IEC 8859-3, Information technology - 8-bit single byte coded graphic character sets - Part 3 : Latin alphabet No.3 8859part3 ISO/IEC 8859-4, Information technology - 8-bit single byte coded graphic character sets - Part 4 : Latin alphabet No.4 8859part4 ISO/IEC 8859-5, Information technology - 8-bit single byte coded graphic character sets - Part 5 : Latin/Cyrillic alphabet 8859part5 ISO/IEC 8859-6, Information technology - 8-bit single byte coded graphic character sets - Part 6 : Latin/Arabic alphabet 8859part6 ISO/IEC 8859-7, Information technology - 8-bit single byte coded graphic character sets - Part 7 : Latin/Greek alphabet 8859part7 ISO/IEC 8859-8, Information technology - 8-bit single byte coded graphic character sets - Part 8 : Latin/Hebrew alphabet 8859part8 ISO/IEC 8859-9, Information technology - 8-bit single byte coded graphic character sets - Part 9 : Latin alphabet No.5 8859part9 ISO/IEC 8859-10, Information technology - 8-bit single byte coded graphic character sets - Part 10 : Latin alphabet No.6 8859part10 ISO/IEC 8859-11, Information technology - 8-bit single byte coded graphic character sets - Part 11 : Latin/Thai alphabet 8859part11 ISO/IEC 8859-13, Information technology - 8-bit single byte coded graphic character sets - Part 13 : Latin alphabet No.7 8859part13 ISO/IEC 8859-14, Information technology - 8-bit single byte coded graphic character sets - Part 14 : Latin alphabet No.8 (Celtic) 8859part14 ISO/IEC 8859-15, Information technology - 8-bit single byte coded graphic character sets - Part 15 : Latin alphabet No.9 8859part15 ISO/IEC 8859-16, Information technology - 8-bit single byte coded graphic character sets - Part 16 : Latin alphabet No.10 8859part16 japanese code set used for electronic transmission jis japanese code set used on MS-DOS machines shiftJIS japanese code set used on UNIX based machines eucJP United States ASCII code set (ISO 646 US) usAscii IBM mainframe code set ebcdic Korean code set eucKR traditional Chinese code set used in Taiwan, Hong Kong of China and other areas big5 simplified Chinese code set GB2312 name of the handling restrictions on the dataset MD_ClassificationCode available for general disclosure unclassified not for general disclosure restricted available for someone who can be entrusted with information confidential kept or meant to be kept private, unknown, or hidden from all but a select group of people secret of the highest secrecy topSecret specific type of information represented in the cell MD_CoverageContentTypeCode meaningful numerical representation of a physical parameter that is not the actual value of the physical parameter image code value with no quantitative meaning, used to represent a physical quantity thematicClassification value in physical units of the quantity being measured physicalMeasurement datatype of element or entity MD_DatatypeCode descriptor of a set of objects that share the same attributes, operations, methods, relationships, and behavior class descriptor of a set of objects that share the same attributes, operations, methods, relationships, and behavior codelist data type whose instances form a list of named literal values, not extendable enumeration permissible value for a codelist or enumeration codelistElement class that cannot be directly instantiated abstractClass class that is composed of classes it is connected to by an aggregate relationship aggregateClass subclass that may be substituted for its superclass specifiedClass class with few or no operations whose primary purpose is to hold the abstract state of another class for transmittal, storage, encoding or persistent storage datatypeClass named set of operations that characterize the behavior of an element interfaceClass class describing a selection of one of the specified types unionClass class whose instances are classes metaClass class used for specification of a domain of instances (objects), together with the operations applicable to the objects. A type may have attributes and associations typeClass free text field characterString numerical field integer semantic relationship between two classes that involves connections among their instances association name of the dimension MD_DimensionNameTypeCode ordinate (y) axis row abscissa (x) axis column vertical (z) axis vertical along the direction of motion of the scan point track perpendicular to the direction of motion of the scan point crossTrack scan line of a sensor line element along a scan line sample duration time name of point or vector objects used to locate zero-, one-, two-, or three-dimensional spatial locations in the dataset MD_GeometricObjectTypeCode set of geometric primitives such that their boundaries can be represented as a union of other primitives complex connected set of curves, solids or surfaces composite bounded, 1-dimensional geometric primitive, representing the continuous image of a line curve zero-dimensional geometric primitive, representing a position but not having an extent point bounded, connected 3-dimensional geometric primitive, representing the continuous image of a region of space solid bounded, connected 2-dimensional geometric primitive, representing the continuous image of a region of a plane surface code which indicates conditions which may affect the image MD_ImagingConditionCode portion of the image is blurred blurredImage portion of the image is partially obscured by cloud cover cloud acute angle between the plane of the ecliptic (the plane of the Earth s orbit) and the plane of the celestial equator degradingObliquity portion of the image is partially obscured by fog fog portion of the image is partially obscured by heavy smoke or dust heavySmokeOrDust image was taken at night night image was taken during rainfall rain image was taken during semi-dark conditions -- twilight conditions semiDarkness portion of the image is obscured by shadow shadow portion of the image is obscured by snow snow the absence of collection data of a given point or area caused by the relative location of topographic features which obstruct the collection path between the collector(s) and the subject(s) of interest terrainMasking methods used to group similar keywords MD_KeywordTypeCode keyword identifies a branch of instruction or specialized learning discipline keyword identifies a location place keyword identifies the layer(s) of any deposited substance stratum keyword identifies a time period related to the dataset temporal keyword identifies a particular subject or topic theme frequency with which modifications and deletions are made to the data after it is first produced MD_MaintenanceFrequencyCode data is repeatedly and frequently updated continual data is updated each day daily data is updated on a weekly basis weekly data is updated every two weeks fortnightly data is updated each month monthly data is updated every three months quartely data is updated twice each year biannually data is updated every year annually data is updated as deemed necessary asNeeded data is updated in intervals that are uneven in duration irregular there are no plans to update the data notPlanned frequency of maintenance for the data is not known unknwon method used to write to the medium MD_MediumFormatCode CoPy In / Out (UNIX file format and command) cpio Tape ARchive tar high sierra file system highSierra information processing volume and file structure of CD-ROM iso9660 rock ridge interchange protocol (UNIX) iso9660RockRidge hierarchical file system (Macintosh) iso9660AppleHFS name of the medium MD_MediumNameCode read-only optical disk cdRom digital versatile disk dvd digital versatile disk, read only dvdRom 3,5 inch magnetic disk 3halfInchFloppy 5,25 inch magnetic disk 5quarterInchFloppy 7 track magnetic tape 7trackTape 9 track magnetic tape 9trackType 3480 cartridge tape drive 3480Cartridge 3490 cartridge tape drive 3490Cartridge 3580 cartridge tape drive 3580Cartridge 4 millimetre magnetic tape 4mmCartridgeTape 8 millimetre magnetic tape 8mmCartridgeTape 0,25 inch magnetic tape 1quarterInchCartridgeTape half inch cartridge streaming tape drive digitalLinearTape direct computer linkage onLine linkage through a satellite communication system satellite communication through a telephone network telephoneLink pamphlet or leaflet giving descriptive information hardcopy obligation of the element or entity MD_ObligationCode element is always required mandatory element is not required optional element is required when a specific condition is met conditional point in a pixel corresponding to the Earth location of the pixel MD_PixelOrientationCode point halfway between the lower left and the upper right of the pixel center the corner in the pixel closest to the origin of the SRS; if two are at the same distance from the origin, the one with the smallest x-value lowerLeft next corner counterclockwise from the lower left lowerRight next corner counterclockwise from the lower right upperRight next corner counterclockwise from the upper right upperLeft status of the dataset or progress of a review MD_ProgressCode production of the data has been completed completed data has been stored in an offline storage facility historicalArchive data is no longer relevant obsolete data is continually being updated onGoing fixed date has been established upon or by which the data will be created or updated planned data needs to be generated or updated required data is currently in the process of being created underDevelopment limitation(s) placed upon the access or use of the data MD_RestrictionCode exclusive right to the publication, production, or sale of the rights to a literary, dramatic, musical, or artistic work, or to the use of a commercial print or label, granted by law for a specified period of time to an author, composer, artist, distributor copyright government has granted exclusive right to make, sell, use or license an invention or discovery patent produced or sold information awaiting a patent patentPending a name, symbol, or other device identifying a product, officially registered and legally restricted to the use of the owner or manufacturer trademark formal permission to do something license rights to financial benefit from and control of distribution of non-tangible property that is a result of creativity intellectualPropertyRights withheld from general circulation or disclosure restricted limitation not listed otherRestrictions class of information to which the referencing entity applies MD_ScopeCode information applies to the attribute class attribute information applies to the characteristic of a feature attributeType information applies to the collection hardware class collectionHardware information applies to the collection session collectionSession information applies to the dataset dataset information applies to the series series information applies to non-geographic data nonGeographicDataset information applies to a dimension group dimensionGroup information applies to a feature feature information applies to a feature type featureType information applies to a property type propertyType information applies to a field session fieldSession information applies to a computer program or routine software information applies to a capability which a service provider entity makes available to a service user entity through a set of interfaces that define a behaviour, such as a use case service information applies to a copy or imitation of an existing or hypothetical object model information applies to a tile, a spatial subset of geographic data tile method used to represent geographic information in the dataset MD_SpatialRepresentationTypeCode vector data is used to represent geographic data vector grid data is used to represent geographic data grid textual or tabular data is used to represent geographic data textTable triangulated irregular network tin three-dimensional view formed by the intersecting homologous rays of an overlapping pair of images stereoModel scene from a video recording video high-level geographic data thematic classification to assist in the grouping and search of available geographic data sets. Can be used to group keywords as well. Listed examples are not exhaustive. MD_TopicCategoryCode rearing of animals and/or cultivation of plants. Examples: agriculture, irrigation, aquaculture, plantations, herding, pests and diseases affecting crops and livestock farming flora and/or fauna in natural environment. Examples: wildlife, vegetation, biological sciences, ecology, wilderness, sealife, wetlands, habitat biota legal land descriptions. Examples: political and administrative boundaries boundaries processes and phenomena of the atmosphere. Examples: cloud cover, weather, climate, atmospheric conditions, climate change, precipitation climatologyMeteorologyAtmosphere economic activities, conditions and employment. Examples: production, labour, revenue, commerce, industry, tourism and ecotourism, forestry, fisheries, commercial or subsistence hunting, exploration and exploitation of resources such as minerals, oil and gas economy height above or below sea level. Examples: altitude, bathymetry, digital elevation models, slope, derived products elevation environmental resources, protection and conservation. Examples: environmental pollution, waste storage and treatment, environmental impact assessment, monitoring environmental risk, nature reserves, landscape environment information pertaining to earth sciences. Examples: geophysical features and processes, geology, minerals, sciences dealing with the composition, structure and origin of the earth s rocks, risks of earthquakes, volcanic activity, landslides, gravity information, soils, permafrost, hydrogeology, erosion geoscientificInformation health, health services, human ecology, and safety. Examples: disease and illness, factors affecting health, hygiene, substance abuse, mental and physical health, health services health base maps. Examples: land cover, topographic maps, imagery, unclassified images, annotations imageryBaseMapsEarthCover military bases, structures, activities. Examples: barracks, training grounds, military transportation, information collection intelligenceMilitary inland water features, drainage systems and their characteristics. Examples: rivers and glaciers, salt lakes, water utilization plans, dams, currents, floods, water quality, hydrographic charts inlandWaters positional information and services. Examples: addresses, geodetic networks, control points, postal zones and services, place names location features and characteristics of salt water bodies (excluding inland waters). Examples: tides, tidal waves, coastal information, reefs oceans information used for appropriate actions for future use of the land. Examples: land use maps, zoning maps, cadastral surveys, land ownership planningCadastre characteristics of society and cultures. Examples: settlements, anthropology, archaeology, education, traditional beliefs, manners and customs, demographic data, recreational areas and activities, social impact assessments, crime and justice, census information society man-made construction. Examples: buildings, museums, churches, factories, housing, monuments, shops, towers structure means and aids for conveying persons and/or goods. Examples: roads, airports/airstrips, shipping routes, tunnels, nautical charts, vehicle or vessel location, aeronautical charts, railways transportation energy, water and waste systems and communications infrastructure and services. Examples: hydroelectricity, geothermal, solar and nuclear sources of energy, water purification and distribution, sewage collection and disposal, electricity and gas distribution, data communication, telecommunication, radio, communication networks utilitiesCommunication degree of complexity of the spatial relationships MD_TopologyLevelCode geometry objects without any additional structure which describes topology geometryOnly 1-dimensional topological complex -- commonly called chain-node topology topology1D 1-dimensional topological complex that is planar. (A planar graph is a graph that can be drawn in a plane in such a way that no two edges intersect except at a vertex.) planarGraph 2-dimensional topological complex that is planar. (A 2-dimensional topological complex is commonly called full topology in a cartographic 2D environment.) fullPlanarGraph 1-dimensional topological complex that is isomorphic to a subset of a surface. (A geometric complex is isomorphic to a topological complex if their elements are in a one-to-one, dimensional-and boundry-preserving correspondence to one another.) surfaceGraph 2-dimensional topological complex that is isomorphic to a subset of a surface fullSurfaceGraph 3-dimensional topological complex. (A topological complex is a collection of topological primitives that are closed under the boundary operations.) topology3D complete coverage of a 3D Euclidean coordinate space fullTopology3D topological complex without any specified geometric realisation abstract Extension of MD_ScopeCode for the needs of GMX application schemas and in the context of a transfer MX_ScopeCode information applies to the attribute class attribute information applies to the characteristic of a feature attributeType information applies to the collection hardware class collectionHardware information applies to the collection session collectionSession information applies to the dataset dataset information applies to the series series information applies to non-geographic data nonGeographicDataset information applies to a dimension group dimensionGroup information applies to a feature feature information applies to a feature type featureType information applies to a property type propertyType information applies to a field session fieldSession information applies to a computer program or routine software information applies to a capability which a service provider entity makes available to a service user entity through a set of interfaces that define a behaviour, such as a use case service information applies to a copy or imitation of an existing or hypothetical object model information applies to a tile, a spatial subset of geographic data tile The referencing entity applies to a transfer aggregate which was originally identified as an initiative (DS_Initiative) initiative The referencing entity applies to a transfer aggregate which was originally identified as a stereo mate (DS_StereoMate) stereomate The referencing entity applies to a transfer aggregate which was originally identified as a sensor (DS_Sensor) sensor The referencing entity applies to a transfer aggregate which was originally identified as a platform series (DS_PlatformSeries) platformSeries The referencing entity applies to a transfer aggregate which was originally identified as a sensor series (DS_SensorSeries) sensorSeries The referencing entity applies to a transfer aggregate which was originally identified as a production series (DS_ProductionSeries) productionSeries The referencing entity applies to a transfer aggregate which has no existence outside of the transfer context transferAggregate The referencing entity applies to a transfer aggregate which has an existence outside of the transfer context, but which does not pertains to a specific aggregate type. otherAggregate ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/ML_gmxCrs.xml ================================================ ML_gmxCrs CRS catalogue for description of gmx metadata dataset Catalogue des paramètres géodésiques pour la description de jeux de métadonnées conformes aux schémas gmx GMX (and imported) namespace 0.0 2005-03-29 English UTF 8 French France UTF 8 4326 WGS84G World Geodetic System 1984 World not known 4326 WGS84G WGS 1984 Monde inconnu 6422 ellipsoidal2Ddeg 9901 Geodetic latitude Lat North 9902 Geodetic longitude Lon East 6326 World Geodetic System 1984 not known 7030 WGS 84 6378137 298.2572 8901 Greenwich 0 ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/gmxCrs.xml ================================================ gmxCrs CRS parameters dictionary GMX (and imported) namespace 0.0 2005-03-18 4326 WGS84G World Geodetic System 1984 World: Afghanistan, Albania, Algeria, American Samoa, Andorra, Angola, Anguilla, Antarctica, Antigua and Barbuda, Argentina, Armenia, Aruba, Australia, Austria, Azerbaijan, Bahamas, Bahrain, Bangladesh, Barbados, Belgium, Belgium, Belize, Benin, Bermuda, Bhutan, Bolivia, Bosnia and Herzegowina, Botswana, Bouvet Island, Brazil, British Indian Ocean Territory, British Virgin Islands, Brunei Darussalam, Bulgaria, Burkina Faso, Burundi, Cambodia, Cameroon, Canada, Cape Verde, Cayman Islands, Central African Republic, Chad, Chile, China, Christmas Island, Cocos (Keeling) Islands, Comoros, Congo, Cook Islands, Costa Rica, Côte d'Ivoire (Ivory Coast), Croatia, Cuba, Cyprus, Czech Republic, Denmark, Djibouti, Dominica, Dominican Republic, East Timor, Ecuador, Egypt, El Salvador, Equatorial Guinea, Eritrea, Estonia, Ethiopia, Falkland Islands (Malvinas), Faroe Islands, Fiji, Finland, France, French Guiana, French Polynesia, French Southern Territories, Gabon, Gambia, Georgia, Germany, Ghana, Gibraltar, Greece, Greenland, Grenada, Guadeloupe, Guam, Guatemala, Guinea, Guinea-Bissau, Guyana, Haiti, Heard Island and McDonald Islands, Holy See (Vatican City State), Honduras, China - Hong Kong, Hungary, Iceland, India, Indonesia, Islamic Republic of Iran, Iraq, Ireland, Israel, Italy, Jamaica, Japan, Jordan, Kazakstan, Kenya, Kiribati, Democratic People's Republic of Korea (North Korea), Republic of Korea (South Korea), Kuwait, Kyrgyzstan, Lao People's Democratic Republic (Laos), Latvia, Lebanon, Lesotho, Liberia, Libyan Arab Jamahiriya, Liechtenstein, Lithuania, Luxembourg, China - Macau, The Former Yugoslav Republic of Macedonia, Madagascar, Malawi, Malaysia, Maldives, Mali, Malta, Marshall Islands, Martinique, Mauritania, Mauritius, Mayotte, Mexico, Federated States of Micronesia, Monaco, Mongolia, Montserrat, Morocco, Mozambique, Myanmar (Burma), Namibia, Nauru, Nepal, Netherlands, Netherlands Antilles, New Caledonia, New Zealand, Nicaragua, Niger, Nigeria, Niue, Norfolk Island, Northern Mariana Islands, Norway, Oman, Pakistan, Palau, Panama, Papua New Guinea (PNG), Paraguay, Peru, Philippines, Pitcairn, Poland, Portugal, Puerto Rico, Qatar, Reunion, Romania, Russian Federation, Rwanda, Saint Kitts and Nevis, Saint Lucia, Saint Vincent and the Grenadines, Samoa, San Marino, Sao Tome and Principe, Saudi Arabia, Senegal, Seychelles, Sierra Leone, Singapore, Slovakia (Slovak Republic), Slovenia, Solomon Islands, Somalia, South Africa, South Georgia and the South Sandwich Islands, Spain, Sri Lanka, Saint Helena, Saint Pierre and Miquelon, Sudan, Suriname, Svalbard and Jan Mayen, Swaziland, Sweden, Switzerland, Syrian Arab Republic, Taiwan, Tajikistan, United Republic of Tanzania, Thailand, The Democratic Republic of the Congo (Zaire), Togo, Tokelau, Tonga, Trinidad and Tobago, Tunisia, Turkey, Turkmenistan, Turks and Caicos Islands, Tuvalu, Uganda, Ukraine, United Arab Emirates (UAE), United Kingdom (UK), United States (USA), United States Minor Outlying Islands, Uruguay, Uzbekistan, Vanuatu, Venezuela, Vietnam, US Virgin Islands, Wallis and Futuna, Western Sahara, Yemen, Yugoslavia - Union of Serbia and Montenegro, Zambia, Zimbabwe. not known 32638 UTM38W84 WGS 84 / UTM zone 38N Between 42 and 48 deg East; northern hemisphere. Armenia. Azerbaijan. Djibouti. Eritrea. Ethiopia. Georgia. Islamic Republic of Iran. Iraq. Kazakstan. Kuwait. Russian Federation. Saudi Arabia. Somalia. Tukey. Yemen. not known Ellipsoidal 2D CS. Axes: latitude, longitude. Orientations: north, east. UoM: deg 6422 CS ellipsoidal2D Cartesian 2D CS. Axes: easting, northing (E,N). Orientations: east, north. UoM: m. 4400 Cs cartesian2D 9901 Geodetic latitude Lat North 9902 Geodetic longitude Lon East 9907 Northing N North 9906 Easting E east 6326 World Geodetic System 1984 not known 7030 WGS 84 6378137 298.2572 8901 Greenwich 0 16038 UTM Zone 38 N not known 0 45 0.9996 500000 0 9807 PRCM040 Transverse Mercator Transverse Mercator 2 2 8801 Latitude of natural origin 8802 Longitude of natural origin 8805 Scale factor at natural origin 8806 False Easting 8807 False Northing ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/example/fr-fr.xml ================================================ France-France French FR UTF 8 2005-03-18 création 2006-02-03 révision french translation team auteur Résumé succint du contenu du jeu de données ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/ML_gmxUom.xml ================================================ uom units of measure dictionary compliant with SI definitions dictionnaire d'unités de mesure conforme avec les définitions du Système International (SI) GMX (and imported) namespace 0.0 2005-06-18 English UTF 8 French France UTF 8 The metre is the length of the path travelled by ligth in vaccum during a time interval of 1/299 792 458 of a second metre length m unité de longueur de référence dans le système international, correspond à la distance parcourue par la lumière dans le vide pendant 1/299 792 458 seconde metre mètre longueur Measure of angle equal to Pi/180 radians, widely used in geography degree angle 1.74532925199433E-02 Unité d'angle de référence en géographie égale à Pi/180 radians. degree degré angle Radian is an unit of angle measure. It is defined as the ratio of arc length to the radius of the circle. radian plane angle rad Le radian est une unité de mesaure angulaire définie comme le ratio entre le rayon et la longueur de l'arc. radian radian angle planaire ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/gmxUom.xml ================================================ gmxUom units of measure dictionary compliant with SI definitions ISO/TC 211 GMX (and imported) namespace 0.0 2005-03-18 The metre is the length of the path travelled by ligth in vaccum during a time interval of 1/299 792 458 of a second metre length m Measure of angle equal to Pi/180 radians, widely used in geography degree angle 1.74532925199433E-02 Radian is an unit of angle measure. It is defined as the ratio of arc length to the radius of the circle. radian plane angle rad ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/srv/serviceMetadata.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 10-13-2006 11:14:04 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/srv/serviceModel.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 10-13-2006 11:14:04 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/srv/srv.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 10-13-2006 11:14:05 ====== ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/ReadMe.txt ================================================ ISO(c) ReadMe.txt ------------------------------------------------------------------------------ Geographic Information - Metadata - XML Schema Implementation This XML Schema implementation is composed of the following namespaces: - Geographic Common (GCO) extensible markup language (http://www.isotc211.org/2005/gco) - Geographic MetaData (GMD) extensible markup language (http://www.isotc211.org/2005/gmd) - Geographic Metadata XML (GMX) Schema (http://www.isotc211.org/2005/gmx) - Geographic Spatial Schema (GSS) extensible markup language (http://www.isotc211.org/2005/gss) - Geographic Spatial Referencing (GSR) extensible markup language (http://www.isotc211.org/2005/gsr) - Geographic Temporal Schema (GTS) extensible markup language (http://www.isotc211.org/2005/gts) The most current schemas are available at: http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/ XML resources related to those namespaces are also provided at this location. ------------------------------------------------------------------------------- See X\ReadMe.txt for details of lineage and modification of the package X ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/ReadMe.txt ================================================ ISO(c) GCO schema ReadMe.txt ------------------------------------------------------------------------------ Geographic COmmon (GCO) extensible markup language GCO is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GCO includes all the definitions of http://www.isotc211.org/2005/gco namespace. The root document of this namespace is the file gco.xsd. The most current schemas are available at: http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/ ------------------------------------------------------------------------------- 2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group * Update of readme.txt file and schema annotations * Use of absolute schema locations of imported namespaces * Simplification of the schema location of included XML Schemas * Adoption of W3C Implementation of XLink: - schemaLocation changed to: http://www.w3.org/1999/xlink.xsd - xlink:simpleLink renamed xlink:simpleAttrs * Addition of the version attribute to the schema element. The value of this attribute is expected to be the date of the last release of the XML schemas (e.g. 2012-07-13 for this release) * Include root XML Schema document in all schema documents Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0) 2009-03-16 Marcellin Prudham & Nicolas Lesage * Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136) Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference ISO 19136 which was published 2007-08-23. The major change applied to ISO 19136 is the change of the namespace URI. Previous release of GCO are not compliant with ISO/TS 19139:2007 Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham) 2006-05-04 Marie-Pierre Escher & Nicolas Lesage * First official release of GCO * GCO XML Schema files were generated from ISO/TC 211 UML class diagrams in accordance with ISO/TS 19139:2007. The XML Schema generator is a Rational Rose Plug-in developed by IGN France (nicolas.lesage@ign.fr). ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/basicTypes.xsd ================================================ Geographic COmmon (GCO) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GCO includes all the definitions of http://www.isotc211.org/2005/gco namespace. The root document of this namespace is the file gco.xsd. This basicTypes.xsd schema implements concepts from the "basic types" package of ISO/TS 19103. A TypeName is a LocalName that references either a recordType or object type in some form of schema. The stored value "aName" is the returned value for the "aName()" operation. This is the types name. - For parsing from types (or objects) the parsible name normally uses a "." navigation separator, so that it is of the form [class].[member].[memberOfMember]. ...) A MemberName is a LocalName that references either an attribute slot in a record or recordType or an attribute, operation, or association role in an object instance or type description in some form of schema. The stored value "aName" is the returned value for the "aName()" operation. Use to represent the possible cardinality of a relation. Represented by a set of simple multiplicity ranges. A component of a multiplicity, consisting of an non-negative lower bound, and a potentially infinite upper bound. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gco.xsd ================================================ Geographic COmmon (GCO) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GCO includes all the definitions of http://www.isotc211.org/2005/gco namespace. The root document of this namespace is the file gco.xsd. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gcoBase.xsd ================================================ Geographic COmmon (GCO) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GCO includes all the definitions of http://www.isotc211.org/2005/gco namespace. The root document of this namespace is the file gco.xsd. This gcoBase.xsd schema provides: 1. tools to handle specific objects like "code lists" and "record"; 2. Some XML types representing that do not follow the general encoding rules. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/ReadMe.txt ================================================ ISO(c) GMD schema ReadMe.txt ------------------------------------------------------------------------------ Geographic MetaData (GMD) extensible markup language GMD is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. The most current schemas are available at: http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/ ------------------------------------------------------------------------------- 2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group * Update of readme.txt file and schema annotations * Use of absolute schema locations of imported namespaces * Simplification of the schema location of included XML Schemas * Addition of the version attribute to the schema element. The value of this attribute is expected to be the date of the last release of the XML schemas (e.g. 2012-07-13 for this release) * Include root XML Schema document in all schema documents Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0) 2009-03-16 Marcellin Prudham & Nicolas Lesage * Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136) Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference ISO 19136 which was published 2007-08-23. The major change applied to ISO 19136 is the change of the namespace URI. Previous release of GMD are not compliant with ISO/TS 19139:2007 Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham) 2006-05-04 Marie-Pierre Escher & Nicolas Lesage * First official release of GMD * GMD XML Schema files were generated from ISO/TC 211 UML class diagrams in accordance with ISO/TS 19139:2007. The XML Schema generator is a Rational Rose Plug-in developed by IGN France (http://www.ign.fr). ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/applicationSchema.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This applicationSchema.xsd schema implements the UML conceptual schema defined in A.2.12 of ISO 19115:2003. It contains the implementation of the class MD_ApplicationSchemaInformation. Information about the application schema used to build the dataset ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/citation.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This citation.xsd schema implements the UML conceptual schema defined in A.3.2 of ISO 19115:2003. It contains the implementation of the following classes: CI_ResponsibleParty, CI_Citation, CI_Address, CI_OnlineResource, CI_Contact, CI_Telephone, URL, CI_Date, CI_Series, CI_RoleCode, CI_PresentationFormCode, CI_OnLineFunctionCode, CI_DateTypeCode. Identification of, and means of communication with, person(s) and organisations associated with the dataset Standardized resource reference Location of the responsible individual or organisation Information about online sources from which the dataset, specification, or community profile name and extended metadata elements can be obtained. Information required enabling contact with the responsible person and/or organisation Telephone numbers for contacting the responsible individual or organisation ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/constraints.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This constraints.xsd schema implements the UML conceptual schema defined in A.2.3 of ISO 19115:2003. It contains the implementation of the following classes: MD_Constraints, MD_LegalConstraints, MD_SecurityConstraints, MD_ClassificationCode, MD_RestrictionCode. Restrictions on the access and use of a dataset or metadata Restrictions and legal prerequisites for accessing and using the dataset. Handling restrictions imposed on the dataset because of national security, privacy, or other concerns ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/content.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This content.xsd schema implements the UML conceptual schema defined in ISO 19115:2003, A.2.8. It contains the implementation of the following classes: MD_FeatureCatalogueDescription, MD_CoverageDescription, MD_ImageDescription, MD_ContentInformation, MD_RangeDimension, MD_Band, MD_CoverageContentTypeCode, MD_ImagingConditionCode. Information identifing the feature catalogue Information about the domain of the raster cell Information about an image's suitability for use Set of adjacent wavelengths in the electro-magnetic spectrum with a common characteristic, such as the visible band ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/dataQuality.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This dataQuality.xsd schema implements the UML conceptual schema defined in A.2.4 of ISO 19115:2003. It contains the implementation of the following classes: LI_ProcessStep, LI_Source, LI_Lineage, DQ_ConformanceResult, DQ_QuantitativeResult, DQ_Result, DQ_TemporalValidity, DQ_AccuracyOfATimeMeasurement, DQ_QuantitativeAttributeAccuracy, DQ_NonQuantitativeAttributeAccuracy, DQ_ThematicClassificationCorrectness, DQ_RelativeInternalPositionalAccuracy, DQ_GriddedDataPositionalAccuracy, DQ_AbsoluteExternalPositionalAccuracy, DQ_TopologicalConsistency, DQ_FormatConsistency, DQ_DomainConsistency, DQ_ConceptualConsistency, DQ_CompletenessOmission, DQ_CompletenessCommission, DQ_TemporalAccuracy, DQ_ThematicAccuracy, DQ_PositionalAccuracy, DQ_LogicalConsistency, DQ_Completeness, DQ_Element, DQ_DataQuality. quantitative_result from Quality Procedures - - renamed to remove implied use limitiation. Quantitative_conformance_measure from Quality Procedures. - - Renamed to remove implied use limitation - - OCL - -- result is type specified by valueDomain - result.tupleType = valueDomain ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/distribution.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This distribution.xsd schema implements the UML conceptual schema defined in A.2.10 of ISO 19115:2003. It contains the implementation of the following classes: MD_Medium, MD_DigitalTransferOptions, MD_StandardOrderProcess, MD_Distributor, MD_Distribution, MD_Format, MD_MediumFormatCode, MD_MediumNameCode. Information about the media on which the data can be distributed Technical means and media by which a dataset is obtained from the distributor Common ways in which the dataset may be obtained or received, and related instructions and fee information Information about the distributor Information about the distributor of and options for obtaining the dataset Description of the form of the data to be distributed ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/extent.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This extent.xsd schema implements the UML conceptual schema defined in A.3.1 of ISO 19115:2003 and the associated corrigendum. It contains the implementation of the following classes: EX_TemporalExtent, EX_VerticalExtent, EX_BoundingPolygon, EX_Extent, EX_GeographicExtent, EX_GeographicBoundingBox, EX_SpatialTemporalExtent, EX_GeographicDescription. Time period covered by the content of the dataset Vertical domain of dataset Boundary enclosing the dataset expressed as the closed set of (x,y) coordinates of the polygon (last point replicates first point) Information about spatial, vertical, and temporal extent Geographic area of the dataset Geographic area of the entire dataset referenced to WGS 84 Extent with respect to date and time ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/freeText.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This freeText.xsd schema implements cultural and linguistic adaptability extensions defined in 7.3 of ISO/TS 19139:2007. This extension essentially formalizes the free text concept described in Annex J of ISO 19115:2003. For this reason, and in order to simplify the organization of overall geographic metadata XML schema, this schema has been included as part of the gmd namespace instead of the gmx namespace. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/gmd.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/identification.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This identification.xsd schema implements the UML conceptual schema defined in A.2.2 of ISO 19115:2003. It contains the implementation of the following classes: MD_Identification, MD_BrowseGraphic, MD_DataIdentification, MD_ServiceIdentification, MD_RepresentativeFraction, MD_Usage, MD_Keywords, DS_Association, MD_AggregateInformation, MD_CharacterSetCode, MD_SpatialRepresentationTypeCode, MD_TopicCategoryCode, MD_ProgressCode, MD_KeywordTypeCode, DS_AssociationTypeCode, DS_InitiativeTypeCode, MD_ResolutionType. Basic information about data Graphic that provides an illustration of the dataset (should include a legend for the graphic) See 19119 for further info Brief description of ways in which the dataset is currently used. Keywords, their type and reference source Encapsulates the dataset aggregation information High-level geospatial data thematic classification to assist in the grouping and search of available geospatial datasets ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/maintenance.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This maintenance.xsd schema implements the UML conceptual schema defined in A.2.5 of ISO 19115:2003. It contains the implementation of the following classes: MD_MaintenanceInformation, MD_MaintenanceFrequencyCode, MD_ScopeCode, MD_ScopeDescription. Information about the scope and frequency of updating Description of the class of information covered by the information ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataApplication.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This metadataApplication.xsd schema implements the UML conceptual schema defined in A.2.12 of ISO 19115:2003. It contains the implementation of the class: MD_ApplicationSchemaInformation. Identifiable collection of datasets Identifiable collection of data ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataEntity.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This metadataEntity.xsd schema implements the UML conceptual schema defined in A.2.1 of ISO 19115:2003. It contains the implementation of the class MD_Metadata. Information about the metadata ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataExtension.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This metadataExtension.xsd schema implements the UML conceptual schema defined in A.2.11 of ISO 19115:2003. It contains the implementation of the following classes: MD_ExtendedElementInformation, MD_MetadataExtensionInformation, MD_ObligationCode, MD_DatatypeCode. New metadata element, not found in ISO 19115, which is required to describe geographic data Information describing metadata extensions. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/portrayalCatalogue.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This portrayalCatalogue.xsd schema implements the UML conceptual schema defined in A.2.9 of ISO 19115:2003. It contains the implementation of the class MD_PortrayalCatalogueReference. Information identifing the portrayal catalogue used ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/referenceSystem.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This referenceSystem.xsd schema implements the UML conceptual schema defined in A.2.7 of ISO 19115:2003 and ISO 19115:2003/Cor. 1:2006. It contains the implementation of the following classes: RS_Identifier, MD_ReferenceSystem, MD_Identifier and RS_Reference System. Description of the spatial and temporal reference systems used in the dataset ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/spatialRepresentation.xsd ================================================ Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This portrayalCatalogue.xsd schema implements the UML conceptual schema defined in A.2.6 of ISO 19115:2003. It contains the implementation of the following classes: MD_GridSpatialRepresentation, MD_VectorSpatialRepresentation, MD_SpatialRepresentation, MD_Georeferenceable, MD_Dimension, MD_Georectified, MD_GeometricObjects, MD_TopologyLevelCode, MD_GeometricObjectTypeCode, MD_CellGeometryCode, MD_DimensionNameTypeCode, MD_PixelOrientationCode. Types and numbers of raster spatial objects in the dataset Information about the vector spatial objects in the dataset Digital mechanism used to represent spatial information ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/ReadMe.txt ================================================ ISO(c) GMX schema ReadMe.txt ------------------------------------------------------------------------------ Geographic Metadata XML (GMX) Schema GMX is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. The most current schemas are available at: http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/ ------------------------------------------------------------------------------- 2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group * Update of readme.txt file and schema annotations * Use of absolute schema locations of imported namespaces * Simplification of the schema location of included XML Schemas * Adoption of W3C Implementation of XLink: - schemaLocation changed to: http://www.w3.org/1999/xlink.xsd - xlink:simpleLink renamed xlink:simpleAttrs * Addition of the version attribute to the schema element. The value of this attribute is expected to be the date of the last release of the XML schemas (e.g. 2012-07-13 for this release) * Include root XML Schema document in all schema documents Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0) 2009-03-16 Marcellin Prudham & Nicolas Lesage * Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136) Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference ISO 19136 which was published 2007-08-23. The major change applied to ISO 19136 is the change of the namespace URI. Previous release of GMX are not compliant with ISO/TS 19139:2007 Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham) 2006-05-04 Marie-Pierre Escher & Nicolas Lesage * First official release of GMX * GMX XML Schema files were generated from ISO/TC 211 UML class diagrams in accordance with ISO/TS 19139:2007. The XML Schema generator is a Rational Rose Plug-in developed by IGN France (nicolas.lesage@ign.fr). ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/catalogues.xsd ================================================ Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This catalogues.xsd schema implements the UML conceptual schema defined in 7.4.4.1 of ISO/TS 19139:2007. It contains the implementation of CT_Catalogue, CT_CodelistCatalogue, CT_UomCatalogue and CT_CrsCatalogue. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/codelistItem.xsd ================================================ Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This codelistItem.xsd schema implements the UML conceptual schema defined in 7.4.4.4 of ISO/TS 19139:2007. It contains the implementation of CT_Codelist and CT_CodelistValue. Constraints: - 1) metadataProperty.card = 0 - 2) dictionaryEntry.card = 0 Constraint: codeEntry.type = ML_CodeListDefinition XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/crsItem.xsd ================================================ Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This crsItem.xsd schema implements the UML conceptual schema defined in 7.4.4.3 of ISO/TS 19139:2007. It contains the implementation of CT_CRS, CT_CoordinateSystem, CT_CoordinateSystemAxis, CT_Datum, CT_Ellipsoid, CT_PrimeMeridian, CT_Operation, CT_OperationMethod and CT_OperationParameters. XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/extendedTypes.xsd ================================================ Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This extendedTypes.xsd schema contains the XML definitions of FileName, Anchor and MimeFileType classes. These classes are fully described in 7.2 of ISO/TS 19139:2007. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmx.xsd ================================================ Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmxUsage.xsd ================================================ Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This gmxUsage.xsd schema implements the UML conceptual schema defined in 7.4.1 of ISO/TS 19139:2007. It contains the implementation of the following classes: MX_Dataset, MX_Aggregate, MX_DataFile and MX_ScopeCode. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/uomItem.xsd ================================================ Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This uomItem.xsd schema implements the UML conceptual schema defined in 7.4.4.2 of ISO/TS 19139:2007. It contains the implementation of the UnitDefinition class. XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/ReadMe.txt ================================================ ISO(c) GSR schema ReadMe.txt ------------------------------------------------------------------------------ Geographic Spatial Referencing (GSR) extensible markup language GSR is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSR includes all the definitions of http://www.isotc211.org/2005/gsr namespace. The root document of this namespace is the file gsr.xsd. The most current schemas are available at: http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/ ------------------------------------------------------------------------------- 2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group * Update of readme.txt file and schema annotations * Use of absolute schema locations of imported namespaces * Simplification of the schema location of included XML Schemas * Addition of the version attribute to the schema element. The value of this attribute is expected to be the date of the last release of the XML schemas (e.g. 2012-07-13 for this release) * Include root XML Schema document in all schema documents Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0) 2009-03-16 Marcellin Prudham & Nicolas Lesage * Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136) Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference ISO 19136 which was published 2007-08-23. The major change applied to ISO 19136 is the change of the namespace URI. Previous release of GSR are not compliant with ISO/TS 19139:2007 Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham) 2006-05-04 Marie-Pierre Escher & Nicolas Lesage * First official release of GSR * GSR XML Schema files were generated from ISO/TC 211 UML class diagrams in accordance with ISO/TS 19139:2007. The XML Schema generator is a Rational Rose Plug-in developed by IGN France (http://www.ign.fr). ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/gsr.xsd ================================================ Geographic Spatial Referencing (GSR) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSR includes all the definitions of http://www.isotc211.org/2005/gsr namespace. The root document of this namespace is the file gsr.xsd. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/spatialReferencing.xsd ================================================ Geographic Spatial Referencing (GSR) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSR includes all the definitions of http://www.isotc211.org/2005/gsr namespace. The root document of this namespace is the file gsr.xsd. This spatialReferencing.xsd schema contains the implementation of SC_CRS. The encoding of this class is mapped to an ISO 19136 XML type. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/ReadMe.txt ================================================ ISO(c) GSS schema ReadMe.txt ------------------------------------------------------------------------------ Geographic Spatial Schema (GSS) extensible markup language GSS is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSS includes all the definitions of http://www.isotc211.org/2005/gss namespace. The root document of this namespace is the file gss.xsd. The most current schemas are available at: http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/ ------------------------------------------------------------------------------- 2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group * Update of readme.txt file and schema annotations * Use of absolute schema locations of imported namespaces * Simplification of the schema location of included XML Schemas * Addition of the version attribute to the schema element. The value of this attribute is expected to be the date of the last release of the XML schemas (e.g. 2012-07-13 for this release) * Include root XML Schema document in all schema documents Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0) 2009-03-16 Marcellin Prudham & Nicolas Lesage * Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136) Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference ISO 19136 which was published 2007-08-23. The major change applied to ISO 19136 is the change of the namespace URI. Previous release of GSS are not compliant with ISO/TS 19139:2007 Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham) 2006-05-04 Marie-Pierre Escher & Nicolas Lesage * First official release of GSS * GSS XML Schema files were generated from ISO/TC 211 UML class diagrams in accordance with ISO/TS 19139:2007. The XML Schema generator is a Rational Rose Plug-in developed by IGN France (nicolas.lesage@ign.fr). ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/geometry.xsd ================================================ Geographic Spatial Schema (GSS) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSS includes all the definitions of http://www.isotc211.org/2005/gss namespace. The root document of this namespace is the file gss.xsd. This geometry.xsd schema contains the implementation of GM_Object and GM_Point. The encoding of these classes is mapped to ISO 19136 geometric types. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/gss.xsd ================================================ Geographic Spatial Schema (GSS) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSS includes all the definitions of http://www.isotc211.org/2005/gss namespace. The root document of this namespace is the file gss.xsd. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/ReadMe.txt ================================================ ISO(c) GTS schema ReadMe.txt ------------------------------------------------------------------------------ Geographic Temporal Schema (GTS) extensible markup language GTS is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GTS includes all the definitions of http://www.isotc211.org/2005/gts namespace. The root document of this namespace is the file gts.xsd. The most current schemas are available at: http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/ ------------------------------------------------------------------------------- 2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group * Update of readme.txt file and schema annotations * Use of absolute schema locations of imported namespaces * Simplification of the schema location of included XML Schemas * Addition of the version attribute to the schema element. The value of this attribute is expected to be the date of the last release of the XML schemas (e.g. 2012-07-13 for this release) * Include root XML Schema document in all schema documents Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0) 2009-03-16 Marcellin Prudham & Nicolas Lesage * Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136) Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference ISO 19136 which was published 2007-08-23. The major change applied to ISO 19136 is the change of the namespace URI. Previous release of GTS are not compliant with ISO/TS 19139:2007 Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham) 2006-05-04 Marie-Pierre Escher & Nicolas Lesage * First official release of GTS * GTS XML Schema files were generated from ISO/TC 211 UML class diagrams in accordance with ISO/TS 19139:2007. The XML Schema generator is a Rational Rose Plug-in developed by IGN France (http://www.ign.fr). ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/gts.xsd ================================================ Geographic Temporal Schema (GTS) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GTS includes all the definitions of http://www.isotc211.org/2005/gts namespace. The root document of this namespace is the file gts.xsd. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/temporalObjects.xsd ================================================ Geographic Temporal Schema (GTS) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GTS includes all the definitions of http://www.isotc211.org/2005/gts namespace. The root document of this namespace is the file gts.xsd. The temporalObjects.xsd schema contains the XML implementation of TM_Object, TM_Primitive and TM_PeriodDuration from ISO 19108. The encoding of these classes is mapped to ISO 19136 temporal types and W3C built-in types. ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/ReadMe.txt ================================================ ISO(c) - ISO/TS 19139:2007 resources ------------------------------------------------------------------------------ ISO/TS 19139:2007 resources are XML Files provided with the XML Schema Implementations defined in ISO/TS 19139-2. Those resources are: - Catalogues of Codelist, Units of measure (uom) and Coordinate Reference Systems (CRS) - sample XML ------------------------------------------------------------------------------- 2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group * Update of Readme.txt file * Use of absolute schema locations * Adoption of W3C Implementation of XLink: Validation: XML Files have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0) No history... ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/ML_gmxCodelists.xml ================================================ ML_gmxCodelists Codelists for description of metadata datasets compliant with ISO/TC 211 19115:2003 and 19139 Listes de codes pour la description de lots de métadonnées conforme ISO TC/211 19115:2003 et 19139 GMX (and imported) namespace 0.0 2005-03-18 English UTF 8 French France UTF 8 identification of when a given event occurred CI_DateTypeCode date identifies when the resource was brought into existence creation creation date identifiant la création de la ressource creation création date identifies when the resource was issued publication publication date identifiant la publication de la ressource publication publication date identifies when the resource was examined or re-examined and imporved or amended revision revision amélioration ou amendement de la ressource revision révision identification de quand un événement s'est produit CI_DateTypeCode function performed by the resource CI_OnLineFunctionCode online instructions for transferring data from one storage device or system to another download Download transfert de la ressource d'un système à un autre download Téléchargement online information about the resource information Information description de la ressource en ligne information Information online instructions for requesting the resource from the provider offlineAccess Off line access information pour requérir la ressource offlineAccess Accès hors ligne online order process for obtening the resource order Order formulaire pour obtenir la ressource order commande en ligne online search interface for seeking out information about the resource search Search interface de recherche d'information sur la ressource search Moteur de recherche Fonctionnalité offerte par la ressource CI_OnLineFunctionCode name of the character coding standard used in the resource MD_CharacterSetCode 16-bit fixed size Universal Character Set, based on ISO/IEC 10646 ucs2 16 bits ISO/IEC 10646 ucs2 32-bit fixed size Universal Character Set, based on ISO/IEC 10646 ucs4 32 bits ISO/IEC 10646 ucs4 7-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf7 7 bits ISO/IEC 10646 utf7 8-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf8 8 bits ISO/IEC 10646 utf8 16-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf16 16 bits ISO/IEC 10646 utf16 ISO/IEC 8859-1, Information technology - 8-bit single byte coded graphic character sets - Part 1 : Latin alphabet No.1 8859part1 ISO/IEC 8859-1, alphabet latin 1 8859part1 ISO/IEC 8859-2, Information technology - 8-bit single byte coded graphic character sets - Part 2 : Latin alphabet No.2 8859part2 ISO/IEC 8859-2, alphabet latin 2 8859part2 ISO/IEC 8859-3, Information technology - 8-bit single byte coded graphic character sets - Part 3 : Latin alphabet No.3 8859part3 ISO/IEC 8859-3, alphabet latin 3 8859part3 ISO/IEC 8859-4, Information technology - 8-bit single byte coded graphic character sets - Part 4 : Latin alphabet No.4 8859part4 ISO/IEC 8859-4, alphabet latin 4 8859part4 ISO/IEC 8859-5, Information technology - 8-bit single byte coded graphic character sets - Part 5 : Latin/Cyrillic alphabet 8859part5 ISO/IEC 8859-5, alphabet latin/cyrillique 8859part5 ISO/IEC 8859-6, Information technology - 8-bit single byte coded graphic character sets - Part 6 : Latin/Arabic alphabet 8859part6 ISO/IEC 8859-6, alphabet latin/arabe 8859part6 ISO/IEC 8859-7, Information technology - 8-bit single byte coded graphic character sets - Part 7 : Latin/Greek alphabet 8859part7 ISO/IEC 8859-7, alphabet latin/grec 8859part7 ISO/IEC 8859-8, Information technology - 8-bit single byte coded graphic character sets - Part 8 : Latin/Hebrew alphabet 8859part8 ISO/IEC 8859-8, alphabet latin/hébreu 8859part8 ISO/IEC 8859-9, Information technology - 8-bit single byte coded graphic character sets - Part 9 : Latin alphabet No.5 8859part9 ISO/IEC 8859-9, alphabet latin 5 8859part9 ISO/IEC 8859-10, Information technology - 8-bit single byte coded graphic character sets - Part 10 : Latin alphabet No.6 8859part10 ISO/IEC 8859-10, alphabet latin 6 8859part10 ISO/IEC 8859-11, Information technology - 8-bit single byte coded graphic character sets - Part 11 : Latin/Thai alphabet 8859part11 ISO/IEC 8859-11, alphabet latin/Thaï 8859part11 ISO/IEC 8859-13, Information technology - 8-bit single byte coded graphic character sets - Part 13 : Latin alphabet No.7 8859part13 ISO/IEC 8859-13, alphabet latin 7 8859part13 ISO/IEC 8859-14, Information technology - 8-bit single byte coded graphic character sets - Part 14 : Latin alphabet No.8 (Celtic) 8859part14 ISO/IEC 8859-14, alphabet latin 8 (celtique) 8859part14 ISO/IEC 8859-15, Information technology - 8-bit single byte coded graphic character sets - Part 15 : Latin alphabet No.9 8859part15 ISO/IEC 8859-15, alphabet latin 9 8859part15 ISO/IEC 8859-16, Information technology - 8-bit single byte coded graphic character sets - Part 16 : Latin alphabet No.10 8859part16 ISO/IEC 8859-16, alphabet latin 10 8859part16 japanese code set used for electronic transmission jis Japonais jis japanese code set used on MS-DOS machines shiftJIS Japonais pour MS-DOS shiftJIS japanese code set used on UNIX based machines eucJP Japonais pour UNIX eucJP United States ASCII code set (ISO 646 US) usAscii ISO 646 US usAscii IBM mainframe code set ebcdic IBM ebcdic Korean code set eucKR Koréen eucKR traditional Chinese code set used in Taiwan, Hong Kong of China and other areas big5 Chinois traditionel (Taiwan, Hong Kong, Chine) big5 simplified Chinese code set GB2312 Chinois simplifié GB2312 Jeu de caractères MD_CharacterSetCode class of information to which the referencing entity applies MD_ScopeCode Information applies to the attribute class attribute Attribute Information qui s’applique à une classe d’attributs attribute Attribut Information applies to the characteristic of a feature attributeType Attribute type Information qui s’applique à la caractéristique d’une entité géographique attributeType Type d’attribut Information applies to the dataset dataset Dataset Information qui s’applique au jeu de données dataset Jeu de données Information applies to the dataset dataset 005 Information applies to the series series Series Information qui s’applique à une série series Série Information applies to non-geographic data nonGeographicDataset Non geographic dataset Information qui s’applique à des données non-géographiques nonGeographicDataset Jeu de données non géographiques Information applies to a feature feature Feature Information qui s’applique à un élément (entité géographique) feature Elément Information applies to a feature type featureType Feature type Information qui s’applique à un type d’élément featureType Type d’élément Information applies to a property type propertyType Property type Information qui s’applique à un type de propriété propertyType Type de propriété Information applies to a tile, a spatial subset of geographic data tile Tile Information qui s’applique à une tuile, un sous-ensemble spatial de données géographiques tile Tuile information sur l'entité sur laquelle les métadonnées s'appliquent MD_ScopeCode Language : ISO 639-2 (3 characters) LanguageCode English eng English Anglais eng Anglais French fra French Français fra Français Langue : ISO 639-2 (3 caractères) LanguageCode Country : ISO 3166-2 (2 characters) Country United Kingdom UK United Kingdom Royaume-Uni UK Royaume-Uni France FR France France FR France Pays : ISO 3166-2 (2 caractères) Country ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/gmxCodelists.xml ================================================ gmxCodelists Codelists for description of metadata datasets compliant with ISO/TC 211 19115:2003 and 19139 GMX (and imported) namespace 0.0 2005-03-18 identification of when a given event occurred CI_DateTypeCode date identifies when the resource was brought into existence creation date identifies when the resource was issued publication date identifies when the resource was examined or re-examined and imporved or amended revision function performed by the resource CI_OnLineFunctionCode online instructions for transferring data from one storage device or system to another download online information about the resource information online instructions for requesting the resource from the provider offlineAccess online order process for obtening the resource order online search interface for seeking out information about the resource search mode in which the data is represented CI_PresentationFormCode digital representation of a primarily textual item (can contain illustrations also) documentDigital representation of a primarily textual item (can contain illustrations also) on paper, photograhic material, or other media imageDigital likeness of natural or man-made features, objects, and activities acquired through the sensing of visual or any other segment of the electromagnetic spectrum by sensors, such as thermal infrared, and high resolution radar and stored in digital format documentHardcopy likeness of natural or man-made features, objects, and activities acquired through the sensing of visual or any other segment of the electromagnetic spectrum by sensors, such as thermal infrared, and high resolution radar and reproduced on paper, photographic material, or other media for use directly by the human user imageHardcopy map represented in raster or vector form mapDigital map printed on paper, photographic material, or other media for use directly by the human user mapHardcopy multi-dimensional digital representation of a feature, process, etc. modelDigital 3-dimensional, physical model modelHardcopy vertical cross-section in digital form profileDigital vertical cross-section printed on paper, etc. profileHardcopy digital representation of facts or figures systematically displayed, especially in columns tableDigital representation of facts or figures systematically displayed, especially in columns, printed onpapers, photographic material, or other media tableHardcopy digital video recording videoDigital video recording on film videoHardcopy function performed by the responsible party CI_RoleCode party that supplies the resource resourceProvider party that accepts accountability and responsability for the data and ensures appropriate care and maintenance of the resource custodian party that owns the resource owner party who uses the resource user party who distributes the resource distributor party who created the resource originator party who can be contacted for acquiring knowledge about or acquisition of the resource pointOfContact key party responsible for gathering information and conducting research principalInvestigator party wha has processed the data in a manner such that the resource has been modified processor party who published the resource publisher party who authored the resource author type or method for evaluating an identified data quality measure DQ_EvaluationMethodTypeCode method of evaluating the quality of a dataset based on inspection of items within the dataset, where all data required is internal to the dataset being evaluated directInternal method of evaluating the quality of a dataset based on inspection of items within the dataset, where reference data external to the dataset being evaluated is required directExternal method of evaluating the quality of a dataset based on external knowledge indirect justification for the correlation of two datasets DS_AssociationTypeCode reference from one dataset to another crossReference reference to a master dataset of which this one is a part largerWorkCitation part of the same structured set of data held in a computer partOfSeamlessDatabase mapping and charting information from which the dataset content originates source part of a set of imagery that when used together, provides three-dimensional images stereoMate type of aggregation activity in which datasets are related DS_InitiativeTypeCode series of organized planned actions campaign accumulation of datasets assembled for a specific purpose collection specific performance of a function or group of functions exercise process designed to find if something is effective or valid experiment search or systematic inquiry investigation specific operation of a data collection system mission device or piece of equipment which detects or records sensor action that is part of a series of actions operation vehicle or other support base that holds a sensor platform method of doing something involving a number of steps process specific planned activity program organized undertaking, research, or development project examination or investigation study piece of work task process of testing to discover or demonstrate something trial code indicating whether grid data is point or area MD_CellGeometryCode each cell represents a point point each cell represents an area area name of the character coding standard used in the resource MD_CharacterSetCode 16-bit fixed size Universal Character Set, based on ISO/IEC 10646 ucs2 32-bit fixed size Universal Character Set, based on ISO/IEC 10646 ucs4 7-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf7 8-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf8 16-bit variable size UCS Transfer Format, based on ISO/IEC 10646 utf16 ISO/IEC 8859-1, Information technology - 8-bit single byte coded graphic character sets - Part 1 : Latin alphabet No.1 8859part1 ISO/IEC 8859-2, Information technology - 8-bit single byte coded graphic character sets - Part 2 : Latin alphabet No.2 8859part2 ISO/IEC 8859-3, Information technology - 8-bit single byte coded graphic character sets - Part 3 : Latin alphabet No.3 8859part3 ISO/IEC 8859-4, Information technology - 8-bit single byte coded graphic character sets - Part 4 : Latin alphabet No.4 8859part4 ISO/IEC 8859-5, Information technology - 8-bit single byte coded graphic character sets - Part 5 : Latin/Cyrillic alphabet 8859part5 ISO/IEC 8859-6, Information technology - 8-bit single byte coded graphic character sets - Part 6 : Latin/Arabic alphabet 8859part6 ISO/IEC 8859-7, Information technology - 8-bit single byte coded graphic character sets - Part 7 : Latin/Greek alphabet 8859part7 ISO/IEC 8859-8, Information technology - 8-bit single byte coded graphic character sets - Part 8 : Latin/Hebrew alphabet 8859part8 ISO/IEC 8859-9, Information technology - 8-bit single byte coded graphic character sets - Part 9 : Latin alphabet No.5 8859part9 ISO/IEC 8859-10, Information technology - 8-bit single byte coded graphic character sets - Part 10 : Latin alphabet No.6 8859part10 ISO/IEC 8859-11, Information technology - 8-bit single byte coded graphic character sets - Part 11 : Latin/Thai alphabet 8859part11 ISO/IEC 8859-13, Information technology - 8-bit single byte coded graphic character sets - Part 13 : Latin alphabet No.7 8859part13 ISO/IEC 8859-14, Information technology - 8-bit single byte coded graphic character sets - Part 14 : Latin alphabet No.8 (Celtic) 8859part14 ISO/IEC 8859-15, Information technology - 8-bit single byte coded graphic character sets - Part 15 : Latin alphabet No.9 8859part15 ISO/IEC 8859-16, Information technology - 8-bit single byte coded graphic character sets - Part 16 : Latin alphabet No.10 8859part16 japanese code set used for electronic transmission jis japanese code set used on MS-DOS machines shiftJIS japanese code set used on UNIX based machines eucJP United States ASCII code set (ISO 646 US) usAscii IBM mainframe code set ebcdic Korean code set eucKR traditional Chinese code set used in Taiwan, Hong Kong of China and other areas big5 simplified Chinese code set GB2312 name of the handling restrictions on the dataset MD_ClassificationCode available for general disclosure unclassified not for general disclosure restricted available for someone who can be entrusted with information confidential kept or meant to be kept private, unknown, or hidden from all but a select group of people secret of the highest secrecy topSecret specific type of information represented in the cell MD_CoverageContentTypeCode meaningful numerical representation of a physical parameter that is not the actual value of the physical parameter image code value with no quantitative meaning, used to represent a physical quantity thematicClassification value in physical units of the quantity being measured physicalMeasurement datatype of element or entity MD_DatatypeCode descriptor of a set of objects that share the same attributes, operations, methods, relationships, and behavior class flexible enumeration useful for expressing a long list of values, can be extended codelist data type whose instances form a list of named literal values, not extendable enumeration permissible value for a codelist or enumeration codelistElement class that cannot be directly instantiated abstractClass class that is composed of classes it is connected to by an aggregate relationship aggregateClass subclass that may be substituted for its superclass specifiedClass class with few or no operations whose primary purpose is to hold the abstract state of another class for transmittal, storage, encoding or persistent storage datatypeClass named set of operations that characterize the behavior of an element interfaceClass class describing a selection of one of the specified types unionClass class whose instances are classes metaClass class used for specification of a domain of instances (objects), together with the operations applicable to the objects. A type may have attributes and associations typeClass free text field characterString numerical field integer semantic relationship between two classes that involves connections among their instances association name of the dimension MD_DimensionNameTypeCode ordinate (y) axis row abscissa (x) axis column vertical (z) axis vertical along the direction of motion of the scan point track perpendicular to the direction of motion of the scan point crossTrack scan line of a sensor line element along a scan line sample duration time name of point or vector objects used to locate zero-, one-, two-, or three-dimensional spatial locations in the dataset MD_GeometricObjectTypeCode set of geometric primitives such that their boundaries can be represented as a union of other primitives complex connected set of curves, solids or surfaces composite bounded, 1-dimensional geometric primitive, representing the continuous image of a line curve zero-dimensional geometric primitive, representing a position but not having an extent point bounded, connected 3-dimensional geometric primitive, representing the continuous image of a region of space solid bounded, connected 2-dimensional geometric primitive, representing the continuous image of a region of a plane surface code which indicates conditions which may affect the image MD_ImagingConditionCode portion of the image is blurred blurredImage portion of the image is partially obscured by cloud cover cloud acute angle between the plane of the ecliptic (the plane of the Earth s orbit) and the plane of the celestial equator degradingObliquity portion of the image is partially obscured by fog fog portion of the image is partially obscured by heavy smoke or dust heavySmokeOrDust image was taken at night night image was taken during rainfall rain image was taken during semi-dark conditions -- twilight conditions semiDarkness portion of the image is obscured by shadow shadow portion of the image is obscured by snow snow the absence of collection data of a given point or area caused by the relative location of topographic features which obstruct the collection path between the collector(s) and the subject(s) of interest terrainMasking methods used to group similar keywords MD_KeywordTypeCode keyword identifies a branch of instruction or specialized learning discipline keyword identifies a location place keyword identifies the layer(s) of any deposited substance stratum keyword identifies a time period related to the dataset temporal keyword identifies a particular subject or topic theme frequency with which modifications and deletions are made to the data after it is first produced MD_MaintenanceFrequencyCode data is repeatedly and frequently updated continual data is updated each day daily data is updated on a weekly basis weekly data is updated every two weeks fortnightly data is updated each month monthly data is updated every three months quarterly data is updated twice each year biannually data is updated every year annually data is updated as deemed necessary asNeeded data is updated in intervals that are uneven in duration irregular there are no plans to update the data notPlanned frequency of maintenance for the data is not known unknown method used to write to the medium MD_MediumFormatCode CoPy In / Out (UNIX file format and command) cpio Tape ARchive tar high sierra file system highSierra information processing volume and file structure of CD-ROM iso9660 rock ridge interchange protocol (UNIX) iso9660RockRidge hierarchical file system (Macintosh) iso9660AppleHFS name of the medium MD_MediumNameCode read-only optical disk cdRom digital versatile disk dvd digital versatile disk, read only dvdRom 3,5 inch magnetic disk 3halfInchFloppy 5,25 inch magnetic disk 5quarterInchFloppy 7 track magnetic tape 7trackTape 9 track magnetic tape 9trackType 3480 cartridge tape drive 3480Cartridge 3490 cartridge tape drive 3490Cartridge 3580 cartridge tape drive 3580Cartridge 4 millimetre magnetic tape 4mmCartridgeTape 8 millimetre magnetic tape 8mmCartridgeTape 0,25 inch magnetic tape 1quarterInchCartridgeTape half inch cartridge streaming tape drive digitalLinearTape direct computer linkage onLine linkage through a satellite communication system satellite communication through a telephone network telephoneLink pamphlet or leaflet giving descriptive information hardcopy obligation of the element or entity MD_ObligationCode element is always required mandatory element is not required optional element is required when a specific condition is met conditional point in a pixel corresponding to the Earth location of the pixel MD_PixelOrientationCode point halfway between the lower left and the upper right of the pixel center the corner in the pixel closest to the origin of the SRS; if two are at the same distance from the origin, the one with the smallest x-value lowerLeft next corner counterclockwise from the lower left lowerRight next corner counterclockwise from the lower right upperRight next corner counterclockwise from the upper right upperLeft status of the dataset or progress of a review MD_ProgressCode production of the data has been completed completed data has been stored in an offline storage facility historicalArchive data is no longer relevant obsolete data is continually being updated onGoing fixed date has been established upon or by which the data will be created or updated planned data needs to be generated or updated required data is currently in the process of being created underDevelopment limitation(s) placed upon the access or use of the data MD_RestrictionCode exclusive right to the publication, production, or sale of the rights to a literary, dramatic, musical, or artistic work, or to the use of a commercial print or label, granted by law for a specified period of time to an author, composer, artist, distributor copyright government has granted exclusive right to make, sell, use or license an invention or discovery patent produced or sold information awaiting a patent patentPending a name, symbol, or other device identifying a product, officially registered and legally restricted to the use of the owner or manufacturer trademark formal permission to do something license rights to financial benefit from and control of distribution of non-tangible property that is a result of creativity intellectualPropertyRights withheld from general circulation or disclosure restricted limitation not listed otherRestrictions class of information to which the referencing entity applies MD_ScopeCode information applies to the attribute class attribute information applies to the characteristic of a feature attributeType information applies to the collection hardware class collectionHardware information applies to the collection session collectionSession information applies to the dataset dataset information applies to the series series information applies to non-geographic data nonGeographicDataset information applies to a dimension group dimensionGroup information applies to a feature feature information applies to a feature type featureType information applies to a property type propertyType information applies to a field session fieldSession information applies to a computer program or routine software information applies to a capability which a service provider entity makes available to a service user entity through a set of interfaces that define a behaviour, such as a use case service information applies to a copy or imitation of an existing or hypothetical object model information applies to a tile, a spatial subset of geographic data tile method used to represent geographic information in the dataset MD_SpatialRepresentationTypeCode vector data is used to represent geographic data vector grid data is used to represent geographic data grid textual or tabular data is used to represent geographic data textTable triangulated irregular network tin three-dimensional view formed by the intersecting homologous rays of an overlapping pair of images stereoModel scene from a video recording video high-level geographic data thematic classification to assist in the grouping and search of available geographic data sets. Can be used to group keywords as well. Listed examples are not exhaustive. MD_TopicCategoryCode rearing of animals and/or cultivation of plants. Examples: agriculture, irrigation, aquaculture, plantations, herding, pests and diseases affecting crops and livestock farming flora and/or fauna in natural environment. Examples: wildlife, vegetation, biological sciences, ecology, wilderness, sealife, wetlands, habitat biota legal land descriptions. Examples: political and administrative boundaries boundaries processes and phenomena of the atmosphere. Examples: cloud cover, weather, climate, atmospheric conditions, climate change, precipitation climatologyMeteorologyAtmosphere economic activities, conditions and employment. Examples: production, labour, revenue, commerce, industry, tourism and ecotourism, forestry, fisheries, commercial or subsistence hunting, exploration and exploitation of resources such as minerals, oil and gas economy height above or below sea level. Examples: altitude, bathymetry, digital elevation models, slope, derived products elevation environmental resources, protection and conservation. Examples: environmental pollution, waste storage and treatment, environmental impact assessment, monitoring environmental risk, nature reserves, landscape environment information pertaining to earth sciences. Examples: geophysical features and processes, geology, minerals, sciences dealing with the composition, structure and origin of the earth s rocks, risks of earthquakes, volcanic activity, landslides, gravity information, soils, permafrost, hydrogeology, erosion geoscientificInformation health, health services, human ecology, and safety. Examples: disease and illness, factors affecting health, hygiene, substance abuse, mental and physical health, health services health base maps. Examples: land cover, topographic maps, imagery, unclassified images, annotations imageryBaseMapsEarthCover military bases, structures, activities. Examples: barracks, training grounds, military transportation, information collection intelligenceMilitary inland water features, drainage systems and their characteristics. Examples: rivers and glaciers, salt lakes, water utilization plans, dams, currents, floods, water quality, hydrographic charts inlandWaters positional information and services. Examples: addresses, geodetic networks, control points, postal zones and services, place names location features and characteristics of salt water bodies (excluding inland waters). Examples: tides, tidal waves, coastal information, reefs oceans information used for appropriate actions for future use of the land. Examples: land use maps, zoning maps, cadastral surveys, land ownership planningCadastre characteristics of society and cultures. Examples: settlements, anthropology, archaeology, education, traditional beliefs, manners and customs, demographic data, recreational areas and activities, social impact assessments, crime and justice, census information society man-made construction. Examples: buildings, museums, churches, factories, housing, monuments, shops, towers structure means and aids for conveying persons and/or goods. Examples: roads, airports/airstrips, shipping routes, tunnels, nautical charts, vehicle or vessel location, aeronautical charts, railways transportation energy, water and waste systems and communications infrastructure and services. Examples: hydroelectricity, geothermal, solar and nuclear sources of energy, water purification and distribution, sewage collection and disposal, electricity and gas distribution, data communication, telecommunication, radio, communication networks utilitiesCommunication degree of complexity of the spatial relationships MD_TopologyLevelCode geometry objects without any additional structure which describes topology geometryOnly 1-dimensional topological complex -- commonly called chain-node topology topology1D 1-dimensional topological complex that is planar. (A planar graph is a graph that can be drawn in a plane in such a way that no two edges intersect except at a vertex.) planarGraph 2-dimensional topological complex that is planar. (A 2-dimensional topological complex is commonly called full topology in a cartographic 2D environment.) fullPlanarGraph 1-dimensional topological complex that is isomorphic to a subset of a surface. (A geometric complex is isomorphic to a topological complex if their elements are in a one-to-one, dimensional-and boundry-preserving correspondence to one another.) surfaceGraph 2-dimensional topological complex that is isomorphic to a subset of a surface fullSurfaceGraph 3-dimensional topological complex. (A topological complex is a collection of topological primitives that are closed under the boundary operations.) topology3D complete coverage of a 3D Euclidean coordinate space fullTopology3D topological complex without any specified geometric realisation abstract Extension of MD_ScopeCode for the needs of GMX application schemas and in the context of a transfer MX_ScopeCode information applies to the attribute class attribute information applies to the characteristic of a feature attributeType information applies to the collection hardware class collectionHardware information applies to the collection session collectionSession information applies to the dataset dataset information applies to the series series information applies to non-geographic data nonGeographicDataset information applies to a dimension group dimensionGroup information applies to a feature feature information applies to a feature type featureType information applies to a property type propertyType information applies to a field session fieldSession information applies to a computer program or routine software information applies to a capability which a service provider entity makes available to a service user entity through a set of interfaces that define a behaviour, such as a use case service information applies to a copy or imitation of an existing or hypothetical object model information applies to a tile, a spatial subset of geographic data tile The referencing entity applies to a transfer aggregate which was originally identified as an initiative (DS_Initiative) initiative The referencing entity applies to a transfer aggregate which was originally identified as a stereo mate (DS_StereoMate) stereomate The referencing entity applies to a transfer aggregate which was originally identified as a sensor (DS_Sensor) sensor The referencing entity applies to a transfer aggregate which was originally identified as a platform series (DS_PlatformSeries) platformSeries The referencing entity applies to a transfer aggregate which was originally identified as a sensor series (DS_SensorSeries) sensorSeries The referencing entity applies to a transfer aggregate which was originally identified as a production series (DS_ProductionSeries) productionSeries The referencing entity applies to a transfer aggregate which has no existence outside of the transfer context transferAggregate The referencing entity applies to a transfer aggregate which has an existence outside of the transfer context, but which does not pertains to a specific aggregate type. otherAggregate ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/tcCodelists.xml ================================================ tcCodelists Codelists used in the type catalogue schema Type catalogues 0.1 2007-06-14 specifies aggregation semantics: specifies whether the value of each property is a single value ("noAggregation") which is the default case or if a single property instance has an aggregate value in which case the value specifies the aggregation type ("bag", "set", "sequence"). Note that this value is independent from the cardinality. TC_AggregationType single value - no aggregation (default) noAggregation aggregation semantics: bag bag aggregation semantics: set set aggregation semantics: sequence (ordered bag) sequence ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/crs/ML_gmxCrs.xml ================================================ ML_gmxCrs CRS catalogue for description of gmx metadata dataset Catalogue des paramètres géodésiques pour la description de jeux de métadonnées conformes aux schémas gmx GMX (and imported) namespace 0.0 2005-03-29 English UTF 8 French France UTF 8 4326 WGS84G World Geodetic System 1984 World not known 4326 WGS84G WGS 1984 Monde inconnu 6422 ellipsoidal2Ddeg 9901 Geodetic latitude Lat North 9902 Geodetic longitude Lon East 6326 World Geodetic System 1984 not known 7030 WGS 84 6378137 298.2572 8901 Greenwich 0 ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/crs/gmxCrs.xml ================================================ gmxCrs CRS parameters dictionary GMX (and imported) namespace 0.0 2005-03-18 4326 WGS84G World Geodetic System 1984 World: Afghanistan, Albania, Algeria, American Samoa, Andorra, Angola, Anguilla, Antarctica, Antigua and Barbuda, Argentina, Armenia, Aruba, Australia, Austria, Azerbaijan, Bahamas, Bahrain, Bangladesh, Barbados, Belgium, Belgium, Belize, Benin, Bermuda, Bhutan, Bolivia, Bosnia and Herzegowina, Botswana, Bouvet Island, Brazil, British Indian Ocean Territory, British Virgin Islands, Brunei Darussalam, Bulgaria, Burkina Faso, Burundi, Cambodia, Cameroon, Canada, Cape Verde, Cayman Islands, Central African Republic, Chad, Chile, China, Christmas Island, Cocos (Keeling) Islands, Comoros, Congo, Cook Islands, Costa Rica, Côte d'Ivoire (Ivory Coast), Croatia, Cuba, Cyprus, Czech Republic, Denmark, Djibouti, Dominica, Dominican Republic, East Timor, Ecuador, Egypt, El Salvador, Equatorial Guinea, Eritrea, Estonia, Ethiopia, Falkland Islands (Malvinas), Faroe Islands, Fiji, Finland, France, French Guiana, French Polynesia, French Southern Territories, Gabon, Gambia, Georgia, Germany, Ghana, Gibraltar, Greece, Greenland, Grenada, Guadeloupe, Guam, Guatemala, Guinea, Guinea-Bissau, Guyana, Haiti, Heard Island and McDonald Islands, Holy See (Vatican City State), Honduras, China - Hong Kong, Hungary, Iceland, India, Indonesia, Islamic Republic of Iran, Iraq, Ireland, Israel, Italy, Jamaica, Japan, Jordan, Kazakstan, Kenya, Kiribati, Democratic People's Republic of Korea (North Korea), Republic of Korea (South Korea), Kuwait, Kyrgyzstan, Lao People's Democratic Republic (Laos), Latvia, Lebanon, Lesotho, Liberia, Libyan Arab Jamahiriya, Liechtenstein, Lithuania, Luxembourg, China - Macau, The Former Yugoslav Republic of Macedonia, Madagascar, Malawi, Malaysia, Maldives, Mali, Malta, Marshall Islands, Martinique, Mauritania, Mauritius, Mayotte, Mexico, Federated States of Micronesia, Monaco, Mongolia, Montserrat, Morocco, Mozambique, Myanmar (Burma), Namibia, Nauru, Nepal, Netherlands, Netherlands Antilles, New Caledonia, New Zealand, Nicaragua, Niger, Nigeria, Niue, Norfolk Island, Northern Mariana Islands, Norway, Oman, Pakistan, Palau, Panama, Papua New Guinea (PNG), Paraguay, Peru, Philippines, Pitcairn, Poland, Portugal, Puerto Rico, Qatar, Reunion, Romania, Russian Federation, Rwanda, Saint Kitts and Nevis, Saint Lucia, Saint Vincent and the Grenadines, Samoa, San Marino, Sao Tome and Principe, Saudi Arabia, Senegal, Seychelles, Sierra Leone, Singapore, Slovakia (Slovak Republic), Slovenia, Solomon Islands, Somalia, South Africa, South Georgia and the South Sandwich Islands, Spain, Sri Lanka, Saint Helena, Saint Pierre and Miquelon, Sudan, Suriname, Svalbard and Jan Mayen, Swaziland, Sweden, Switzerland, Syrian Arab Republic, Taiwan, Tajikistan, United Republic of Tanzania, Thailand, The Democratic Republic of the Congo (Zaire), Togo, Tokelau, Tonga, Trinidad and Tobago, Tunisia, Turkey, Turkmenistan, Turks and Caicos Islands, Tuvalu, Uganda, Ukraine, United Arab Emirates (UAE), United Kingdom (UK), United States (USA), United States Minor Outlying Islands, Uruguay, Uzbekistan, Vanuatu, Venezuela, Vietnam, US Virgin Islands, Wallis and Futuna, Western Sahara, Yemen, Yugoslavia - Union of Serbia and Montenegro, Zambia, Zimbabwe. not known 32638 UTM38W84 WGS 84 / UTM zone 38N Between 42 and 48 deg East; northern hemisphere. Armenia. Azerbaijan. Djibouti. Eritrea. Ethiopia. Georgia. Islamic Republic of Iran. Iraq. Kazakstan. Kuwait. Russian Federation. Saudi Arabia. Somalia. Tukey. Yemen. not known Ellipsoidal 2D CS. Axes: latitude, longitude. Orientations: north, east. UoM: deg 6422 CS ellipsoidal2D Cartesian 2D CS. Axes: easting, northing (E,N). Orientations: east, north. UoM: m. 4400 Cs cartesian2D 9901 Geodetic latitude Lat North 9902 Geodetic longitude Lon East 9907 Northing N North 9906 Easting E east 6326 World Geodetic System 1984 not known 7030 WGS 84 6378137 298.2572 8901 Greenwich 0 16038 UTM Zone 38 N not known 0 45 0.9996 500000 0 9807 PRCM040 Transverse Mercator Transverse Mercator 2 2 8801 Latitude of natural origin 8802 Longitude of natural origin 8805 Scale factor at natural origin 8806 False Easting 8807 False Northing ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/example/fr-fr.xml ================================================ France-France French FR UTF 8 2005-03-18 création 2006-02-03 révision french translation team auteur Résumé succint du contenu du jeu de données ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/uom/ML_gmxUom.xml ================================================ uom units of measure dictionary compliant with SI definitions dictionnaire d'unités de mesure conforme avec les définitions du Système International (SI) GMX (and imported) namespace 0.0 2005-06-18 English UTF 8 French France UTF 8 The metre is the length of the path travelled by ligth in vaccum during a time interval of 1/299 792 458 of a second metre length m unité de longueur de référence dans le système international, correspond à la distance parcourue par la lumière dans le vide pendant 1/299 792 458 seconde metre mètre longueur Measure of angle equal to Pi/180 radians, widely used in geography degree angle 1.74532925199433E-02 Unité d'angle de référence en géographie égale à Pi/180 radians. degree degré angle Radian is an unit of angle measure. It is defined as the ratio of arc length to the radius of the circle. radian plane angle rad Le radian est une unité de mesaure angulaire définie comme le ratio entre le rayon et la longueur de l'arc. radian radian angle planaire ================================================ FILE: pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/uom/gmxUom.xml ================================================ gmxUom units of measure dictionary compliant with SI definitions ISO/TC 211 GMX (and imported) namespace 0.0 2005-03-18 The metre is the length of the path travelled by ligth in vaccum during a time interval of 1/299 792 458 of a second metre length m Measure of angle equal to Pi/180 radians, widely used in geography degree angle 1.74532925199433E-02 Radian is an unit of angle measure. It is defined as the ratio of arc length to the radius of the circle. radian plane angle rad ================================================ FILE: pycsw/plugins/profiles/ebrim/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/plugins/profiles/ebrim/docs/ebrim.rst ================================================ .. _ebrim: CSW-ebRIM Registry Service - Part 1: ebRIM profile of CSW --------------------------------------------------------- Overview ^^^^^^^^ The CSW-ebRIM Registry Service is a profile of CSW 2.0.2 which enables discovery of geospatial metadata following the ebXML information model. Configuration ^^^^^^^^^^^^^ No extra configuration is required. Querying ^^^^^^^^ * **typename**: ``rim:RegistryObject`` * **outputschema**: ``urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0`` Enabling ebRIM Support ^^^^^^^^^^^^^^^^^^^^^^ To enable ebRIM support, add ``ebrim`` to ``profiles`` as specified in :ref:`configuration`. Testing ^^^^^^^ A testing interface is available in ``tests/index.html`` which contains tests specific to ebRIM to demonstrate functionality. See :ref:`tests` for more information. ================================================ FILE: pycsw/plugins/profiles/ebrim/ebrim.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import os from pycsw.core.etree import etree from pycsw.core import util from pycsw.ogc.csw.csw2 import write_boundingbox from pycsw.plugins.profiles import profile class EBRIM(profile.Profile): ''' EBRim class ''' def __init__(self, model, namespaces, context): self.context = context self.namespaces = { 'ebrim': 'http://www.opengis.net/cat/wrs/1.0', 'rim': 'urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0', 'wrs': 'http://www.opengis.net/cat/wrs/1.0' } self.repository = { 'rim:RegistryObject': { 'outputschema': 'urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0', 'queryables': {}, 'mappings': { 'csw:Record': { # map APISO queryables to DC queryables 'apiso:Title': 'dc:title', 'apiso:Creator': 'dc:creator', 'apiso:Subject': 'dc:subject', 'apiso:Abstract': 'dct:abstract', 'apiso:Publisher': 'dc:publisher', 'apiso:Contributor': 'dc:contributor', 'apiso:Modified': 'dct:modified', #'apiso:Date': 'dc:date', 'apiso:Type': 'dc:type', 'apiso:Format': 'dc:format', 'apiso:Language': 'dc:language', 'apiso:Relation': 'dc:relation', 'apiso:AccessConstraints': 'dc:rights', } } } } profile.Profile.__init__(self, name='ebrim', version='1.0.1', title='ebRIM profile of CSW', url='http://portal.opengeospatial.org/files/?artifact_id=31137', namespace=self.namespaces['rim'], typename='rim:RegistryObject', outputschema=self.namespaces['rim'], prefixes=['rim'], model=model, core_namespaces=namespaces, added_namespaces=self.namespaces, repository=self.repository['rim:RegistryObject']) def extend_core(self, model, namespaces, config): ''' Extend core configuration ''' self.ogc_schemas_base = config['server'].get('ogc_schemas_base') def check_parameters(self, kvp): '''Check for Language parameter in GetCapabilities request''' return None def get_extendedcapabilities(self): ''' Add child to ows:OperationsMetadata Element ''' return None def get_schemacomponents(self): ''' Return schema components as lxml.etree.Element list ''' node = etree.Element( util.nspath_eval('csw:SchemaComponent', self.context.namespaces), schemaLanguage='XMLSCHEMA', targetNamespace=self.namespace) schema_file = os.path.join(self.context.pycsw_home, 'plugins', 'profiles', 'ebrim', 'schemas', 'ogc', 'csw', '2.0.2', 'profiles', 'ebrim', '1.0', 'csw-ebrim.xsd') schema = etree.parse(schema_file, self.context.parser).getroot() node.append(schema) return [node] def check_getdomain(self, kvp): '''Perform extra profile specific checks in the GetDomain request''' return None def write_record(self, result, esn, outputschema, queryables): ''' Return csw:SearchResults child as lxml.etree.Element ''' identifier = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Identifier']) typename = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Typename']) if esn == 'full' and typename == 'rim:RegistryObject': # dump record as is and exit return etree.fromstring(util.getqattr(result, queryables['pycsw:XML']['dbcol']), self.context.parser) node = etree.Element(util.nspath_eval('rim:ExtrinsicObject', self.namespaces)) node.attrib[util.nspath_eval('xsi:schemaLocation', self.context.namespaces)] = \ '%s %s/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd' % (self.namespaces['wrs'], self.ogc_schemas_base) node.attrib['id'] = identifier node.attrib['lid'] = identifier node.attrib['objectType'] = str(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Type'])) node.attrib['status'] = 'urn:oasis:names:tc:ebxml-regrep:StatusType:Submitted' etree.SubElement(node, util.nspath_eval('rim:VersionInfo', self.namespaces), versionName='') if esn in ['summary', 'full']: etree.SubElement(node, util.nspath_eval('rim:ExternalIdentifier', self.namespaces), value=identifier, identificationScheme='foo', registryObject=str(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Relation'])), id=identifier) name = etree.SubElement(node, util.nspath_eval('rim:Name', self.namespaces)) etree.SubElement(name, util.nspath_eval('rim:LocalizedString', self.namespaces), value=str(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Title']))) description = etree.SubElement(node, util.nspath_eval('rim:Description', self.namespaces)) etree.SubElement(description, util.nspath_eval('rim:LocalizedString', self.namespaces), value=str(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Abstract']))) val = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:BoundingBox']) bboxel = write_boundingbox(val, self.context.namespaces) if bboxel is not None: bboxslot = etree.SubElement(node, util.nspath_eval('rim:Slot', self.namespaces), slotType='urn:ogc:def:dataType:ISO-19107:2003:GM_Envelope') valuelist = etree.SubElement(bboxslot, util.nspath_eval('rim:ValueList', self.namespaces)) value = etree.SubElement(valuelist, util.nspath_eval('rim:Value', self.namespaces)) value.append(bboxel) rkeywords = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Keywords']) if rkeywords is not None: subjectslot = etree.SubElement(node, util.nspath_eval('rim:Slot', self.namespaces), name='http://purl.org/dc/elements/1.1/subject') valuelist = etree.SubElement(subjectslot, util.nspath_eval('rim:ValueList', self.namespaces)) for keyword in rkeywords.split(','): etree.SubElement(valuelist, util.nspath_eval('rim:Value', self.namespaces)).text = keyword return node ================================================ FILE: pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim-iri.xsd ================================================ This schema defines content models for HTTP request messages that may be serialized into the query string portion of the URI or into the message body in accord with the WSDL HTTP binding rules for the IRI style. The schemas defined in the base specifications do not adhere to the rules for the IRI style and thus cannot be used for this purpose. See OGC 05-008c1, cl. 7.2.1. See OGC 07-006r1, cl. 10.9.2 See OGC 07-006r1, cl. 10.8.2. Some optional CSW parameters have been elided. Matching items are returned as rim:RegistryObject elements that include the "summary" element set. See OGC 07-110r2, cl. 12.2. Invokes a predefined query. See OGC 07-110r2, cl. 16.1 Examples: "2.0.35", "1.1.0,1.1.1" Examples: "OperationsMetadata", "application/xml,text/html" ================================================ FILE: pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd ================================================ rim:Value not allowed in this context: expected wrs:AnyValue. Schema for CSW-ebRIM catalogue profile (OGC 07-110r3). A general record identifier, expressed as an absolute URI that maps to the rim:RegistryObject/@id attribute. It substitutes for the ogc:_Id element in an OGC filter expression. Extends rim:ExtrinsicObjectType to add the following: 1. MTOM/XOP based attachment support. 2. XLink based reference to a part in a multipart/related message structure. NOTE: This content model is planned for RegRep 4.0. Allows complex slot values. Incorporates the attributes defined for use in simple XLink elements. ================================================ FILE: pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/wsdl/1.1/csw-ebrim-binding.wsdl ================================================ WSDL 1.1 binding descriptions for the CSW-ebRIM catalogue application profile. ================================================ FILE: pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/wsdl/1.1/csw-ebrim-interface.wsdl ================================================ WSDL 1.1 interface descriptions for the CSW-ebRIM catalogue application profile. This schema declares message elements for GET requests or POST requests encoded as content type "application/x-www-form-urlencoded" (i.e., KVP-style encoding). 1. Parameter names and values are escaped. Space characters are replaced by '+', and then reserved characters are percent-encoded as described in RFC 3986, section 2.2. 2. the parameter name is separated from the value by the EQUALS SIGN character and name/value pairs are separated from each other by the AMPERSAND character. If multiple values are allowed they are separated using the COMMA character. Examples: "2.0.35", "1.1.0,1.1.1" Examples: "OperationsMetadata", "application/xml,text/html" Uses the POST method with the "application/xml" serialization format. ================================================ FILE: pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/wsdl/1.1/csw-ebrim-service.wsdl ================================================ WSDL 1.1 service descriptions for the CSW-ebRIM catalogue application profile. This is meant to be a template and does not specify an actual service. ================================================ FILE: pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/wsdl/2.0/csw-ebrim-interface.wsdl ================================================ W3C WSDL interface descriptions for the CSW-ebRIM 1.0 catalogue service. This document shall be imported by all instance-specific service descriptions. The body of the request message is invalid or not well formed. The response status code is 400 and the OGC exception code is "InvalidRequest". Unsupported functionality--the request cannot be processed. The response status code is 501 and the OGC exception code is "NotImplemented". Request OGC service description (mandatory). Alternative GetCapabilities request that supplies an XML message body (optional). Main search and retrieval facility (mandatory). Alternative GetRecords request using the IRI style (optional). Retrieve representations of one or more registry objects by identifier (mandatory). Alternative GetRecordById request that supplies an XML message body (optional). Includes discovery operations specific to CSW-ebRIM implementations. Retrieve a repository item described by an ExtrinsicObject (mandatory). The response body contains the actual repository item. Invoke a predefined query (mandatory). At least one of the registration operations must be implemented. The body of the request message is invalid or not well formed. The response status code is 400 and the OGC exception code is "InvalidRequest". Unsupported functionality--the request cannot be processed. The response status code is 501 and the OGC exception code is "NotImplemented". The requested transaction could not be completed for some reason other than a validation error. The response status code is 500 and the OGC exception code is "TransactionFailed". The HTTP SOAP Transmission Optimization Feature is required to handle requests containing MIME multipart/related entities with repository items. See http://www.w3.org/TR/soap12-mtom/. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/plugins/profiles/iso19115p3/iso19115p3.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Author: Vincent Fazio # # Copyright (c) 2023 CSIRO Australia # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import os import json from pycsw.core import config, util from pycsw.core.etree import etree from pycsw.plugins.profiles import profile CODELIST = 'http://standards.iso.org/iso/19115/resources/Codelist/cat/codelists.xml' class ISO19115p3(profile.Profile): """ ISO19115p3 class represents the profile for input and output of ISO 19115 Part 3 XML """ def __init__(self, model, namespaces, context): """ :param model: model :param namespaces: namespaces :param context: context """ self.context = context self.namespaces = { "mdb":"http://standards.iso.org/iso/19115/-3/mdb/2.0", "cat":"http://standards.iso.org/iso/19115/-3/cat/1.0", "gfc":"http://standards.iso.org/iso/19110/gfc/1.1", "cit":"http://standards.iso.org/iso/19115/-3/cit/2.0", "gcx":"http://standards.iso.org/iso/19115/-3/gcx/1.0", "gex":"http://standards.iso.org/iso/19115/-3/gex/1.0", "lan":"http://standards.iso.org/iso/19115/-3/lan/1.0", "srv":"http://standards.iso.org/iso/19115/-3/srv/2.1", "mas":"http://standards.iso.org/iso/19115/-3/mas/1.0", "mcc":"http://standards.iso.org/iso/19115/-3/mcc/1.0", "mco":"http://standards.iso.org/iso/19115/-3/mco/1.0", "mda":"http://standards.iso.org/iso/19115/-3/mda/1.0", "mds":"http://standards.iso.org/iso/19115/-3/mds/2.0", "mdt":"http://standards.iso.org/iso/19115/-3/mdt/2.0", "mex":"http://standards.iso.org/iso/19115/-3/mex/1.0", "mmi":"http://standards.iso.org/iso/19115/-3/mmi/1.0", "mpc":"http://standards.iso.org/iso/19115/-3/mpc/1.0", "mrc":"http://standards.iso.org/iso/19115/-3/mrc/2.0", "mrd":"http://standards.iso.org/iso/19115/-3/mrd/1.0", "mri":"http://standards.iso.org/iso/19115/-3/mri/1.0", "mrl":"http://standards.iso.org/iso/19115/-3/mrl/2.0", "mrs":"http://standards.iso.org/iso/19115/-3/mrs/1.0", "msr":"http://standards.iso.org/iso/19115/-3/msr/2.0", "mdq":"http://standards.iso.org/iso/19157/-2/mdq/1.0", "mac":"http://standards.iso.org/iso/19115/-3/mac/2.0", "gco":"http://standards.iso.org/iso/19115/-3/gco/1.0", "gml":"http://www.opengis.net/gml", "xlink":"http://www.w3.org/1999/xlink", "xsi":"http://www.w3.org/2001/XMLSchema-instance" } self.inspire_namespaces = { } self.repository = { 'mdb:MD_Metadata': { 'outputschema': 'http://standards.iso.org/iso/19115/-3/mdb/2.0', 'queryables': { 'SupportedISO19115p3Queryables': { 'mdb:Subject': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:topicCategory/mri:MD_TopicCategoryCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:Keywords']}, 'mdb:Title': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:citation/cit:CI_Citation/cit:title/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Title']}, 'mdb:Abstract': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:abstract/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Abstract']}, 'mdb:Edition': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:citation/cit:CI_Citation/cit:edition/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Edition']}, 'mdb:Format': {'xpath': 'mdb:distributionInfo/mrd:MD_Distribution/mrd:distributionFormat/mrd:MD_Format/mrd:formatSpecificationCitation/cit:CI_Citation/cit:title/gcx:Anchor', 'dbcol': self.context.md_core_model['mappings']['pycsw:Format']}, 'mdb:Identifier': {'xpath': 'mdb:metadataIdentifier/mcc:MD_Identifier/mcc:code/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Identifier']}, 'mdb:Modified': {'xpath': 'mdb:MD_Metadata/mdb:dateInfo/cit:CI_Date[cit:dateType/cit:CI_DateTypeCode="lastUpdate"]/cit:date/gco:DateTime', 'dbcol': self.context.md_core_model['mappings']['pycsw:Modified']}, 'mdb:Type': {'xpath': 'mdb:metadataScope/mdb:MD_MetadataScope/mdb:resourceScope/mcc:MD_ScopeCode/@codeListValue', 'dbcol': self.context.md_core_model['mappings']['pycsw:Type']}, # NB: Placeholder only 'mdb:BoundingBox': {'xpath': 'mdb:BoundingBox', 'dbcol': self.context.md_core_model['mappings']['pycsw:BoundingBox']}, 'mdb:VertExtentMin': {'xpath': 'gex:EX_VerticalExtent/gex:minimumValue/gco:Real', 'dbcol': self.context.md_core_model['mappings']['pycsw:VertExtentMin']}, 'mdb:VertExtentMax': {'xpath': 'gex:EX_VerticalExtent/gex:maximumValue/gco:Real', 'dbcol': self.context.md_core_model['mappings']['pycsw:VertExtentMax']}, 'mdb:CRS': {'xpath': '''concat("urn:ogc:def:crs:", "mdb:referenceSystemInfo/mrs:MD_ReferenceSystem/mrs:referenceSystemIdentifier/mcc:MD_Identifier/mcc:codeSpace/gco:CharacterString", ":", "mdb:referenceSystemInfo/mrs:MD_ReferenceSystem/mrs:referenceSystemIdentifier/mcc:MD_Identifier/mcc:version/gco:CharacterString", ":", "mdb:referenceSystemInfo/mrs:MD_ReferenceSystem/mrs:referenceSystemIdentifier/mcc:MD_Identifier/mcc:code/gco:CharacterString")''', 'dbcol': self.context.md_core_model['mappings']['pycsw:CRS']}, 'mdb:AlternateTitle': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:citation/cit:CI_Citation/cit:title/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:AlternateTitle']}, 'mdb:RevisionDate': {'xpath': 'mdb:dateInfo/cit:CI_Date[cit:dateType/cit:CI_DateTypeCode/@codeListValue="revision"]/cit:date/gco:DateTime', 'dbcol': self.context.md_core_model['mappings']['pycsw:RevisionDate']}, 'mdb:CreationDate': {'xpath': 'mdb:dateInfo/cit:CI_Date[cit:dateType/cit:CI_DateTypeCode/@codeListValue="creation"]/cit:date/gco:DateTime', 'dbcol': self.context.md_core_model['mappings']['pycsw:CreationDate']}, 'mdb:PublicationDate': {'xpath': 'mdb:dateInfo/cit:CI_Date[cit:dateType/cit:CI_DateTypeCode/@codeListValue="publication"]/cit:date/gco:DateTime', 'dbcol': self.context.md_core_model['mappings']['pycsw:PublicationDate']}, 'mdb:OrganisationName': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:pointOfContact/cit:CI_Responsibility/cit:party/cit:CI_Organisation/cit:name/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OrganizationName']}, 'mdb:HasSecurityConstraints': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:resourceConstraints/mco:MD_SecurityConstraints', 'dbcol': self.context.md_core_model['mappings']['pycsw:SecurityConstraints']}, 'mdb:Language': {'xpath': 'mdb:defaultLocale/lan:PT_Locale/lan:language/lan:LanguageCode|mdb:defaultLocale/lan:PT_Locale/lan:language/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Language']}, 'mdb:ParentIdentifier': {'xpath': 'mdb:parentMetadata/cit:CI_Citation/cit:identifier/mcc:MD_Identifier/mcc:code/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:ParentIdentifier']}, 'mdb:KeywordType': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:descriptiveKeywords/mri:MD_Keywords/mri:type/mri:MD_KeywordTypeCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:KeywordType']}, 'mdb:TopicCategory': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:topicCategory/mri:MD_TopicCategoryCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:TopicCategory']}, 'mdb:ResourceLanguage': {'xpath': 'mdb:defaultLocale/lan:PT_Locale/lan:language/lan:LanguageCode/@codeListValue', 'dbcol': self.context.md_core_model['mappings']['pycsw:ResourceLanguage']}, 'mdb:GeographicDescriptionCode': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:extent/gex:EX_Extent/gex:geographicElement/gex:EX_GeographicDescription/gex:geographicIdentifier/mcc:MD_Identifier/mcc:code/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:GeographicDescriptionCode']}, 'mdb:Denominator': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:spatialResolution/mri:MD_Resolution/mri:equivalentScale/mri:MD_RepresentativeFraction/mri:denominator/gco:Integer', 'dbcol': self.context.md_core_model['mappings']['pycsw:Denominator']}, 'mdb:DistanceValue': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:spatialResolution/mri:MD_Resolution/mri:distance/gco:Distance', 'dbcol': self.context.md_core_model['mappings']['pycsw:DistanceValue']}, 'mdb:DistanceUOM': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:spatialResolution/mri:MD_Resolution/mri:distance/gco:Distance/@uom', 'dbcol': self.context.md_core_model['mappings']['pycsw:DistanceUOM']}, 'mdb:TempExtent_begin': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:extent/gex:EX_Extent/gex:temporalElement/gex:EX_TemporalExtent/mri:extent/gml:TimePeriod/gml:beginPosition', 'dbcol': self.context.md_core_model['mappings']['pycsw:TempExtent_begin']}, 'mdb:TempExtent_end': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:extent/gex:EX_Extent/gex:temporalElement/gex:EX_TemporalExtent/mri:extent/gml:TimePeriod/gml:endPosition', 'dbcol': self.context.md_core_model['mappings']['pycsw:TempExtent_end']}, 'mdb:AnyText': {'xpath': '//', 'dbcol': self.context.md_core_model['mappings']['pycsw:AnyText']}, 'mdb:ServiceType': {'xpath': 'mdb:identificationInfo/srv:SV_ServiceIdentification/srv:serviceType/gco:LocalName', 'dbcol': self.context.md_core_model['mappings']['pycsw:ServiceType']}, 'mdb:ServiceTypeVersion': {'xpath': 'mdb:identificationInfo/srv:SV_ServiceIdentification/srv:serviceTypeVersion/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:ServiceTypeVersion']}, 'mdb:Operation': {'xpath': 'mdb:identificationInfo/srv:SV_ServiceIdentification/srv:containsOperations/srv:SV_OperationMetadata/srv:operationName/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Operation']}, 'mdb:CouplingType': {'xpath': 'mdb:identificationInfo/srv:SV_ServiceIdentification/srv:couplingType/srv:SV_CouplingType', 'dbcol': self.context.md_core_model['mappings']['pycsw:CouplingType']}, 'mdb:OperatesOn': {'xpath': 'mdb:identificationInfo/srv:SV_ServiceIdentification/srv:operatesOn/mri:MD_DataIdentification/mri:citation/cit:CI_Citation/cit:identifier/mcc:MD_Identifier/mcc:code/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OperatesOn']}, 'mdb:OperatesOnIdentifier': {'xpath': 'mdb:identificationInfo/srv:SV_ServiceIdentification/srv:coupledResource/srv:SV_CoupledResource/srv:identifier/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OperatesOnIdentifier']}, 'mdb:OperatesOnName': {'xpath': 'mdb:identificationInfo/srv:SV_ServiceIdentification/srv:coupledResource/srv:SV_CoupledResource/srv:operationName/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OperatesOnName']}, }, 'AdditionalISO19115p3Queryables': { 'mdb:Degree': {'xpath': 'mdb:dataQualityInfo/mdq:DQ_DataQuality/mdq:report/mdq:DQ_DomainConsistency/mdq:result/mdq:DQ_ConformanceResult/mdq:pass/gco:Boolean', 'dbcol': self.context.md_core_model['mappings']['pycsw:Degree']}, 'mdb:AccessConstraints': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:resourceConstraints/mco:MD_LegalConstraints/mco:accessConstraints/mco:MD_RestrictionCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:AccessConstraints']}, 'mdb:OtherConstraints': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:resourceConstraints/mco:MD_LegalConstraints/mco:otherConstraints/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:OtherConstraints']}, 'mdb:Classification': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:resourceConstraints/mco:MD_LegalConstraints/mco:accessConstraints/mco:MD_ClassificationCode/@codeListValue', 'dbcol': self.context.md_core_model['mappings']['pycsw:Classification']}, 'mdb:ConditionApplyingToAccessAndUse': {'xpath': 'mdb:metadataConstraints/mco:MD_LegalConstraints/mco:useLimitation/gco:CharacterString|mdb:identificationInfo/mri:MD_DataIdentification/mri:resourceConstraints/mco:MD_LegalConstraints/mco:useLimitation/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:ConditionApplyingToAccessAndUse']}, 'mdb:Lineage': {'xpath': 'mdb:dataQualityInfo/mdq:DQ_DataQuality/mrl:lineage/mrl:LI_Lineage/mrl:statement/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Lineage']}, 'mdb:ResponsiblePartyRole': {'xpath': 'mdb:contact/cit:CI_Responsiblility/cit:role/cit:CI_RoleCode', 'dbcol': self.context.md_core_model['mappings']['pycsw:ResponsiblePartyRole']}, 'mdb:SpecificationTitle': {'xpath': 'mdb:dataQualityInfo/mdq:DQ_DataQuality/mdq:report/mdq:DQ_DomainConsistency/mdq:result/mdq:DQ_ConformanceResult/mdq:specification/cit:CI_Citation/cit:title/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:SpecificationTitle']}, 'mdb:SpecificationDate': {'xpath': 'mdb:dataQualityInfo/mdq:DQ_DataQuality/mdq:report/mdq:DQ_DomainConsistency/mdq:result/mdq:DQ_ConformanceResult/mdq:secification/cit:CI_Citation/cit:date/cit:CI_Date/cit:date/gco:Date', 'dbcol': self.context.md_core_model['mappings']['pycsw:SpecificationDate']}, 'mdb:SpecificationDateType': {'xpath': 'mdb:dataQualityInfo/mdq:DQ_DataQuality/mdq:report/mdq:DQ_DomainConsistency/mdq:result/mdq:DQ_ConformanceResult/mdq:specification/cit:CI_Citation/cit:date/cit:CI_Date/cit:dateType/cit:CI_DateTypeCode/@codeListValue', 'dbcol': self.context.md_core_model['mappings']['pycsw:SpecificationDateType']}, 'mdb:Creator': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:citation/cit:CI_Citation/cit:citedResponsibleParty/cit:CI_Responsibility/cit:role/cit:CI_RoleCode[text()="creator"]', 'dbcol': self.context.md_core_model['mappings']['pycsw:Creator']}, 'mdb:Publisher': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:citation/cit:CI_Citation/cit:citedResponsibleParty/cit:CI_Responsibility/cit:role/cit:CI_RoleCode[text()="publisher"]', 'dbcol': self.context.md_core_model['mappings']['pycsw:Publisher']}, 'mdb:Contributor': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:citation/cit:CI_Citation/cit:citedResponsibleParty/cit:CI_Responsibility/cit:role/cit:CI_RoleCode[text()="contributor"]', 'dbcol': self.context.md_core_model['mappings']['pycsw:Contributor']}, 'mdb:Relation': {'xpath': 'mdb:identificationInfo/mri:MD_DataIdentification/mri:aggregationInfo', 'dbcol': self.context.md_core_model['mappings']['pycsw:Relation']}, # 19115-2 'mdb:Platform': {'xpath': 'mdb:acquisitionInfo/mac:MI_AcquisitionInformation/mac:platform/mac:MI_Platform/mac:identifier', 'dbcol': self.context.md_core_model['mappings']['pycsw:Platform']}, 'mdb:Instrument': {'xpath': 'mdb:acquisitionInfo/mac:MI_AcquisitionInformation/mac:platform/mac:MI_Platform/mac:instrument/mac:MI_Instrument/mac:identifier', 'dbcol': self.context.md_core_model['mappings']['pycsw:Instrument']}, 'mdb:SensorType': {'xpath': 'mdb:acquisitionInfo/mac:MI_AcquisitionInformation/mac:platform/mac:MI_Platform/mac:instrument/mac:MI_Instrument/mac:type', 'dbcol': self.context.md_core_model['mappings']['pycsw:SensorType']}, 'mdb:CloudCover': {'xpath': 'mdb:contentInfo/mrc:MD_ImageDescription/mrc:cloudCoverPercentage', 'dbcol': self.context.md_core_model['mappings']['pycsw:CloudCover']}, 'mdb:Bands': {'xpath': 'mdb:contentInfo/mrc:MD_ImageDescription/mrc:attributeGroup/mrc:MD_AttributeGroup/mrc:attribute/mrc:MD_Band/mrc:sequenceIdentifier/gco:MemberName/gco:aName/gco:CharacterString', 'dbcol': self.context.md_core_model['mappings']['pycsw:Bands']}, } }, 'mappings': { 'csw:Record': { # map MDB queryables to DC queryables 'mdb:Title': 'dc:title', 'mdb:Creator': 'dc:creator', 'mdb:Subject': 'dc:subject', 'mdb:Abstract': 'dct:abstract', 'mdb:Publisher': 'dc:publisher', 'mdb:Contributor': 'dc:contributor', 'mdb:Modified': 'dct:modified', 'mdb:PublicationDate': 'dc:date', 'mdb:Type': 'dc:type', 'mdb:Format': 'dc:format', 'mdb:Language': 'dc:language', 'mdb:Relation': 'dc:relation', 'mdb:AccessConstraints': 'dc:rights', } } } } profile.Profile.__init__(self, name='mdb', version='1.0.0', title='ISO 19115-3 XML Metadata', url='https://www.iso.org/standard/32579.html', namespace=self.namespaces['mdb'], typename='mdb:MD_Metadata', outputschema=self.namespaces['mdb'], prefixes=['mdb'], model=model, core_namespaces=namespaces, added_namespaces=self.namespaces, repository=self.repository['mdb:MD_Metadata']) def extend_core(self, model, namespaces, config): """ Extend core configuration :param model: """ # update harvest resource types with WMS, since WMS is not a typename, if 'Harvest' in model['operations']: model['operations']['Harvest']['parameters']['ResourceType']['values'].append('https://schemas.isotc211.org/19115/-3/mdb/2.0/') self.inspire_config = None server_cfg = config.get('server', {}) self.ogc_schemas_base = server_cfg.get('ogc_schemas_base', 'http://schemas.opengis.net') self.url = server_cfg.get('url', 'http://localhost/pycsw/csw.py') def check_parameters(self, kvp): """ Check for Language parameter in GetCapabilities request Kept for backwards compatibility """ return None def get_extendedcapabilities(self): """ Get extended capabilities Kept for backwards compatibility """ return None def get_schemacomponents(self): """ Return schema components as lxml.etree.Element list """ node1 = etree.Element( util.nspath_eval('csw:SchemaComponent', self.context.namespaces), schemaLanguage='XMLSCHEMA', targetNamespace=self.namespace, parentSchema='mdb.xsd') # Copied from: https://github.com/geonetwork/core-geonetwork/tree/main/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/schema/standards.iso.org/19115/-3/mdb/2.0 schema_file = os.path.join(self.context.pycsw_home, 'plugins', 'profiles', 'iso19115p3', 'schemas', 'ogc', 'iso', 'iso19115-3', 'mdb', '2.0', 'mdb.xsd') schema = etree.parse(schema_file, self.context.parser).getroot() node1.append(schema) node2 = etree.Element( util.nspath_eval('csw:SchemaComponent', self.context.namespaces), schemaLanguage='XMLSCHEMA', targetNamespace=self.namespace, parentSchema='mdb.xsd') schema_file = os.path.join(self.context.pycsw_home, 'plugins', 'profiles', 'iso19115p3', 'schemas', 'ogc', 'iso', 'iso19115-3', 'srv', '2.1', 'serviceInformation.xsd') schema = etree.parse(schema_file, self.context.parser).getroot() node2.append(schema) return [node1, node2] def check_getdomain(self, kvp): """ Perform extra profile specific checks in the GetDomain request Kept for backwards compatibility """ return None def write_record(self, result, esn, outputschema, queryables, caps=None): """ Return csw:SearchResults child as etree.Element :param result: results from repository query (to be written out) :param esn: CSW element set name parameter :param outputschema: CSW outputschema :param queryables: database column mapping for our 'mdb:XXXX' :param caps: optional information object gathered from GetCapabilities response """ typename = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Typename']) is_mdb_anyway = False xml_blob = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:XML']) #xml_blob_decoded = bytes.fromhex(xml_blob[2:]).decode('utf-8') if isinstance(xml_blob, bytes): iso_string = b'' else: iso_string = '' if caps is None and xml_blob is not None and xml_blob.startswith(iso_string): is_mdb_anyway = True if (esn == 'full' and (typename == 'mdb:MD_Metadata' or is_mdb_anyway)): # dump record as is and exit return etree.fromstring(xml_blob, self.context.parser) node = etree.Element(util.nspath_eval('mdb:MD_Metadata', self.namespaces), nsmap=self.namespaces) node.attrib[util.nspath_eval('xsi:schemaLocation', self.context.namespaces)] = \ f"{self.namespace} {self.ogc_schemas_base}/csw/2.0.2/csw.xsd" # identifier idval = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Identifier']) meta_identifier = etree.SubElement(node, util.nspath_eval('mdb:metadataIdentifier', self.namespaces)) md_identifier = etree.SubElement(meta_identifier, util.nspath_eval('mcc:MD_Identifier', self.namespaces)) code = etree.SubElement(md_identifier, util.nspath_eval('mcc:code', self.namespaces)) etree.SubElement(code, util.nspath_eval('gco:CharacterString', self.namespaces)).text = idval if esn in ['summary', 'full']: # Language must use a code, so preferentially prefer to use 'mdb:ResourceLanguage' which maps to 'gmd:MD_LanguageTypeCode' in older ISO XML standard try: val = util.getqattr(result, queryables['mdb:ResourceLanguage']['dbcol']) except Exception as e: LOGGER.error(f"{queryables=}") LOGGER.error("exc=", e) if val is None: val = util.getqattr(result, queryables['mdb:Language']['dbcol']) lang_code = build_path(node,['mdb:defaultLocale', 'lan:PT_Locale', 'lan:language', 'lan:LanguageCode'], self.namespaces) lang_code.set('codeListValue', val) lang_code.set('codeList', 'http://www.loc.gov/standards/iso639-2/') # hierarchyLevel mtype = util.getqattr(result, queryables['mdb:Type']['dbcol']) or None if mtype is not None: if mtype == 'http://purl.org/dc/dcmitype/Dataset': mtype = 'dataset' md_scope = etree.SubElement(node, util.nspath_eval('mdb:metadataScope', self.namespaces)) md_metascope = etree.SubElement(md_scope, util.nspath_eval('mdb:MD_MetadataScope', self.namespaces)) res_scope = etree.SubElement(md_metascope, util.nspath_eval('mdb:resourceScope', self.namespaces)) res_scope.append(write_codelist_element('mcc:MD_ScopeCode', mtype, self.namespaces)) if esn in ['summary', 'full']: # Contact ci_resp = build_path(node, ['mdb:contact', 'cit:CI_Responsibility'], self.namespaces) ci_org = build_path(ci_resp, ['cit:party', 'cit:CI_Organisation'], self.namespaces) # If 'GetCapability' information is supplied if caps is not None: ci_contact = build_path(ci_resp, ['cit:contactInfo', 'cit:CI_Contact'], self.namespaces) # Name of individual within an organisation if hasattr(caps.provider.contact, 'name'): path = ['cit:individual', 'cit:CI_Individual', 'cit:name', 'gco:CharacterString'] ind_name = build_path(ci_org, path, self.namespaces) ind_name.text = caps.provider.contact.name # Name of organisation if hasattr(caps.provider.contact, 'organization'): if caps.provider.contact.organization is not None: org_val = caps.provider.contact.organization else: org_val = caps.provider.name path = ['cit:name', 'gco:CharacterString'] org_name = build_path(ci_org, path, self.namespaces) org_name.text = org_val # Position of individual within organisation if hasattr(caps.provider.contact, 'position'): path = ['cit:party', 'cit:CI_Organisation', 'cit:positionName', 'cit:CI_Individual', 'cit:individual', 'gco:characterString'] pos_name = build_path(ci_resp, path, self.namespaces) pos_name.text = caps.provider.contact.position # Phone number and fax of individual within an organisation if hasattr(caps.provider.contact, 'phone'): self._write_contact_phone(ci_contact, caps.provider.contact.phone) if hasattr(caps.provider.contact, 'fax'): self._write_contact_fax(ci_contact, caps.provider.contact.fax) # Address of organisation self._write_contact_address(ci_resp, ci_contact, **vars(caps.provider.contact)) # URL of organisation or individual contact_url = None if hasattr(caps.provider, 'url'): contact_url = caps.provider.url if hasattr(caps.provider.contact, 'url') and caps.provider.contact.url is not None: contact_url = caps.provider.contact.url if contact_url is not None: path = ['cit:onlineResource', 'cit:CI_OnlineResource', 'cit:linkage', 'gco:characterString'] url = build_path(ci_contact, path, self.namespaces) url.text = contact_url # Role if hasattr(caps.provider.contact, 'role'): role = build_path(ci_resp, ['cit:role', 'cit:CI_RoleCode'], self.namespaces) role_val = caps.provider.contact.role if role_val is None: role_val = 'pointOfContact' role.set("codeList", f'{CODELIST}#CI_RoleCode') role.set("codeListValue", role_val) else: # If 'GetCapability' information is not supplied ... # Name of organisation org_val = util.getqattr(result, queryables['mdb:OrganisationName']['dbcol']) if org_val: path = ['cit:name', 'gco:CharacterString'] org_name = build_path(ci_org, path, self.namespaces) org_name.text = org_val # Get address, phone etc. from contacts cjson = util.getqattr(result,self.context.md_core_model['mappings']['pycsw:Contacts']) if cjson not in [None, '', 'null']: try: for contact in json.loads(cjson): path = ['cit:individual', 'cit:CI_Individual'] ci_individ = build_path(ci_org, path, self.namespaces) # Name and position of individual within organisation if contact.get('name', None) != None: path = ['cit:name', 'gco:CharacterString'] name = build_path(ci_individ, path, self.namespaces) name.text = contact.get('name') if contact.get('position', None) != None: path = ['cit:positionName', 'gco:CharacterString'] position = build_path(ci_individ, path, self.namespaces) position.text = contact.get('position') # Contact information ci_contact = build_path(ci_individ, ['cit:contactInfo', 'cit:CI_Contact'], self.namespaces) if contact.get('phone', None) != None: self._write_contact_phone(ci_contact, contact.get('phone')) if contact.get('fax', None) != None: self._write_contact_fax(ci_contact, contact.get('fax')) # Organisation address self._write_contact_address(ci_resp, ci_contact, **contact) except Exception as err: LOGGER.error(f"failed to parse contacts json of {cjson}: {err}") # Creation date for record val = util.getqattr(result, queryables['mdb:Modified']['dbcol']) date = build_path(node, ['mdb:dateInfo'], self.namespaces) ci_date = self._write_date(val, 'creation') date.append(ci_date) metadatastandardname = 'ISO 19115-1:2014' if mtype == 'service': metadatastandardname = 'ISO19119:2016' # Metadata standard name and version path = ['mdb:metadataStandard', 'cit:CI_Citation', 'cit:title', 'gco:CharacterString'] standard_name = build_path(node, path, self.namespaces) standard_name.text = metadatastandardname # Title title_val = util.getqattr(result, queryables['mdb:Title']['dbcol']) or '' identification = etree.SubElement(node, util.nspath_eval('mdb:identificationInfo', self.namespaces)) if mtype == 'service': res_tagname = 'srv:SV_ServiceIdentification' else: res_tagname = 'mri:MD_DataIdentification' resident = etree.SubElement(identification, util.nspath_eval(res_tagname, self.namespaces), id=idval) ci_citation = build_path(resident, ['mri:citation', 'cit:CI_Citation'], self.namespaces) title = build_path(ci_citation, ['cit:title', 'gco:CharacterString'], self.namespaces) title.text = title_val # Edition edition_val = util.getqattr(result, queryables['mdb:Edition']['dbcol']) if edition_val is not None: edition = build_path(ci_citation, ['cit:edition', 'gco:CharacterString'], self.namespaces) edition.text = edition_val date_info = build_path(node, ['mdb:dateInfo'], self.namespaces) # Creation date val = util.getqattr(result, queryables['mdb:CreationDate']['dbcol']) if val is not None: date_info.append(self._write_date(val, 'creation')) # Publication date val = util.getqattr(result, queryables['mdb:PublicationDate']['dbcol']) if val is not None: date_info.append(self._write_date(val, 'publication')) # Revision date val = util.getqattr(result, queryables['mdb:RevisionDate']['dbcol']) if val is not None: date_info.append(self._write_date(val, 'revision')) if esn in ['summary', 'full']: # Abstract val = util.getqattr(result, queryables['mdb:Abstract']['dbcol']) or '' abstract = build_path(resident, ['mri:abstract', 'gco:characterString'], self.namespaces) abstract.text = val # Keywords kw = util.getqattr(result, queryables['mdb:Subject']['dbcol']) if kw is not None: md_keywords = build_path(resident, ['mri:descriptiveKeywords'], self.namespaces) md_keywords.append(self._write_keywords(kw)) # Spatial resolution val = util.getqattr(result, queryables['mdb:Denominator']['dbcol']) if val: path = ['mri:spatialResolution', 'mri:MD_Resolution', 'mri:equivalentScale', 'mri:MD_RepresentativeFraction', 'mri:denominator', 'gco:Integer'] int_elem = build_path(resident, path, self.namespaces) int_elem.text = str(val) # Topic category val = util.getqattr(result, queryables['mdb:TopicCategory']['dbcol']) topic_cat = build_path(resident, ['mri:topicCategory'], self.namespaces) if val: for v in val.split(','): etree.SubElement(topic_cat, util.nspath_eval('mri:MD_TopicCategoryCode', self.namespaces)).text = val # Bbox and vertical extent bbox = util.getqattr(result, queryables['mdb:BoundingBox']['dbcol']) vert_ext_min = util.getqattr(result, queryables['mdb:VertExtentMin']['dbcol']) vert_ext_max = util.getqattr(result, queryables['mdb:VertExtentMax']['dbcol']) # Convert float to string if vert_ext_min is not None: vert_ext_min = f"{vert_ext_min}" if vert_ext_max is not None: vert_ext_max = f"{vert_ext_max}" bboxel = self._write_extent(bbox, vert_ext_min, vert_ext_max) if bboxel is not None and mtype != 'service': # Add element etc. resident.append(bboxel) # Service identification if mtype == 'service': # Service type & service type version val = util.getqattr(result, queryables['mdb:ServiceType']['dbcol']) val2 = util.getqattr(result, queryables['mdb:ServiceTypeVersion']['dbcol']) if val is not None: tmp = etree.SubElement(resident, util.nspath_eval('srv:serviceType', self.namespaces)) etree.SubElement(tmp, util.nspath_eval('gco:LocalName', self.namespaces)).text = val tmp = etree.SubElement(resident, util.nspath_eval('srv:serviceTypeVersion', self.namespaces)) etree.SubElement(tmp, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val2 # Keywords kw = util.getqattr(result, queryables['mdb:Subject']['dbcol']) if kw is not None: srv_keywords = etree.SubElement(resident, util.nspath_eval('srv:descriptiveKeywords', self.namespaces)) srv_keywords.append(self._write_keywords(kw)) # Extent and bounding box if bboxel is not None: # Change element to and append bboxel.tag = util.nspath_eval('srv:extent', self.namespaces) resident.append(bboxel) val = util.getqattr(result, queryables['mdb:CouplingType']['dbcol']) if val is not None: couplingtype = etree.SubElement(resident, util.nspath_eval('srv:couplingType', self.namespaces)) etree.SubElement(couplingtype, util.nspath_eval('srv:SV_CouplingType', self.namespaces), codeListValue=val, codeList=f'{CODELIST}#SV_CouplingType').text = val if esn in ['summary', 'full']: # all service resources as coupled resources coupledresources = util.getqattr(result, queryables['mdb:OperatesOn']['dbcol']) operations = util.getqattr(result, queryables['mdb:Operation']['dbcol']) if coupledresources: for val2 in coupledresources.split(','): coupledres = etree.SubElement(resident, util.nspath_eval('srv:coupledResource', self.namespaces)) svcoupledres = etree.SubElement(coupledres, util.nspath_eval('srv:SV_CoupledResource', self.namespaces)) opname = etree.SubElement(svcoupledres, util.nspath_eval('srv:coupledName', self.namespaces)) etree.SubElement(opname, util.nspath_eval('gco:ScopedName', self.namespaces)).text = get_resource_opname(operations) sid = etree.SubElement(svcoupledres, util.nspath_eval('srv:resourceReference', self.namespaces)) # Unfortunately only have one field to apply # has a ci_citation = etree.SubElement(sid, util.nspath_eval('cit:CI_Citation', self.namespaces)) # must have a title, insert reference title = build_path(cit_citation, ['cit:title', 'gco:CharacterString'], self.namespaces) title.text = val2 # Insert reference as a identifier code code = build_path(cit_citation, ['cit:identifer', 'mcc:MD_Identifier', 'mcc:code', 'gco:CharacterString'], self.namespaces) code.text = val2 # Service operations if operations: for i in operations.split(','): oper = etree.SubElement(resident, util.nspath_eval('srv:containsOperations', self.namespaces)) sv_opermetadata = etree.SubElement(oper, util.nspath_eval('srv:SV_OperationMetadata', self.namespaces)) oper_name = etree.SubElement(sv_opermetadata, util.nspath_eval('srv:operationName', self.namespaces)) etree.SubElement(oper_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = i dcp = etree.SubElement(sv_opermetadata, util.nspath_eval('srv:distributedComputingPlatform', self.namespaces)) dcp_list1 = etree.SubElement(dcp, util.nspath_eval('srv:DCPList', self.namespaces)) etree.SubElement(dcp_list1, util.nspath_eval('srv:DCPList', self.namespaces), codeList=f'{CODELIST}#DCPList', codeListValue='HTTPGet').text = 'HTTPGet' dcp_list2 = etree.SubElement(dcp, util.nspath_eval('srv:DCPList', self.namespaces)) etree.SubElement(dcp_list2, util.nspath_eval('srv:DCPList', self.namespaces), codeList=f'{CODELIST}#DCPList', codeListValue='HTTPPost').text = 'HTTPPost' connectpoint = etree.SubElement(sv_opermetadata, util.nspath_eval('srv:connectPoint', self.namespaces)) onlineres = etree.SubElement(connectpoint, util.nspath_eval('cit:CI_OnlineResource', self.namespaces)) linkage = etree.SubElement(onlineres, util.nspath_eval('cit:linkage', self.namespaces)) etree.SubElement(linkage, util.nspath_eval('gco:CharacterString', self.namespaces)).text = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Source']) # operates on resource(s) if coupledresources: for i in coupledresources.split(','): operates_on = etree.SubElement(resident, util.nspath_eval('srv:operatesOn', self.namespaces)) code = build_path(operates_on, ['mri:MD_DataIdentification','mri:citation','cit:CI_Citation','cit:identifier','mcc:MD_Identifier','mcc:code','gcx:Anchor'], self.namespaces) code.text = f"{util.bind_url(self.url)}service=CSW&version=2.0.2&request=GetRecordById&outputschema={self.repository['mdb:MD_Metadata']['outputschema']}&id={idval}-{i}" rlinks = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Links']) if rlinks: distinfo = etree.SubElement(node, util.nspath_eval('mdb:distributionInfo', self.namespaces)) distinfo2 = etree.SubElement(distinfo, util.nspath_eval('mrd:MD_Distribution', self.namespaces)) transopts = etree.SubElement(distinfo2, util.nspath_eval('mrd:transferOptions', self.namespaces)) dtransopts = etree.SubElement(transopts, util.nspath_eval('mrd:MD_DigitalTransferOptions', self.namespaces)) for link in util.jsonify_links(rlinks): online = etree.SubElement(dtransopts, util.nspath_eval('mrd:onLine', self.namespaces)) online2 = etree.SubElement(online, util.nspath_eval('cit:CI_OnlineResource', self.namespaces)) linkage = etree.SubElement(online2, util.nspath_eval('cit:linkage', self.namespaces)) etree.SubElement(linkage, util.nspath_eval('gco:CharacterString', self.namespaces)).text = link['url'] protocol = etree.SubElement(online2, util.nspath_eval('cit:protocol', self.namespaces)) etree.SubElement(protocol, util.nspath_eval('gco:CharacterString', self.namespaces)).text = link.get('protocol', 'WWW:LINK') name = etree.SubElement(online2, util.nspath_eval('cit:name', self.namespaces)) etree.SubElement(name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = link.get('name') desc = etree.SubElement(online2, util.nspath_eval('cit:description', self.namespaces)) etree.SubElement(desc, util.nspath_eval('gco:CharacterString', self.namespaces)).text = link.get('description') return node def _write_contact_phone(self, ci_contact, phone_num_str): """ Write out a telephone number of a contact within an organisation :param ci_contact: 'cit:CI_Contact' XML etree.Element :param phone_num_str: phone number string :returns: XML contact phone etree.Element """ phone = build_path(ci_contact, ['cit:phone', 'cit:CI_Telephone'], self.namespaces) ph_number = build_path(phone, ['cit:number', 'gco:characterString'], self.namespaces) ph_number.text = phone_num_str ph_type = build_path(phone, ['cit:numberType', 'cit:CI_TelephoneTypeCode'], self.namespaces) ph_type.text = "voice" def _write_contact_fax(self, ci_contact, fax_num_str): """ Write out a fax number of a contact within an organisation :param ci_contact: 'cit:CI_Contact' XML etree.Element :param fax_num_str: fax number string :returns: XML contact fax etree.Element """ phone = build_path(ci_contact, ['cit:phone', 'cit:CI_Telephone'], self.namespaces, reuse=False) ph_number = build_path(phone, ['cit:number', 'gco:characterString'], self.namespaces) ph_number.text = fax_num_str ph_type = build_path(phone, ['cit:numberType', 'cit:CI_TelephoneTypeCode'], self.namespaces) ph_type.text = "facsimile" def _write_contact_address(self, ci_resp, ci_contact, **contact): """ Write out an address of a contact within an organisation :param ci_resp: 'cit:CI_Responsibility' XML etree.Element :param ci_contact: 'cit:CI_Contact' XML etree.Element :param contact: dict of contact details, keys are 'address' 'city' 'region' 'postcode' 'country' 'email' :returns: XML contact address etree.Element """ ci_address = build_path(ci_contact, ['cit:address', 'cit:CI_Address'], self.namespaces) if contact.get('address', None) is not None: delivery_point = etree.SubElement(ci_address, util.nspath_eval('cit:deliveryPoint', self.namespaces)) etree.SubElement(delivery_point, util.nspath_eval('gco:CharacterString', self.namespaces)).text = contact['address'] if contact.get('city', None) is not None: city = etree.SubElement(ci_address, util.nspath_eval('cit:city', self.namespaces)) etree.SubElement(city, util.nspath_eval('gco:CharacterString', self.namespaces)).text = contact['city'] if contact.get('region', None) is not None: admin_area = etree.SubElement(ci_address, util.nspath_eval('cit:administrativeArea', self.namespaces)) etree.SubElement(admin_area, util.nspath_eval('gco:CharacterString', self.namespaces)).text = contact['region'] if contact.get('postcode', None) is not None: postal_code = etree.SubElement(ci_address, util.nspath_eval('cit:postalCode', self.namespaces)) etree.SubElement(postal_code, util.nspath_eval('gco:CharacterString', self.namespaces)).text = contact['postcode'] if contact.get('country', None) is not None: country = etree.SubElement(ci_address, util.nspath_eval('cit:country', self.namespaces)) etree.SubElement(country, util.nspath_eval('gco:CharacterString', self.namespaces)).text = contact['country'] if contact.get('email', None) is not None: email = etree.SubElement(ci_address, util.nspath_eval('cit:electronicMailAddress', self.namespaces)) etree.SubElement(email, util.nspath_eval('gco:CharacterString', self.namespaces)).text = contact['email'] # URL of organisation or individual if contact.get('url', None) is not None: path = ['cit:onlineResource', 'cit:CI_OnlineResource', 'cit:linkage', 'gco:characterString'] url = build_path(ci_contact, path, self.namespaces) url.text = contact['url'] # Role role = build_path(ci_resp, ['cit:role', 'cit:CI_RoleCode'], self.namespaces) role.set("codeList", f'{CODELIST}#CI_RoleCode') role_str = 'pointOfContact' if contact.get('role', None) is not None: role_str = contact.get('role') role.set("codeListValue", role_str) def _write_keywords(self, keywords): """ Generate XML mri:MD_Keywords construct :param keywords: keywords CSV string :returns: XML as etree.Element """ md_keywords = etree.Element(util.nspath_eval('mri:MD_Keywords', self.namespaces)) for kw in keywords.split(','): keyword = etree.SubElement(md_keywords, util.nspath_eval('mri:keyword', self.namespaces)) etree.SubElement(keyword, util.nspath_eval('gco:CharacterString', self.namespaces)).text = kw return md_keywords def _write_extent(self, bbox, vert_ext_min, vert_ext_max): """ Generate XML for a bounding box in 2 dimensions or a bounding box and vertical extent in 3 dimensions :param bbox: bounding box in EWKT (Extended Well Known Text) format :param vert_ext_min: vertical extent minimum, pass in None for 2D :param vert_extent_max: vertical extent maximum, pass in None for 2D :returns: XML as etree.Element """ if bbox is not None: try: bbox2 = util.wkt2geom(bbox) except: return None extent = etree.Element(util.nspath_eval('mri:extent', self.namespaces)) ex_extent = etree.SubElement(extent, util.nspath_eval('gex:EX_Extent', self.namespaces)) gbb = build_path(ex_extent, ['gex:geographicElement', 'gex:EX_GeographicBoundingBox'], self.namespaces) west = etree.SubElement(gbb, util.nspath_eval('gex:westBoundLongitude', self.namespaces)) east = etree.SubElement(gbb, util.nspath_eval('gex:eastBoundLongitude', self.namespaces)) south = etree.SubElement(gbb, util.nspath_eval('gex:southBoundLatitude', self.namespaces)) north = etree.SubElement(gbb, util.nspath_eval('gex:northBoundLatitude', self.namespaces)) etree.SubElement(west, util.nspath_eval('gco:Decimal', self.namespaces)).text = str(bbox2[0]) etree.SubElement(south, util.nspath_eval('gco:Decimal', self.namespaces)).text = str(bbox2[1]) etree.SubElement(east, util.nspath_eval('gco:Decimal', self.namespaces)).text = str(bbox2[2]) etree.SubElement(north, util.nspath_eval('gco:Decimal', self.namespaces)).text = str(bbox2[3]) # If there is a vertical extent if vert_ext_min is not None and vert_ext_max is not None: vert_ext = build_path(ex_extent, ['gex:verticalElement', 'gex:EX_VerticalExtent'], self.namespaces) min_val = build_path(vert_ext, ['gex:minimumValue', 'gco:Real'], self.namespaces) min_val.text = vert_ext_min max_val = build_path(vert_ext, ['gex:maximumValue', 'gco:Real'], self.namespaces) max_val.text = vert_ext_max return extent return None def _write_date(self, dateval, datetypeval): """ Generate XML date elements :param dateval: date string :param datetypeval: date type code string :returns: date XML etree.Element """ date1 = etree.Element(util.nspath_eval('cit:CI_Date', self.namespaces)) date2 = etree.SubElement(date1, util.nspath_eval('cit:date', self.namespaces)) if dateval.find('T') != -1: dateel = 'gco:DateTime' else: dateel = 'gco:Date' etree.SubElement(date2, util.nspath_eval(dateel, self.namespaces)).text = dateval datetype = etree.SubElement(date1, util.nspath_eval('cit:dateType', self.namespaces)) datetype.append(write_codelist_element('cit:CI_DateTypeCode', datetypeval, self.namespaces)) return date1 # END of class def get_resource_opname(operations): """ Looks for resource opename in a CSV string :param operations: CSV string of operations :returns: operation name """ for op in operations.split(','): if op in ['GetMap', 'GetFeature', 'GetCoverage', 'GetObservation']: return op return None def write_codelist_element(codelist_element, codelist_value, nsmap): """ Generic routine to write codelist artributes into an element :param codelist_element: codelist element :param codelist_value: codelist values :param nsmap: namespace map, namepace str -> namespace URI :returns: lxml.etree.Element """ # Get tag name without namespace namespace, no_ns_tag = codelist_element.split(':') element = etree.Element(util.nspath_eval(codelist_element, nsmap), codeSpace='http://standards.iso.org/iso/19115', codeList=f'{CODELIST}#{no_ns_tag}', codeListValue=codelist_value) element.text = codelist_value return element def build_path(node, path_list, nsmap, reuse=True): """ Generic routine to build an etree.Element path Set reuse=False if you want to create duplicates :param node: add elements to this Element :param path_list: list of xml tags of new path to create, list of strings :param reuse: if False will always create new Elements along this path :return: returns the last etree.Element in the new Element path """ tail = node for elem_name in path_list: # Does the next node in the path exist? next_node = node.find(elem_name, namespaces=nsmap) # If next node does not exist or reuse flag is False then create it if next_node is None or not reuse: tail = etree.SubElement(tail, util.nspath_eval(elem_name, nsmap)) else: tail = next_node return tail ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/cat.xsd ================================================ catalogue is a collection of information items (CT_Items) that are managed using a registry (CT_Catalogue). The abstract concept of catalogue was defined in ISO19139 to harmonise the different ISO 19100 series catalogue concepts, such as PF_PortrayalCatalogue (ISO 19117) and FC_FeatureCatalogue (ISO 19110). ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/catalogues.xsd ================================================ Handcrafted ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/codelistItem.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/crsItem.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/uomItem.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/1.0/cit.sch ================================================ The individual does not have a name or a position. Une personne n'a pas de nom ou de fonction. Individual name is "" and position "" . Le nom de la personne est "" ,sa fonction "" . Individual MUST have a name or a position Une personne DOIT avoir un nom ou une fonction The organisation does not have a name or a logo. Une organisation n'a pas de nom ou de logo. Organisation name is "" and logo filename is "" . Le nom de l'organisation est "" , son logo "" . ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/1.0/cit.xsd ================================================ Namespace for XML elements <font color="#1f497d">for constructing citations to resources</font>. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/1.0/citation.xsd ================================================ location of the responsible individual or organisation address line for the location (as described in ISO 11180, Annex A) city of the location state, province of the location ZIP or other postal code country of the physical address address of the electronic mailbox of the responsible organisation or individual standardized resource reference name by which the cited resource is known short name or other language name by which the cited information is known. Example: DCW as an alternative title for Digital Chart of the World reference date for the cited resource version of the cited resource date of the edition value uniquely identifying an object within a namespace name and position information for an individual or organisation that is responsible for the resource mode in which the resource is represented information about the series, or aggregate resource, of which the resource is a part other information required to complete the citation that is not recorded elsewhere international Standard Book Number international Standard Serial Number online reference to the cited resource citation graphic or logo for cited party information required to enable contact with the responsible person and/or organisation telephone numbers at which the organisation or individual may be contacted physical and email address at which the organisation or individual may be contacted on-line information that can be used to contact the individual or organisation time period (including time zone) when individuals can contact the organisation or individual supplemental instructions on how or when to contact the individual or organisation reference date and event used to describe it reference date for the cited resource event used for reference date identification of when a given event occurred information about the party if the party is an individual position of the individual in an organisation function performed by the resource information about on-line sources from which the resource, specification, or community profile name and extended metadata elements can be obtained location (address) for on-line access using a Uniform Resource Locator/Uniform Resource Identifier address or similar addressing scheme such as http://www.statkart.no/isotc211 connection protocol to be used e.g. http, ftp, file name of an application profile that can be used with the online resource name of the online resource detailed text description of what the online resource is/does code for function performed by the online resource protocol used by the accessed resource information about the party if the party is an organisation Graphic identifying organization information about the individual and/or organisation of the party name of the party contact information for the party mode in which the data is represented information about the party and their role function performed by the responsible party spatial or temporal extent of the role function performed by the responsible party information about the series, or aggregate resource, to which a resource belongs name of the series, or aggregate resource, of which the resource is a part information identifying the issue of the series details on which pages of the publication the article was published telephone numbers for contacting the responsible individual or organisation telephone number by which individuals can contact responsible organisation or individual type of telephone responsible organisation or individual type of telephone ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/2.0/cit.xsd ================================================ Namespace for XML elements for constructing citations to resources. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/2.0/citation.xsd ================================================ location of the responsible individual or organisation address line for the location (as described in ISO 11180, Annex A) city of the location state, province of the location ZIP or other postal code country of the physical address address of the electronic mailbox of the responsible organisation or individual standardized resource reference name by which the cited resource is known short name or other language name by which the cited information is known. Example: DCW as an alternative title for Digital Chart of the World reference date for the cited resource version of the cited resource date of the edition value uniquely identifying an object within a namespace name and position information for an individual or organisation that is responsible for the resource mode in which the resource is represented information about the series, or aggregate resource, of which the resource is a part other information required to complete the citation that is not recorded elsewhere international Standard Book Number international Standard Serial Number online reference to the cited resource citation graphic or logo for cited party information required to enable contact with the responsible person and/or organisation telephone numbers at which the organisation or individual may be contacted physical and email address at which the organisation or individual may be contacted on-line information that can be used to contact the individual or organisation time period (including time zone) when individuals can contact the organisation or individual supplemental instructions on how or when to contact the individual or organisation reference date and event used to describe it reference date for the cited resource event used for reference date identification of when a given event occurred information about the party if the party is an individual position of the individual in an organisation function performed by the resource information about on-line sources from which the resource, specification, or community profile name and extended metadata elements can be obtained location (address) for on-line access using a Uniform Resource Locator/Uniform Resource Identifier address or similar addressing scheme such as http://www.statkart.no/isotc211 connection protocol to be used e.g. http, ftp, file name of an application profile that can be used with the online resource name of the online resource detailed text description of what the online resource is/does code for function performed by the online resource protocol used by the accessed resource information about the party if the party is an organisation Graphic identifying organization information about the individual and/or organisation of the party name of the party contact information for the party value uniquely identifying a party (individual or organization) mode in which the data is represented information about the party and their role function performed by the responsible party spatial or temporal extent of the role function performed by the responsible party information about the series, or aggregate resource, to which a resource belongs name of the series, or aggregate resource, of which the resource is a part information identifying the issue of the series details on which pages of the publication the article was published telephone numbers for contacting the responsible individual or organisation telephone number by which individuals can contact responsible organisation or individual type of telephone responsible organisation or individual type of telephone ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gco/1.0/baseTypes2014.xsd ================================================ Geographic COmmon (GCO) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19115-3, based on the implementation patterns defined and utilized in ISO19139. This gcoBase.xsd schema provides: 1. tools to handle specific objects like "code lists" and "record"; 2. Some XML types that do not follow the general encoding rules specified in ISO19139. *** SMR 2014-12-22. Refactor gco, gts, gsr, gss to separate gml dependencies. All element or attribute types in this schema are either types defined by this schema, or are datatypes defined by the XML schema namespace (http://www.w3.org/2001/XMLSchema) To remove the dependency between gml and the base datatypes in ISO19115-3: 1. The nilReason attribute is defined here instead of extending the gml type. 2. The definition of MeasureType is copied here from gml 3.2 basic Types. The only difference this will introduce in instance documents is that the uom attribute on a measure value (or one of its substitutions) will be gco:uom, not gml:uom. copied from gml32:NilReasonType. This Type defines a content model that allows recording of an explanation for a void value or other exception. gml:NilReasonType is a union of the following enumerated values: - inapplicable- there is no value - missing- the correct value is not readily available to the sender of this data. Furthermore, a correct value may not exist - template- the value will be available later - unknown- the correct value is not known to, and not computable by, the sender of this data. However, a correct value probably exists - withheld- the value is not divulged - other:text - other brief explanation, where text is a string of two or more characters with no included spaces and - xs:anyURI which should refer to a resource which describes the reason for the exception A particular community may choose to assign more detailed semantics to the standard values provided. Alternatively, the URI method enables a specific or more complete explanation for the absence of a value to be provided elsewhere and indicated by-reference in an instance document. gml:NilReasonType is used as a member of a union in a number of simple content types where it is necessary to permit a value from the NilReasonType union as an alternative to the primary type. A TypeName is a LocalName that references either a recordType or object type in some form of schema. The stored value "aName" is the returned value for the "aName()" operation. This is the types name. - For parsing from types (or objects) the parsible name normally uses a "." navigation separator, so that it is of the form [class].[member].[memberOfMember]. ...) A MemberName is a LocalName that references either an attribute slot in a record or recordType or an attribute, operation, or association role in an object instance or type description in some form of schema. The stored value "aName" is the returned value for the "aName()" operation. Use to represent the possible cardinality of a relation. Represented by a set of simple multiplicity ranges. A component of a multiplicity, consisting of an non-negative lower bound, and a potentially infinite upper bound. Copied from gml32:MeasureType, which supports recording an amount encoded as a value of XML Schema double, together with a units of measure indicated by an attribute uom, short for "units Of measure". The value of the uom attribute identifies a reference system for the amount, usually a ratio or interval scale. Namespace changed to gco The simple type gml:UomIdentifer defines the syntax and value space of the unit of measure identifier. This type specifies a character string of length at least one, and restricted such that it must not contain any of the following characters: ":" (colon), " " (space), (newline), (carriage return), (tab). This allows values corresponding to familiar abbreviations, such as "kg", "m/s", etc. It is recommended that the symbol be an identifier for a unit of measure as specified in the "Unified Code of Units of Measure" (UCUM) (http://aurora.regenstrief.org/UCUM). This provides a set of symbols and a grammar for constructing identifiers for units of measure that are unique, and may be easily entered with a keyboard supporting the limited character set known as 7-bit ASCII. ISO 2955 formerly provided a specification with this scope, but was withdrawn in 2001. UCUM largely follows ISO 2955 with modifications to remove ambiguities and other problems. This type specifies a URI, restricted such that it must start with one of the following sequences: "#", "./", "../", or a string of characters followed by a ":". These patterns ensure that the most common URI forms are supported, including absolute and relative URIs and URIs that are simple fragment identifiers, but prohibits certain forms of relative URI that could be mistaken for unit of measure symbol . NOTE It is possible to re-write such a relative URI to conform to the restriction (e.g. "./m/s"). In an instance document, on elements of type gml:MeasureType the mandatory uom attribute shall carry a value corresponding to either - a conventional unit of measure symbol, - a link to a definition of a unit of measure that does not have a conventional symbol, or when it is desired to indicate a precise or variant definition. gml:CodeType is a generalized type to be used for a term, keyword or name. It adds a XML attribute codeSpace to a term, where the value of the codeSpace attribute (if present) shall indicate a dictionary, thesaurus, classification scheme, authority, or pattern for the term. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gco/1.0/gco.xsd ================================================ This is the root document of the The Geographic COmmon (GCO) http://standards.iso.org/iso/19115/-3/gco/1.0 namespace, a component of the XML Schema Implementation of Geographic Information Metadata (ISO19115-1). Original implementation documented in ISO/TS 19139:2007 is refactored in this implementation for ISO19115-3 to remove dependency of base data types on GML (the only gml element used was the enumeration of nilReasons). GCO includes all the definitions of http://standards.iso.org/iso/19115/-3/gco/1.0 namespace. Elements that are extensions of GML elements are defined in the gmw namespace in ISO19115-3. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gcx/1.0/extendedTypes.xsd ================================================ This file was generated from ISO TC/211 UML class diagrams == 03-14-2005 12:00:20 ====== Handcrafted 20130614 SMR updates: 1. schema locations for gco and xlink. 2. change namespace prefix from gmx to gcx, to use for ISO19115-3. 3. change attribute group for gcx:anchor from xlink:simpleLink (old) to xlink:simpleAttrs (new). 20130327 - Ted changed targetNamespace and gcx namespace to http://www.isotc211.org/2005/gcx/1.0/2013-03-28 20130624 SMR update namespace version date 20140729 SMR update namespace for 07-11 build. The schema generated by ShapeChange from the UML does not work for gcx namespace. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gcx/1.0/extendedTypes_autoFromShapeChange.xsd ================================================ Handcrafted ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gcx/1.0/gcx.xsd ================================================ Elements for xml implementation, from ISO 19139 updated for compatibility with new schema. Anchor, FileName, MimeFileType; all in substitution group for CharacterString to support Web environments. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gex/1.0/extent.xsd ================================================ enclosing geometric object which locates the resource, expressed as a set of (x,y) coordinate (s) NOTE: If a polygon is used it should be closed (last point replicates first point) sets of points defining the bounding polygon or any other GM_Object geometry (point, line or polygon) extent of the resource sets of points defining the bounding polygon or any other GM_Object geometry (point, line or polygon) geographic position of the resource NOTE: This is only an approximate reference so specifying the coordinate reference system is unnecessary and need only be provided with a precision of up to two decimal places western-most coordinate of the limit of the resource extent, expressed in longitude in decimal degrees (positive east) eastern-most coordinate of the limit of the resource extent, expressed in longitude in decimal degrees (positive east) southern-most coordinate of the limit of the resource extent, expressed in latitude in decimal degrees (positive north) northern-most, coordinate of the limit of the resource extent expressed in latitude in decimal degrees (positive north) description of the geographic area using identifiers identifier used to represent a geographic area e.g. a geographic identifier as described in ISO 19112 spatial area of the resource indication of whether the geographic element encompasses an area covered by the data or an area where data is not present extent with respect to date/time and spatial boundaries vertical extent component time period covered by the content of the resource period for the content of the resource vertical domain of resource lowest vertical extent contained in the resource highest vertical extent contained in the resource ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gex/1.0/gex.sch ================================================ The extent does not contain a description or a geographicElement. L'étendue ne contient aucun élement. The extent contains a description. L'étendue contient une description. The extent contains a geographic identifier. L'étendue contient un identifiant géographique. The extent contains a bounding box element. L'étendue contient une emprise géographique. The extent contains a bounding polygon. L'étendue contient un polygone englobant. The extent contains a vertical element. L'étendue contient une étendue verticale. The extent contains a temporal element. L'étendue contient une étendue temporelle. Extent MUST have one description or one geographic, temporal or vertical element Une étendue DOIT avoir une description ou un élément géographique, temporel ou vertical The vertical extent does not contains CRS or CRS identifier. L'étendue verticale ne contient pas de CRS ou d'identifiant de CRS. The vertical extent contains CRS information. L'étendue verticale contient les informations sur le CRS. Vertical element MUST contains a CRS or CRS identifier Une étendue verticale DOIT contenir un CRS ou un identifiant de CRS ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gex/1.0/gex.xsd ================================================ Namespace for XML elements used to specify spatial and temporal extents. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gmw/1.0/gmlWrapperTypes2014.xsd ================================================ Geographic COmmon (GCO) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GCO includes all the definitions of http://standards.iso.org/iso/19115/-3/gco/1.0" namespace. The root document of this namespace is the file gco.xsd. This basicTypes.xsd schema implements concepts from the "basic types" package of ISO/TS 19103. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gmw/1.0/gmw.xsd ================================================ This is the root document of the The GMl Wrapper type (GMW) http://standards.iso.org/iso/19115/-3/gmw/1.0 namespace, a component of the XML Schema Implementation of Geographic Information Metadata (ISO19115-1). Original implementation documented in ISO/TS 19139:2007 is refactored in this implementation for ISO19115-3 to put type definitions that wrap GML elements in property types with optional gco:ObjectProperties and gco:nilReason attributes as originally specified in ISO19139 in the gco, gss, gsr and gts namespaces. Elements from the ISO19139 gco namespace that do not have dependencies on gml are specified in the http://standards.iso.org/iso/19115/-3/gco/1.0 namespace in the ISO19115-3 implementation ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/lan/1.0/lan.xsd ================================================ Namespace for XML elements used to implement cultural and linguistic adaptability, i.e. different character set and language encoding of metadata content. Originally defined in ISO 19139. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/lan/1.0/language.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/1.0/acquisitionInformationImagery.xsd ================================================ Description: Designations for the measuring instruments and their bands, the platform carrying them, and the mission to which the data contributes FGDC: Platform_and_Instrument_Identification, Mission_Information shortName: PltfrmInstId Description: context of activation shortName: CntxtCode Description: identification of a significant collection point within an operation shortName: Event Description: Event name or number shortName: evtId Description: Initiator of the event shortName: evtTrig Description: Meaning of the event shortName: evtCntxt Description: Relative time ordering of the event shortName: evtSeq Description: Time the event occured shortName: evtTime Description: geometric description of collection shortName: GeoTypeCode Description: Designations for the measuring instruments FGDC: Platform_and_Instrument_Identification shortName: PltfrmInstId Description: complete citation of the instrument FGDC: Instrument_Full_Name Position: 1 shortName: instNam Conditional: if shortName not specified Description: complete citation of the instrument FGDC: Instrument_Full_Name Position: 1 shortName: instNam Conditional: if shortName not specified Description: Code describing the type of instrument shortName: instType Description: Textual description of the instrument shortName: instDesc Description: Describes the characteristics, spatial and temportal extent of the intended object to be observed shortName: TargetId Description: Registered code used to identify the objective Postion: 1 shortName: targetId Description: priority applied to the target Position: 3 shortName: trgtPriority Description: collection technique for the objective Position: 4 shortName: trgtType Description: function performed by or at the objective Position: 5 shortName: trgtFunct Description: extent information including the bounding box, bounding polygon, vertical and temporal extent of the objective Position: 6 shortName: trgtExtent Description: temporal persistence of collection objective shortName: ObjTypeCode Description: Designations for the operation used to acquire the dataset shortName: MssnId Description: Description of the mission on which the platform observations are part and the objectives of that mission FGDC: Mission_Description Position: 3 shortName: mssnDesc Description: character string by which the mission is known FGDC: Mission_Name Position: 1 shortName: pltMssnNam NITF_ACFTA:AC_MSN_ID Description: character string by which the mission is known FGDC: Mission_Name Position: 1 shortName: pltMssnNam NITF_ACFTA:AC_MSN_ID Description: status of the data acquisition FGDC: Mission_Start_Date Position: 4 shortName: mssnStatus Description: status of the data acquisition FGDC: Mission_Start_Date Position: 4 shortName: mssnStatus Description: Platform (or platforms) used in the operation. Description: Designations for the planning information related to meeting requirements shortName: PlanId Description: manner of sampling geometry the planner expects for collection of the objective data Postion: 2 shortName: planType Description: current status of the plan (pending, completed, etc.) shortName: planStatus Description: Identification of authority requesting target collection Postion: 1 shortName: planReqId Description: Designations for the platform used to acquire the dataset shortName: PltfrmId Description: complete citation of the platform FGDC: Platform_Full_Name Position: 3 shortName: pltNam Conditional: if shortName not specified Description: Unique identification of the platform shortName: pltId Description: Narrative description of the platform supporting the instrument FGDC: Platform_Description Position: 2 shortName: pltfrmDesc Description: organization responsible for building, launch, or operation of the platform FGDC: Platform_Sponsor Position: 6 shortName: pltfrmSpnsr Description: identification of collection coverage shortName: PlatformPass Description: unique name of the pass shortName: passId Description: Area covered by the pass shortName: passExt Description: ordered list of priorities shortName: PriCode Description: range of date validity shortName: ReqstDate Description: preferred date and time of collection shortName: collectDate Description: latest date and time collection must be completed shortName: latestDate Description: requirement to be satisfied by the planned data acquisition shortName: Requirement Description: identification of reference or guidance material for the requirement shortName: reqRef Description: unique name, or code, for the requirement shortName: reqId Description: origin of requirement shortName: requestor Description: person(s), or body(ies), to recieve results of requirement shortName: recipient Description: relative ordered importance, or urgency, of the requirement shortName: reqPri Description: required or preferred acquisition date and time shortName: reqDate Description: date and time after which collection is no longer valid shortName: reqExpire <UsedBy> <NameSpace>ISO 19115-2 Metadata - Imagery</NameSpace> <Class>MI_Instrument</Class> <Package>Acquisition information - Imagery</Package> <Attribute>type</Attribute> <Type>MI_SensorTypeCode</Type> <UsedBy> Description: temporal relation of activation shortName: SeqCode Description: mechanism of activation shortName: TriggerCode ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/1.0/mac.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/2.0/acquisitionInformationImagery.xsd ================================================ Description: Designations for the measuring instruments and their bands, the platform carrying them, and the mission to which the data contributes FGDC: Platform_and_Instrument_Identification, Mission_Information shortName: PltfrmInstId the specific data to which the acquisition information applies Description: context of activation shortName: CntxtCode Description: identification of a significant collection point within an operation shortName: Event Description: Event name or number shortName: evtId Description: Initiator of the event shortName: evtTrig Description: Meaning of the event shortName: evtCntxt Description: Relative time ordering of the event shortName: evtSeq Description: Time the event occured shortName: evtTime Description: geometric description of collection shortName: GeoTypeCode Description: Designations for the measuring instruments FGDC: Platform_and_Instrument_Identification shortName: PltfrmInstId Description: complete citation of the instrument FGDC: Instrument_Full_Name Position: 1 shortName: instNam Conditional: if shortName not specified Description: complete citation of the instrument FGDC: Instrument_Full_Name Position: 1 shortName: instNam Conditional: if shortName not specified Description: Code describing the type of instrument shortName: instType Description: Textual description of the instrument shortName: instDesc type of other property description (i.e. netcdf/variable in ncml.xsd or AdditionalAttribute in ECHO) instance of otherPropertyType that defines attributes not explicitly included in MI_Platform Sensor Description Description: Describes the characteristics, spatial and temportal extent of the intended object to be observed shortName: TargetId Description: Registered code used to identify the objective Postion: 1 shortName: targetId Description: priority applied to the target Position: 3 shortName: trgtPriority Description: collection technique for the objective Position: 4 shortName: trgtType Description: function performed by or at the objective Position: 5 shortName: trgtFunct Description: extent information including the bounding box, bounding polygon, vertical and temporal extent of the objective Position: 6 shortName: trgtExtent Description: temporal persistence of collection objective shortName: ObjTypeCode Description: Designations for the operation used to acquire the dataset shortName: MssnId Description: Description of the mission on which the platform observations are part and the objectives of that mission FGDC: Mission_Description Position: 3 shortName: mssnDesc Description: character string by which the mission is known FGDC: Mission_Name Position: 1 shortName: pltMssnNam NITF_ACFTA:AC_MSN_ID Description: character string by which the mission is known FGDC: Mission_Name Position: 1 shortName: pltMssnNam NITF_ACFTA:AC_MSN_ID Description: status of the data acquisition FGDC: Mission_Start_Date Position: 4 shortName: mssnStatus Description: status of the data acquisition FGDC: Mission_Start_Date Position: 4 shortName: mssnStatus Description: Platform (or platforms) used in the operation. type of other property description (i.e. netcdf/variable in ncml.xsd or AdditionalAttribute in ECHO) instance of otherPropertyType that defines attributes not explicitly included in MI_Operation Description: Designations for the planning information related to meeting requirements shortName: PlanId Description: manner of sampling geometry the planner expects for collection of the objective data Postion: 2 shortName: planType Description: current status of the plan (pending, completed, etc.) shortName: planStatus Description: Identification of authority requesting target collection Postion: 1 shortName: planReqId Description: Designations for the platform used to acquire the dataset shortName: PltfrmId Description: complete citation of the platform FGDC: Platform_Full_Name Position: 3 shortName: pltNam Conditional: if shortName not specified Unique identification of the platform Description: Narrative description of the platform supporting the instrument FGDC: Platform_Description Position: 2 shortName: pltfrmDesc Description: organization responsible for building, launch, or operation of the platform FGDC: Platform_Sponsor Position: 6 shortName: pltfrmSpnsr type of other property description (i.e. netcdf/variable in ncml.xsd or AdditionalAttribute in ECHO) instance of otherPropertyType that defines attributes not explicitly included in MI_Platform Description: identification of collection coverage shortName: PlatformPass Description: unique name of the pass shortName: passId Description: Area covered by the pass shortName: passExt Description: ordered list of priorities shortName: PriCode Description: range of date validity shortName: ReqstDate Description: preferred date and time of collection shortName: collectDate Description: latest date and time collection must be completed shortName: latestDate Description: requirement to be satisfied by the planned data acquisition shortName: Requirement Description: identification of reference or guidance material for the requirement shortName: reqRef Description: unique name, or code, for the requirement shortName: reqId Description: origin of requirement shortName: requestor Description: person(s), or body(ies), to recieve results of requirement shortName: recipient Description: relative ordered importance, or urgency, of the requirement shortName: reqPri Description: required or preferred acquisition date and time shortName: reqDate Description: date and time after which collection is no longer valid shortName: reqExpire <UsedBy> <NameSpace>ISO 19115-2 Metadata - Imagery</NameSpace> <Class>MI_Instrument</Class> <Package>Acquisition information - Imagery</Package> <Attribute>type</Attribute> <Type>MI_SensorTypeCode</Type> <UsedBy> Description: temporal relation of activation shortName: SeqCode Description: mechanism of activation shortName: TriggerCode ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/2.0/event.xsd ================================================ event.xsd Version 1.0 thabermann@hdfgroup.org Created 2017-01-18 Instrumentation EventList Description Instrumentation Event Description Description: NASA Revision Description ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/2.0/mac.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mas/1.0/applicationSchema.xsd ================================================ information about the application schema used to build the dataset name of the application schema used identification of the schema language used formal language used in Application Schema full application schema given as an ASCII file full application schema given as a graphics file full application schema given as a software development file software dependent format used for the application schema software dependent file ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mas/1.0/mas.xsd ================================================ Namespace for XML elements <font color="#1f497d">to specify the application schema associated with a resource</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mcc/1.0/AbstractCommonClasses.xsd ================================================ <ul> <li></li> </ul> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mcc/1.0/commonClasses.xsd ================================================ graphic that provides an illustration of the dataset (should include a legend for the graphic, if applicable) name of the file that contains a graphic that provides an illustration of the dataset text description of the illustration restriction on access and/or use of browse graphic link to browse graphic value uniquely identifying an object within a namespace Citation for the code namespace and optionally the person or party responsible for maintenance of that namespace alphanumeric value identifying an instance in the namespace e.g. EPSG::4326 Identifier or namespace in which the code is valid version identifier for the namespace natural language description of the meaning of the code value E.G for codeSpace = EPSG, code = 4326: description = WGS-84" to "for codeSpace = EPSG, code = EPSG::4326: description = WGS-84 status of the resource new: information about the scope of the resource description of the scope class of information to which the referencing entity applies description of the class of information covered by the information instances of attribute types to which the information applies instances of feature types to which the information applies feature instances to which the information applies attribute instances to which the information applies dataset to which the information applies class of information that does not fall into the other categories to which the information applies method used to represent geographic information in the resource Uniform Resource Identifier (URI), is a compact string of characters used to identify or name a resource ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mcc/1.0/mcc.xsd ================================================ Abstract classes for linking to elements in the metadata implementation from external schema to loosely couple the external schema for smoother handling of version changes in components. Classes used by all components in ISO19115 metadata application. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mco/1.0/constraints.xsd ================================================ name of the handling restrictions on the resource restrictions on the access and use of a resource or metadata limitation affecting the fitness for use of the resource or metadata. Example, "not to be used for navigation" Spatial and temporal extent of the application of the constraint restrictions graphic /symbol indicating the constraint Eg. citation/URL for the limitation or constraint, e.g. copyright statement, license agreement, etc information concerning the parties to whom the resource can or cannot be released and the party responsible for determining the releasibility party responsible for the resource constraints restrictions and legal prerequisites for accessing and using the resource or metadata access constraints applied to assure the protection of privacy or intellectual property, and any special restrictions or limitations on obtaining the resource or metadata constraints applied to assure the protection of privacy or intellectual property, and any special restrictions or limitations or warnings on using the resource or metadata other restrictions and legal prerequisites for accessing and using the resource or metadata state, nation or organization to which resource can be released to e.g. NATO unclassified releasable to PfP party responsible for the Release statement release statement component in determining releasability limitation(s) placed upon the access or use of the data handling restrictions imposed on the resource or metadata for national security or similar security concerns name of the handling restrictions on the resource or metadata explanation of the application of the legal constraints or other restrictions and legal prerequisites for obtaining and using the resource or metadata name of the classification system additional information about the restrictions on handling the resource or metadata ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mco/1.0/mco.sch ================================================ The releasabilty does not define addresse or statement. La possibilité de divulgation ne définit pas de destinataire ou d'indication. The releasability addressee is defined: "". Le destinataire dans le cas de possibilité de divulgation est défini "". The releasability statement is "". L'indication concernant la possibilité de divulgation est "". Releasability MUST specified an addresse or a statement La possibilité de divulgation DOIT définir un destinataire ou une indication The legal constraint is incomplete. La contrainte légale est incomplète. The legal constraint is complete. La contrainte légale est complète. Legal constraint MUST specified an access, use or other constraint or use limitation or releasability Une contrainte légale DOIT définir un type de contrainte (d'accès, d'utilisation ou autre) ou bien une limite d'utilisation ou une possibilité de divulgation The legal constraint does not specified other constraints while access and use constraint is set to other restriction. La contrainte légale ne précise pas les autres contraintes bien que les contraintes d'accès ou d'usage indiquent que d'autres restrictions s'appliquent. The legal constraint other constraints is "". Les autres contraintes de la contrainte légale sont "". Legal constraint defining other restrictions for access or use constraint MUST specified other constraint. Une contrainte légale indiquant d'autres restrictions d'utilisation ou d'accès DOIT préciser ces autres restrictions ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mco/1.0/mco.xsd ================================================ Namespace for XML elements <font color="#1f497d">to specify constraints on access to or usage of a resource</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md1/1.0/md1.xsd ================================================ Namespace <font color="#1f497d">that identifies conformance class that allows extended types (gcx) in metadata records</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md1/1.0/metadataWExtendedType.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md2/1.0/md2.xsd ================================================ Namespace <font color="#1f497d">that identifies conformance class that includes user-defined metadata extensions in metadata records</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md2/1.0/metadataWithExtensions.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mda/1.0/mda.xsd ================================================ Namespace for XML elements <font color="#1f497d">for metadata applications describing aggregated resources with linked metadata records</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mda/1.0/metadataApplication.xsd ================================================ collection of resources identifiable collection of data collection of associated resources related by their participation in a common initiative collection of resource associated through inspecified means collection of associated resources produced from the same sensor platform collection of associated resources produced to the same production specification an identifiable asset or means that fulfils a requirement collection of associated resources produced by the same sensor collection of resource related by a common heritage adhering to a common specification resource is a service ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/1.0/mdb.sch ================================================ The root element must be MD_Metadata. Modifier l'élément racine du document pour que ce soit un élément MD_Metadata. Root element MD_Metadata found. Élément racine MD_Metadata défini. Metadata document root element Élément racine du document A metadata instance document conforming to this specification SHALL have a root MD_Metadata element defined in the http://standards.iso.org/iso/19115/-3/mdb/1.0 namespace. Une fiche de métadonnées conforme au standard ISO19115-1 DOIT avoir un élément racine MD_Metadata (défini dans l'espace de nommage http://standards.iso.org/iso/19115/-3/mdb/1.0). The default locale character encoding is "UTF-8". Current value is "". L'encodage ne doit pas être vide. La valeur par défaut est "UTF-8". La valeur actuelle est "". The characeter encoding is ". L'encodage est ". Default locale Langue du document The default locale MUST be documented if not defined by the encoding. The default value for the character encoding is "UTF-8". La langue doit être documentée si non définie par l'encodage. L'encodage par défaut doit être "UTF-8". Specify a name for the metadata scope (required if the scope code is not "dataset", in that case ""). Préciser la description du domaine d'application (car le document décrit une ressource qui n'est pas un "jeu de données", la ressource est de type ""). Scope name "" is defined for resource with type "". La description du domaine d'application "" est renseignée pour la ressource de type "". Metadata scope Name Description du domaine d'application If a MD_MetadataScope element is present, the name property MUST have a value if resourceScope is not equal to "dataset" Si un élément domaine d'application (MD_MetadataScope) est défini, sa description (name) DOIT avoir une valeur si ce domaine n'est pas "jeu de données" (ie. "dataset"). Specify a creation date for the metadata record in the metadata section. Définir une date de création pour le document dans la section sur les métadonnées. Metadata creation date: . Date de création du document : . Metadata create date Date de création du document A dateInfo property value with data type = "creation" MUST be present in every MD_Metadata instance. Tout document DOIT avoir une date de création définie (en utilisant un élément dateInfo avec un type de date "creation"). ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/1.0/mdb.xsd ================================================ Wrapper namespace to support Catalog Service implementations ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/1.0/metadataBase.xsd ================================================ root entity which defines metadata about a resource or resources Provides information about an alternatively used localized character string for a linguistic extension Identifier and onlineResource for a parent metadata record party responsible for the metadata information Date(s) other than creation dateEG: expiry date Citation for the standards to which the metadata conforms unique Identifier and onlineResource for alternative metadata online location where the metadata is available ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/2.0/mdb.sch ================================================ The root element must be MD_Metadata. Modifier l'élément racine du document pour que ce soit un élément MD_Metadata. Root element MD_Metadata found. Élément racine MD_Metadata défini. Metadata document root element Élément racine du document A metadata instance document conforming to this specification SHALL have a root MD_Metadata element defined in the http://standards.iso.org/iso/19115/-3/mdb/1.0 namespace. Une fiche de métadonnées conforme au standard ISO19115-1 DOIT avoir un élément racine MD_Metadata (défini dans l'espace de nommage http://standards.iso.org/iso/19115/-3/mdb/1.0). The default locale character encoding is "UTF-8". Current value is "". L'encodage ne doit pas être vide. La valeur par défaut est "UTF-8". La valeur actuelle est "". The characeter encoding is ". L'encodage est ". Default locale Langue du document The default locale MUST be documented if not defined by the encoding. The default value for the character encoding is "UTF-8". La langue doit être documentée si non définie par l'encodage. L'encodage par défaut doit être "UTF-8". Specify a name for the metadata scope (required if the scope code is not "dataset", in that case ""). Préciser la description du domaine d'application (car le document décrit une ressource qui n'est pas un "jeu de données", la ressource est de type ""). Scope name "" is defined for resource with type "". La description du domaine d'application "" est renseignée pour la ressource de type "". Metadata scope Name Description du domaine d'application If a MD_MetadataScope element is present, the name property MUST have a value if resourceScope is not equal to "dataset" Si un élément domaine d'application (MD_MetadataScope) est défini, sa description (name) DOIT avoir une valeur si ce domaine n'est pas "jeu de données" (ie. "dataset"). Specify a creation date for the metadata record in the metadata section. Définir une date de création pour le document dans la section sur les métadonnées. Metadata creation date: . Date de création du document : . Metadata create date Date de création du document A dateInfo property value with data type = "creation" MUST be present in every MD_Metadata instance. Tout document DOIT avoir une date de création définie (en utilisant un élément dateInfo avec un type de date "creation"). ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/2.0/mdb.xsd ================================================ Wrapper namespace to support Catalog Service implementations ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/2.0/metadataBase.xsd ================================================ root entity which defines metadata about a resource or resources Provides information about an alternatively used localized character string for a linguistic extension Identifier and onlineResource for a parent metadata record party responsible for the metadata information Date(s) other than creation dateEG: expiry date Citation for the standards to which the metadata conforms unique Identifier and onlineResource for alternative metadata online location where the metadata is available ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mds/1.0/mds.xsd ================================================ Namespace <font color="#1f497d">that imports all necessary namespaces to implement a complete metadata record for a dataset or service, not including extended data types or user-defined extensions. </font>Wrapper namespace to support Catalog Service implementations. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mds/1.0/metadataDataServices.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdt/1.0/mdt.xsd ================================================ Namespace for XML elements <font color="#1f497d">required to implement data transfer packages with bundled metadata, data files, and registries defining package content</font>. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdt/1.0/metadataTransfer.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mex/1.0/metadataExtension.xsd ================================================ Method used to represent geographic information in the dataset datatype of element or entity new metadata element, not found in ISO 19115, which is required to describe geographic data name of the extended metadata element definition of the extended element obligation of the extended element condition under which the extended element is mandatory code which identifies the kind of value provided in the extended element maximum occurrence of the extended element valid values that can be assigned to the extended element name of the metadata entity(s) under which this extended metadata element may appear. The name(s) may be standard metadata element(s) or other extended metadata element(s) specifies how the extended element relates to other existing elements and entities reason for creating the extended element name of the person or organisation creating the extended element information describing metadata extensions information about on-line sources containing the community profile name and the extended metadata elements. Information for all new metadata elements obligation of the element or entity obligation of the element or entity element is always required element is not required element is required when a specific condition is met ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mex/1.0/mex.sch ================================================ Extended element information "" of type "" does not specified max occurence. L'élément d'extension "" de type "" ne précise pas le nombre d'occurences maximum. Extended element information "" of type "" has max occurence: "". L'élément d'extension "" de type "" a pour nombre d'occurences maximum : "". Extended element information "" of type "" does not specified domain value. L'élément d'extension "" de type "" ne précise pas la valeur du domaine. Extended element information "" of type "" has domain value: "". L'élément d'extension "" de type "" a pour valeur du domaine : "". Extended element information which are not codelist, enumeration or codelistElement MUST specified max occurence and domain value Un élément d'extension qui n'est ni une codelist, ni une énumération, ni un élément de codelist DOIT préciser le nombre maximum d'occurences ainsi que la valeur du domaine The conditional extended element "" does not specified the condition. L'élément d'extension conditionnel "" ne précise pas les termes de la condition. The conditional extended element "" has for condition: "". L'élément d'extension conditionnel "" a pour condition : "". Extended element information which are conditional MUST explained the condition Un élément d'extension conditionnel DOIT préciser les termes de la condition The extended element "" of type "" does not specified a code. L'élément d'extension "" de type "" ne précise pas de code. The extended element "" of type "" has for code: "". L'élément d'extension "" de type "" a pour code : "". The extended element "" of type "" does not specified a concept name. L'élément d'extension "" de type "" ne précise pas de nom de concept. The extended element "" of type "" has for concept name: "". L'élément d'extension "" de type "" a pour nom de concept : "". Extended element information which are codelist, enumeration or codelistElement MUST specified a code and a concept name Un élément d'extension qui est une codelist, une énumération, un élément de codelist DOIT préciser un code et un nom de concept ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mex/1.0/mex.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document user-defined metadata extensions</font>. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mmi/1.0/maintenance.xsd ================================================ Status of the dataset or progress of a review frequency with which modifications and deletions are made to the data after it is first produced information about the scope and frequency of updating frequency with which changes and additions are made to the resource after the initial resource is completed date information associated with maintenance of resource maintenance period other than those defined information about the scope and extent of maintenance information regarding specific requirements for maintaining the resource identification of, and means of communicating with, person(s) and organisation(s) with responsibility for maintaining the metadata ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mmi/1.0/mmi.sch ================================================ The maintenance information does not define update frequency. L'information sur la maintenance ne définit pas de fréquence de mise à jour. The update frequency is "". La fréquence de mise à jour est "". The user defined update frequency is "". La fréquence de mise à jour définie par l'utilisateur est "". Maintenance information MUST specified an update frequency L'information sur la maintenance DOIT définir une fréquence de mise à jour ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mmi/1.0/mmi.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document the maintenance history and scheduling for a resource</font>. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mpc/1.0/mpc.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document a portrayal catalogue associated with a resource that specifies how to visualize the resource content.</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mpc/1.0/portrayalCatalogue.xsd ================================================ information identifying the portrayal catalogue used bibliographic reference to the portrayal catalogue cited ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/content.xsd ================================================ type of information represented by the value range of wavelengths in the electromagnetic spectrum wavelength at which the response is the highest number of discrete numerical values in the grid data description of the content of a resource. Note in 19115-3 implementation, this class is implemented by abstract class _ContentInformation in the Abstract Common Classes package specific type of information represented in the cell details about the content of a resource description of the attribute described by the measurement value Code and codespace that identifies the level of processing that has been applied to the resource a catalogue of feature types the catalogue of feature types, attribution, operations, and relationships used by the resource information identifying the feature catalogue or the conceptual schema indication of whether or not the cited feature catalogue complies with ISO 19110 language(s) used within the catalogue indication of whether or not the feature catalogue is included with the resource subset of feature types from cited feature catalogue occurring in dataset complete bibliographic reference to one or more external feature catalogues information about an image's suitability for use illumination elevation measured in degrees clockwise from the target plane at intersection of the optical line of sight with the Earth's surface. For images from a scanning device, refer to the centre pixel of the image illumination azimuth measured in degrees clockwise from true north at the time the image is taken. For images from a scanning device, refer to the centre pixel of the image conditions affected the image code in producers code space that specifies the image quality area of the dataset obscured by clouds, expressed as a percentage of the spatial extent count of the number of lossy compression cycles performed on the image indication of whether or not triangulation has been performed upon the image indication of whether or not the radiometric calibration information for generating the radiometrically calibrated standard data product is available indication of whether or not constants are available which allow for camera calibration corrections indication of whether or not Calibration Reseau information is available indication of whether or not lens aberration correction information is available code which indicates conditions which may affect the image information on the range of attribute values number that uniquely identifies instances of bands of wavelengths on which a sensor operates description of the range of a cell measurement value identifiers for each attribute included in the resource. These identifiers can be used to provide names for the resource's attribute from a standard set of names the characteristics of each dimension (layer) included in the resource maximum value of data values in each dimension included in the resource. Restricted to UomLength in the MD_Band class. minimum value of data values in each dimension included in the resource. Restricted to UomLength in the MD_Band class. units of data in each dimension included in the resource. Note that the type of this is UnitOfMeasure and that it is restricted to UomLength in the MD_Band class. scale factor which has been applied to the cell value the physical value corresponding to a cell value of zero mean value of data values in each dimension included in the resource this gives the number of values used in a thematicClassification resource EX:. the number of classes in a Land Cover Type coverage or the number of cells with data in other types of coverages standard deviation of data values in each dimension included in the resource type of other attribute description (i.e. netcdf/variable in ncml.xsd) instance of otherAttributeType that defines attributes not explicitly included in MD_CoverageType maximum number of significant bits in the uncompressed representation for the value in each band of each pixel ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/contentInformationImagery.xsd ================================================ Name: Content Position: 5 Description: extensions to electromagnetic spectrum wavelength description shortName: BandExt Description: Designation of criterion for defining maximum and minimum wavelengths for a spectral band FGDC: Band_Boundry_Definition Position: 1 shortName: bBndDef Description: Smallest distance between which separate points can be distinguished, as specified in instrument design FGDC: Nominal_Spatial_Resolution Position: 4 shortName: bndRes Description: transform function to be used when scaling a physical value for a given element shortName: scalXfrFunc Description: polarisation of the transmitter or detector shortName: polarisation Description: polarisation of the transmitter or detector shortName: polarisation Description: Designation of criterion for defining maximum and minimum wavelengths for a spectral band FGDC: Band_Boundry_Definition shortName: BndDef Description: information about the content of a coverage, including the description of specific range elements shortName: CCovDesc Description: information about the content of an image, including the description of specific range elements shortName: ICovDesc Description: polarisation of the antenna relative to the waveform shortName: PolarOrienCode Description: description of specific range elements shortName: RgEltDesc Description: designation associated with a set of range elements shortName: rgEltName Description: description of a set of specific range elements shortName: rgEltDef Description: specific range elements, i.e. range elements associated with a name and definition defining their meaning shortName: rgElt Description: transform function to be used when scaling a physical value for a given element shortName: XfrFuncTypeCode ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/mrc.sch ================================================ The sample dimension does not provide max, min or mean value. La dimension ne précise pas de valeur maximum ou minimum ni de moyenne. The sample dimension max value is "". La valeur maximum de la dimension de l'échantillon est "". The sample dimension min value is "". La valeur minimum de la dimension de l'échantillon est "". The sample dimension mean value is "". La valeur moyenne de la dimension de l'échantillon est "". Sample dimension MUST provide a max, a min or a mean value La dimension de l'échantillon DOIT préciser une valeur maximum, une valeur minimum ou une moyenne The band defined a bound without unit. La bande définit une borne minimum et/ou maximum sans préciser d'unité. The band bound [-] unit is "". L'unité de la borne [-] est "". Band MUST specified bounds units when a bound max or bound min is defined Une bande DOIT préciser l'unité lorsqu'une borne maximum ou minimum est définie ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/mrc.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document schema and amount of content in a structured resource.</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/2.0/content.xsd ================================================ type of information represented by the value range of wavelengths in the electromagnetic spectrum wavelength at which the response is the highest number of discrete numerical values in the grid data description of the content of a resource. Note in 19115-3 implementation, this class is implemented by abstract class _ContentInformation in the Abstract Common Classes package specific type of information represented in the cell details about the content of a resource description of the attribute described by the measurement value Code and codespace that identifies the level of processing that has been applied to the resource a catalogue of feature types the catalogue of feature types, attribution, operations, and relationships used by the resource information identifying the feature catalogue or the conceptual schema indication of whether or not the cited feature catalogue complies with ISO 19110 language(s) used within the catalogue indication of whether or not the feature catalogue is included with the resource subset of feature types from cited feature catalogue occurring in dataset complete bibliographic reference to one or more external feature catalogues information about an image's suitability for use illumination elevation measured in degrees clockwise from the target plane at intersection of the optical line of sight with the Earth's surface. For images from a scanning device, refer to the centre pixel of the image illumination azimuth measured in degrees clockwise from true north at the time the image is taken. For images from a scanning device, refer to the centre pixel of the image conditions affected the image code in producers code space that specifies the image quality area of the dataset obscured by clouds, expressed as a percentage of the spatial extent count of the number of lossy compression cycles performed on the image indication of whether or not triangulation has been performed upon the image indication of whether or not the radiometric calibration information for generating the radiometrically calibrated standard data product is available indication of whether or not constants are available which allow for camera calibration corrections indication of whether or not Calibration Reseau information is available indication of whether or not lens aberration correction information is available code which indicates conditions which may affect the image information on the range of attribute values number that uniquely identifies instances of bands of wavelengths on which a sensor operates description of the range of a cell measurement value identifiers for each attribute included in the resource. These identifiers can be used to provide names for the resource's attribute from a standard set of names the characteristics of each dimension (layer) included in the resource maximum value of data values in each dimension included in the resource. Restricted to UomLength in the MD_Band class. minimum value of data values in each dimension included in the resource. Restricted to UomLength in the MD_Band class. units of data in each dimension included in the resource. Note that the type of this is UnitOfMeasure and that it is restricted to UomLength in the MD_Band class. scale factor which has been applied to the cell value the physical value corresponding to a cell value of zero mean value of data values in each dimension included in the resource this gives the number of values used in a thematicClassification resource EX:. the number of classes in a Land Cover Type coverage or the number of cells with data in other types of coverages standard deviation of data values in each dimension included in the resource type of other attribute description (i.e. netcdf/variable in ncml.xsd) instance of otherAttributeType that defines attributes not explicitly included in MD_CoverageType maximum number of significant bits in the uncompressed representation for the value in each band of each pixel ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/2.0/contentInformationImagery.xsd ================================================ Description: extensions to electromagnetic spectrum wavelength description shortName: BandExt Description: Designation of criterion for defining maximum and minimum wavelengths for a spectral band FGDC: Band_Boundry_Definition Position: 1 shortName: bBndDef Description: Smallest distance between which separate points can be distinguished, as specified in instrument design FGDC: Nominal_Spatial_Resolution Position: 4 shortName: bndRes Description: transform function to be used when scaling a physical value for a given element shortName: scalXfrFunc Description: polarisation of the transmitter or detector shortName: polarisation Description: polarisation of the transmitter or detector shortName: polarisation Description: polarisation of the transmitter or detector shortName: polarisation Description: Designation of criterion for defining maximum and minimum wavelengths for a spectral band FGDC: Band_Boundry_Definition shortName: BndDef Description: information about the content of a coverage, including the description of specific range elements shortName: CCovDesc Description: information about the content of an image, including the description of specific range elements shortName: ICovDesc Description: polarisation of the antenna relative to the waveform shortName: PolarOrienCode Description: description of specific range elements shortName: RgEltDesc Description: designation associated with a set of range elements shortName: rgEltName Description: description of a set of specific range elements shortName: rgEltDef Description: specific range elements, i.e. range elements associated with a name and definition defining their meaning shortName: rgElt Description: transform function to be used when scaling a physical value for a given element shortName: XfrFuncTypeCode ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/2.0/mrc.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document schema and amount of content in a structured resource.</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrd/1.0/distribution.xsd ================================================ technical means and media by which a resource is obtained from the distributor tiles, layers, geographic areas, etc., in which data is available NOTE: unitsOfDistribution applies to both onLine and offLine distributions estimated size of a unit in the specified transfer format, expressed in megabytes. The transfer size is > 0.0 information about online sources from which the resource can be obtained information about offline media on which the resource can be obtained rate of occurrence of distribution format of distribution information about the distributor of and options for obtaining the resource information about the distributor party from whom the resource may be obtained. This list need not be exhaustive description of the computer language construct that specifies the representation of data objects in a record, file, message, storage device or transmission channel citation/URL of the specification for the format amendment number of the format version recommendations of algorithms or processes that can be applied to read or expand resources to which compression techniques have been applied medium used by the format information about the media on which the resource can be distributed name of the medium on which the resource can be received density at which the data is recorded units of measure for the recording density number of items in the media identified method used to write to the medium description of other limitations or requirements for using the medium method used to write to the medium common ways in which the resource may be obtained or received, and related instructions and fee information fees and terms for retrieving the resource. Include monetary units (as specified in ISO 4217) date and time when the resource will be available general instructions, terms and services provided by the distributor typical turnaround time for the filling of an order description of the order options record request/purchase choices ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrd/1.0/mrd.sch ================================================ The medium define a density without unit. La densité du média est définie sans unité. Medium density is "" (unit: ""). La densité du média est "" (unité : ""). Medium having density MUST specified density units Un média précisant une densité DOIT préciser l'unité ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrd/1.0/mrd.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to specify how various representations(distributions) of a resource can be obtained</font>. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mri/1.0/identification.xsd ================================================ justification for the correlation of two resources type of aggregation activity in which resources are related associated resource information NOTE: An associated resource is a dataset composed of a collection of datasets citation information about the associated resource type of relation between the resources type of initiative under which the associated resource was produced NOTE: the activity that resulted in the associated resource reference to the metadata of the associated resource information required to identify a resource description of the resource in the producer's processing environment, including items such as the software, the computer operating system, file name, and the dataset size any other descriptive information about the resource basic information required to uniquely identify a resource or resources citation for the resource(s) brief narrative summary of the content of the resource(s) summary of the intentions with which the resource(s) was developed recognition of those who contributed to the resource(s) status of the resource(s) identification of, and means of communication with, person(s) and organisation(s) associated with the resource(s) method used to spatially represent geographic information factor which provides a general understanding of the density of spatial data in the resource resolution of the resource with respect to time main theme(s) of the resource spatial and temporal extent of the resource other documentation associated with the resource code that identifies the level of processing in the producers coding system of a resource eg. NOAA level 1B specification of a class to categorize keywords in a domain-specific vocabulary that has a binding to a formal ontology character string to label the keyword category in natural language URI of concept in ontology specified by the ontology attribute; this concept is labeled by the className: CharacterString. a reference that binds the keyword class to a formal conceptualization of a knowledge domain for use in semantic processingNOTE: Keywords in the associated MD_Keywords keyword list must be within the scope of this ontology methods used to group similar keywords keywords, their type and reference source NOTE: When the resource described is a service, one instance of MD_Keyword shall refer to the service taxonomy defined in ISO 19119, 8.3) commonly used word(s) or formalised word(s) or phrase(s) used to describe the subject subject matter used to group similar keywords name of the formally registered thesaurus or a similar authoritative source of keywords derived from ISO 19103 Scale where MD_RepresentativeFraction.denominator = 1 / Scale.measure And Scale.targetUnits = Scale.sourceUnits the number below the line in a vulgar fraction level of detail expressed as a scale factor, a distance or an angle level of detail expressed as the scale of a comparable hardcopy map or chart horizontal ground sample distance Vertical sampling distance Angular sampling measure brief textual description of the spatial resolution of the resource high-level geographic data thematic classification to assist in the grouping and search of available geographic data sets. Can be used to group keywords as well. Listed examples are not exhaustive. NOTE: It is understood there are overlaps between general categories and the user is encouraged to select the one most appropriate. high-level geographic data thematic classification to assist in the grouping and search of available geographic data sets. Can be used to group keywords as well. Listed examples are not exhaustive. NOTE: It is understood there are overlaps between general categories and the user is encouraged to select the one most appropriate. rearing of animals and/or cultivation of plantsExamples: agriculture, irrigation, aquaculture, plantations, herding, pests and diseases affecting crops and livestock flora and/or fauna in natural environment Examples: wildlife, vegetation, biological sciences, ecology, wilderness, sealife, wetlands, habitat legal land descriptions Examples: political and administrative boundaries processes and phenomena of the atmosphere Examples: cloud cover, weather, climate, atmospheric conditions, climate change, precipitation economic activities, conditions and employment Examples: production, labour, revenue, commerce, industry, tourism and ecotourism, forestry, fisheries, commercial or subsistence hunting, exploration and exploitation of resources such as minerals, oil and gas height above or below a vertical datumExamples: altitude, bathymetry, digital elevation models, slope, derived products environmental resources, protection and conservation Examples: environmental pollution, waste storage and treatment, environmental impact assessment, monitoring environmental risk, nature reserves, landscape information pertaining to earth sciences Examples: geophysical features and processes, geology, minerals, sciences dealing with the composition, structure and origin of the earth's rocks, risks of earthquakes, volcanic activity, landslides, gravity information, soils, permafrost, hydrogeology, erosion health, health services, human ecology, and safety Examples: disease and illness, factors affecting health, hygiene, substance abuse, mental and physical health, health services base maps Examples: land cover, topographic maps, imagery, unclassified images, annotations military bases, structures, activities Examples: barracks, training grounds, military transportation, information collection inland water features, drainage systems and their characteristics Examples: rivers and glaciers, salt lakes, water utilization plans, dams, currents, floods, water quality, hydrographic charts positional information and services Examples: addresses, geodetic networks, control points, postal zones and services, place names features and characteristics of salt water bodies (excluding inland waters) Examples: tides, tidal waves, coastal information, reefs information used for appropriate actions for future use of the land Examples: land use maps, zoning maps, cadastral surveys, land ownership characteristics of society and cultures Examples: settlements, anthropology, archaeology, education, traditional beliefs, manners and customs, demographic data, recreational areas and activities, social impact assessments, crime and justice, census information man-made construction Examples: buildings, museums, churches, factories, housing, monuments, shops, towers means and aids for conveying persons and/or goods Examples: roads, airports/airstrips, shipping routes, tunnels, nautical charts, vehicle or vessel location, aeronautical charts, railways energy, water and waste systems and communications infrastructure and servicesExamples: hydroelectricity, geothermal, solar and nuclear sources of energy, water purification and distribution, sewage collection and disposal, electricity and gas distribution, data communication, telecommunication, radio, communication networks region more than 100 km above the surface of the Earth brief description of ways in which the resource(s) is/are currently or has been used brief description of the resource and/or resource series usage date and time of the first use or range of uses of the resource and/or resource series applications, determined by the user for which the resource and/or resource series is not suitable identification of and means of communicating with person(s) and organisation(s) using the resource(s) response to the user-determined limitationsE.G.. 'this has been fixed in version x' ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mri/1.0/mri.sch ================================================ The dataset MUST provide a geographic description or a bounding box. Le jeu de données DOIT être décrit par une description géographique ou une emprise. The dataset geographic description is: "". La description géographique du jeu de données est "". The dataset geographic bounding box is: [W:, S:], [E:, N:], . L'emprise géographique du jeu de données est [W:, S:], [E:, N:] . Dataset extent Emprise du jeu de données A topic category MUST be specified for dataset or series. Un thème principal (ISO) DOIT être défini quand la ressource est un jeu de donnée ou une série. Number of topic category identified: . Nombre de thèmes : . Topic category for dataset and series Thème principal d'un jeu de données ou d'une série When a resource is associated, a name or a metadata reference MUST be specified. Lorsqu'une resource est associée, un nom ou une référence à une fiche DOIT être défini. The resource "" is associated. La ressource "" est associée. Associated resource name Nom ou référence à une ressource associée Resource language MUST be defined when the resource includes textual information. La langue de la resource DOIT être renseignée lorsque la ressource contient des informations textuelles. Number of resource language: . Nombre de langues de la ressource : . Resource language Langue de la ressource A service metadata SHALL refer to the service taxonomy defined in ISO19119 defining one or more value in the keyword section. Une métadonnée de service DEVRAIT référencer un type de service tel que défini dans l'ISO19119 dans la section mot clé. Number of service taxonomy specified: . Nombre de types de service : . Service taxonomy Taxonomie des services ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mri/1.0/mri.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document basic metadata properties of a described resource</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/1.0/lineage.xsd ================================================ information about the events or source data used in constructing the data specified by the scope or lack of knowledge about lineage general explanation of the data producer's knowledge about the lineage of a resource type of resource and/or extent to which the lineage information applies information about an event or transformation in the life of a resource including the process used to maintain the resource description of the event, including related parameters or tolerances requirement or purpose for the process step date, time, range or period of process step identification of, and means of communication with, person(s) and organisation(s) associated with the process step process step documentation type of resource and/or extent to which the process step applies information about the source resource used in creating the data specified by the scope detailed description of the level of the source resource level of detail expressed as a scale factor, a distance or an angle spatial reference system used by the source resource recommended reference to be used for the source resource identifier and link to source metadata type of resource and/or extent of the source ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/1.0/lineageImagery.xsd ================================================ Description: Details of the methodology by which geographic information was derived from the instrument readings FGDC: Algorithm_Information shortName: Algorithm Description: information identifying the algorithm and version or date FGDC: Algorithm_Identifiers Position: 1 shortName: algId Description: information describing the algorithm used to generate the data FGDC: Algorithm_Description Position: 2 shortName: algDesc Description: Distance between adjacent pixels shortName: nomRes Description: Distance between adjacent pixels in the scan plane shortName: scanRes Description: Distance between adjacent pixels in the object space shortName: groundRes Description: Information about an event or transformation in the life of the dataset including details of the algorithm and software used for processing FGDC: shortName: DetailProcStep Description: Report of what occured during the process step shortName: ProcStepRep Description: Name of the processing report shortName: procRepName Description: Textual description of what occurred during the process step shortName: procRepDesc Description: Type of file that contains that processing report shortName: procRepFilTyp Description: Comprehensive information about the procedure(s), process(es) and algorithm(s) applied in the process step shortName: Procsg Description: Information to identify the processing package that produced the data FGDC: Processing_Identifiers Position: 1 shortName: procInfoId Description: Reference to document describing processing software FGDC: Processing_Software_Reference Position: 2 shortName: procInfoSwRef Description: Additional details about the processing procedures FGDC: Processing_Procedure_Description Position: 3 shortName: procInfoDesc Description: Reference to documentation describing the processing FGDC: Processing_Documentation Position: 4 shortName: procInfoDoc Description: Parameters to control the processing operations, entered at run time FGDC: Command_Line_Processing_Parameter Position: 5 shortName: procInfoParam Description: information on source of data sets for processing step shortName: SrcDataset Description: Processing level of the source data shortName: procLevel Description: Distance between two adjacent pixels shortName: procResol ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/1.0/mrl.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document the lineage (provenance) of a resource</font>. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/2.0/lineage.xsd ================================================ information about the events or source data used in constructing the data specified by the scope or lack of knowledge about lineage general explanation of the data producer's knowledge about the lineage of a resource type of resource and/or extent to which the lineage information applies information about an event or transformation in the life of a resource including the process used to maintain the resource description of the event, including related parameters or tolerances requirement or purpose for the process step date, time, range or period of process step identification of, and means of communication with, person(s) and organisation(s) associated with the process step process step documentation type of resource and/or extent to which the process step applies information about the source resource used in creating the data specified by the scope detailed description of the level of the source resource level of detail expressed as a scale factor, a distance or an angle spatial reference system used by the source resource recommended reference to be used for the source resource identifier and link to source metadata type of resource and/or extent of the source ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/2.0/lineageImagery.xsd ================================================ Description: Details of the methodology by which geographic information was derived from the instrument readings FGDC: Algorithm_Information shortName: Algorithm Description: information identifying the algorithm and version or date FGDC: Algorithm_Identifiers Position: 1 shortName: algId Description: information describing the algorithm used to generate the data FGDC: Algorithm_Description Position: 2 shortName: algDesc Description: Distance between adjacent pixels shortName: nomRes Description: Distance between adjacent pixels in the scan plane shortName: scanRes Description: Distance between adjacent pixels in the object space shortName: groundRes Description: Information about an event or transformation in the life of the dataset including details of the algorithm and software used for processing FGDC: shortName: DetailProcStep Description: Report of what occured during the process step shortName: ProcStepRep Description: Name of the processing report shortName: procRepName Description: Textual description of what occurred during the process step shortName: procRepDesc Description: Type of file that contains that processing report shortName: procRepFilTyp Description: Comprehensive information about the procedure(s), process(es) and algorithm(s) applied in the process step shortName: Procsg Description: Information to identify the processing package that produced the data FGDC: Processing_Identifiers Position: 1 shortName: procInfoId Description: Reference to document describing processing software FGDC: Processing_Software_Reference Position: 2 shortName: procInfoSwRef Description: Additional details about the processing procedures FGDC: Processing_Procedure_Description Position: 3 shortName: procInfoDesc Description: Reference to documentation describing the processing FGDC: Processing_Documentation Position: 4 shortName: procInfoDoc Description: Parameters to control the processing operations, entered at run time FGDC: Command_Line_Processing_Parameter Position: 5 shortName: procInfoParam type of other property description (i.e. netcdf/variable in ncml.xsd or AdditionalAttribute in ECHO) type of other property description (i.e. netcdf/variable in ncml.xsd or AdditionalAttribute in ECHO) instance of otherPropertyType that defines attributes not explicitly included in LE_Processing Description: information on source of data sets for processing step shortName: SrcDataset Description: Processing level of the source data shortName: procLevel Description: Distance between two adjacent pixels shortName: procResol This was added as part of the 19115-2 Revision the name, as used by the process for this parameter indication if the parameter is an input to the service, an output or both a narrative explanation of the role of the parameter indication if the parameter is required indication if more than one value of the parameter may be provided type of other property description (i.e. netcdf/variable in ncml.xsd or AdditionalAttribute in ECHO) instance of otherPropertyType that defines attributes not explicitly included in LE_Processing xxx direction of parameter (in, out, in/out) direction of parameter (in, out, in/out) the parameter is an input parameter to the process the parameter is an output parameter to the process the parameter is both an input and output parameter to the process ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/2.0/mrl.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document the lineage (provenance) of a resource</font>. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrs/1.0/mrs.sch ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrs/1.0/mrs.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document the spatial reference system used to geolocate information content of a resource</font> ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrs/1.0/referenceSystem.xsd ================================================ information about the reference system identifier and codespace for reference systeme.g. EPSG::4326 type of reference system identifiede.g. geographic2D defines type of reference system used ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/1.0/msr.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document the encoding scheme used to represent geolocation in the content of a resource</font>. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/1.0/spatialRepresentation.xsd ================================================ Frequency with which modifications and deletions are made to the data after it is first produced digital mechanism used to represent spatial information code indicating the geometry represented by the grid cell value axis properties name of the axis number of elements along the axis degree of detail in the grid dataset enhancement/modifier of the dimension name EX for other time dimension 'runtime' or dimensionName = 'column' dimensionTitle = 'Longitude' Description of the axis name of the dimension name of point or vector objects used to locate zero-, one-, two-, or three-dimensional spatial locations in the dataset number of objects, listed by geometric object type, used in the dataset name of point or vector objects used to locate zero-, one-, two-, or three-dimensional spatial locations in the dataset total number of the point or vector object type occurring in the dataset grid whose cells are regularly spaced in a geographic (i.e., lat / long) or map coordinate system defined in the Spatial Referencing System (SRS) so that any cell in the grid can be geolocated given its grid coordinate and the grid origin, cell spacing, and orientation indication of whether or not geographic position points are available to test the accuracy of the georeferenced grid data description of geographic position points used to test the accuracy of the georeferenced grid data earth location in the coordinate system defined by the Spatial Reference System and the grid coordinate of the cells at opposite ends of grid coverage along two diagonals in the grid spatial dimensions. There are four corner points in a georectified grid; at least two corner points along one diagonal are required. The first corner point corresponds to the origin of the grid. earth location in the coordinate system defined by the Spatial Reference System and the grid coordinate of the cell halfway between opposite ends of the grid in the spatial dimensions point in a pixel corresponding to the Earth location of the pixel general description of the transformation information about which grid axes are the spatial (map) axes grid with cells irregularly spaced in any given geographic/map projection coordinate system, whose individual cells can be geolocated using geolocation information supplied with the data but cannot be geolocated from the grid properties alone indication of whether or not control point(s) exists indication of whether or not orientation parameters are available description of parameters used to describe sensor orientation terms which support grid data georeferencing reference providing description of the parameters information about grid spatial objects in the resource number of independent spatial-temporal axes information about spatial-temporal axis properties identification of grid data as point or cell indication of whether or not parameters for transformation between image coordinates and geographic or map coordinates exist (are available) point in a pixel corresponding to the Earth location of the pixel point in a pixel corresponding to the Earth location of the pixel point halfway between the lower left and the upper right of the pixel the corner in the pixel closest to the origin of the SRS; if two are at the same distance from the origin, the one with the smallest x-value next corner counterclockwise from the lower left next corner counterclockwise from the lower right next corner counterclockwise from the upper right degree of complexity of the spatial relationships information about the vector spatial objects in the resource code which identifies the degree of complexity of the spatial relationships information about the geometric objects used in the resource ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/1.0/spatialRepresentationImagery.xsd ================================================ Name: SpatialRepresentation Position: 3 Description: extends georectified grid description to include associated checkpoints shortName: IGeorect Description: Description of information provided in metadata that allows the geographic or map location raster points to be located FGDC: Georeferencing_Description shortName: IGeoref ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/2.0/msr.xsd ================================================ Namespace for XML elements <font color="#1f497d">used to document the encoding scheme used to represent geolocation in the content of a resource</font>. ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/2.0/spatialRepresentation.xsd ================================================ Frequency with which modifications and deletions are made to the data after it is first produced digital mechanism used to represent spatial information level and extent of the spatial representation code indicating the geometry represented by the grid cell value axis properties name of the axis number of elements along the axis degree of detail in the grid dataset enhancement/modifier of the dimension name EX for other time dimension 'runtime' or dimensionName = 'column' dimensionTitle = 'Longitude' Description of the axis name of the dimension name of point or vector objects used to locate zero-, one-, two-, or three-dimensional spatial locations in the dataset number of objects, listed by geometric object type, used in the dataset name of point or vector objects used to locate zero-, one-, two-, or three-dimensional spatial locations in the dataset total number of the point or vector object type occurring in the dataset grid whose cells are regularly spaced in a geographic (i.e., lat / long) or map coordinate system defined in the Spatial Referencing System (SRS) so that any cell in the grid can be geolocated given its grid coordinate and the grid origin, cell spacing, and orientation indication of whether or not geographic position points are available to test the accuracy of the georeferenced grid data description of geographic position points used to test the accuracy of the georeferenced grid data earth location in the coordinate system defined by the Spatial Reference System and the grid coordinate of the cells at opposite ends of grid coverage along two diagonals in the grid spatial dimensions. There are four corner points in a georectified grid; at least two corner points along one diagonal are required. The first corner point corresponds to the origin of the grid. earth location in the coordinate system defined by the Spatial Reference System and the grid coordinate of the cell halfway between opposite ends of the grid in the spatial dimensions point in a pixel corresponding to the Earth location of the pixel general description of the transformation information about which grid axes are the spatial (map) axes grid with cells irregularly spaced in any given geographic/map projection coordinate system, whose individual cells can be geolocated using geolocation information supplied with the data but cannot be geolocated from the grid properties alone indication of whether or not control point(s) exists indication of whether or not orientation parameters are available description of parameters used to describe sensor orientation terms which support grid data georeferencing reference providing description of the parameters information about grid spatial objects in the resource number of independent spatial-temporal axes information about spatial-temporal axis properties identification of grid data as point or cell indication of whether or not parameters for transformation between image coordinates and geographic or map coordinates exist (are available) point in a pixel corresponding to the Earth location of the pixel point in a pixel corresponding to the Earth location of the pixel point halfway between the lower left and the upper right of the pixel the corner in the pixel closest to the origin of the SRS; if two are at the same distance from the origin, the one with the smallest x-value next corner counterclockwise from the lower left next corner counterclockwise from the lower right next corner counterclockwise from the upper right degree of complexity of the spatial relationships information about the vector spatial objects in the resource code which identifies the degree of complexity of the spatial relationships information about the geometric objects used in the resource ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/2.0/spatialRepresentationImagery.xsd ================================================ Name: SpatialRepresentation Position: 3 Description: extends georectified grid description to include associated checkpoints shortName: IGeorect Description: Description of information provided in metadata that allows the geographic or map location raster points to be located FGDC: Georeferencing_Description shortName: IGeoref ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.0/serviceInformation.xsd ================================================ class of information to which the referencing entity applies links a given operationName (mandatory attribute of SV_OperationMetadata) with a data set identified by an 'identifier' scoped identifier of the resource in the context of the given service instance NOTE: name of the resources (i.e. dataset) as it is used by a service instance (e.g. layer name or featureTypeName). reference to the dataset on which the service operates class of information to which the referencing entity applies Operation Chain Information the name, as used by the service for this chain a narrative explanation of the services in the chain and resulting output describes the signature of one and only one method provided by the service a unique identifier for this interface distributed computing platforms on which the operation has been implemented free text description of the intent of the operation and the results of the operation the name used to invoke this interface within the context of the DCP. The name is identical for all DCPs. handle for accessing the service interface parameter information the name, as used by the service for this parameter indication if the parameter is an input to the service, an output or both a narrative explanation of the role of the parameter indication if the parameter is required indication if more than one value of the parameter may be provided class of information to which the referencing entity applies class of information to which the referencing entity applies the parameter is an input parameter to the service instance the parameter is an output parameter to the service instance the parameter is both an input and output parameter to the service instance identification of capabilities which a service provider makes available to a service user through a set of interfaces that define a behaviour - See ISO 19119 for further information a service type name, E.G. 'discovery', 'view', 'download', 'transformation', or 'invoke' provide for searching based on the version of serviceType. For example, we may only be interested in OGC Catalogue V1.1 services. If version is maintained as a separate attribute, users can easily search for all services of a type regardless of the version information about the availability of the service, including, 'fees' 'planned' 'available date and time' 'ordering instructions' 'turnaround' type of coupling between service and associated data (if exists) further description of the data coupling in the case of tightly coupled services provides a reference to the dataset on which the service operates ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.0/srv.sch ================================================ The service identification does not contain chain or operation. L'identification du service ne contient ni chaîne d'opérations, ni opération. The service identification contains the following number of chains: . and number of operations: . L'identification du service contient le nombre de chaînes d'opérations suivant : . le nombre d'opérations : . Service identification MUST contains chain or operations L'identification du service DOIT contenir des chaînes d'opérations ou des opérations The service identification MUST specify coupling type when coupled resource exist L'identification du service DOIT définir un type de couplage lorsqu'une ressource est couplée. Number of coupled resources: . Coupling type: "". Nombre de ressources couplées : . Type de couplage : "". Service identification MUST specify coupling type when coupled resource exist L'identification du service DOIT définir un type de couplage lorsqu'une ressource est couplée The service identification define operatedDataset. No operatesOn can be specified. L'identification du service utilise operatedDataset. OperatesOn ne peut être utilisé dans ce cas. Service identification only use operated dataset. L'identification du service n'utilise que operatedDataset. Service identification MUST not use both operatedDataset and operatesOn L'identification du service NE DOIT PAS utiliser en même temps operatedDataset et operatesOn The service identification define operatesOn. No operatedDataset can be specified. L'identification du service utilise operatesOn. OperatedDataset ne peut être utilisé dans ce cas. The service identification only use operates on. L'identification du service n'utilise que des éléments de type operatesOn. Service identification MUST not use both operatesOn and operatedDataset L'identification du service NE DOIT PAS utiliser en même temps operatesOn et operatedDataset The coupled resource does not contains a resource nor a resource reference. La ressource couplée ne contient ni une ressource ni une référence à une ressource. The coupled resource contains a resource or a resource reference. La ressource couplée contient une ressource ou une référence à une ressource. Coupled resource MUST contains a resource or a resource reference Une ressource couplée DOIT définir une ressource ou une référence à une ressource The coupled resource contains both a resource and a resource reference. La ressource couplée utilise à la fois une ressource et une référence à une ressource. The coupled resource contains only resources. La ressource couplée contient uniquement des ressources. Coupled resource MUST not use both resource and resource reference Une ressource couplée NE DOIT PAS utiliser en même temps une ressource et une référence à une ressource The coupled resource contains both a resource and a resource reference. La ressource couplée utilise à la fois une ressource et une référence à une ressource. The coupled resource contains only resource references. La ressource couplée contient uniquement des références à des ressources. Coupled resource MUST not use both resource and resource reference Une ressource couplée NE DOIT PAS utiliser en même temps une ressource et une référence à une ressource ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.0/srv.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.1/serviceInformation.xsd ================================================ class of information to which the referencing entity applies links a given operationName (mandatory attribute of SV_OperationMetadata) with a data set identified by an 'identifier' scoped identifier of the resource in the context of the given service instance NOTE: name of the resources (i.e. dataset) as it is used by a service instance (e.g. layer name or featureTypeName). reference to the dataset on which the service operates class of information to which the referencing entity applies Operation Chain Information the name, as used by the service for this chain a narrative explanation of the services in the chain and resulting output describes the signature of one and only one method provided by the service a unique identifier for this interface distributed computing platforms on which the operation has been implemented free text description of the intent of the operation and the results of the operation the name used to invoke this interface within the context of the DCP. The name is identical for all DCPs. handle for accessing the service interface parameter information the name, as used by the service for this parameter indication if the parameter is an input to the service, an output or both a narrative explanation of the role of the parameter indication if the parameter is required indication if more than one value of the parameter may be provided class of information to which the referencing entity applies class of information to which the referencing entity applies the parameter is an input parameter to the service instance the parameter is an output parameter to the service instance the parameter is both an input and output parameter to the service instance identification of capabilities which a service provider makes available to a service user through a set of interfaces that define a behaviour - See ISO 19119 for further information a service type name, E.G. 'discovery', 'view', 'download', 'transformation', or 'invoke' provide for searching based on the version of serviceType. For example, we may only be interested in OGC Catalogue V1.1 services. If version is maintained as a separate attribute, users can easily search for all services of a type regardless of the version information about the availability of the service, including, 'fees' 'planned' 'available date and time' 'ordering instructions' 'turnaround' type of coupling between service and associated data (if exists) further description of the data coupling in the case of tightly coupled services provides a reference to the dataset on which the service operates ================================================ FILE: pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.1/srv.xsd ================================================ ================================================ FILE: pycsw/plugins/profiles/profile.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2024 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import os import warnings class Profile(object): ''' base Profile class ''' def __init__(self, name, version, title, url, namespace, typename, outputschema, prefixes, model, core_namespaces, added_namespaces,repository): ''' Initialize profile ''' self.name = name self.version = version self.title = title self.url = url self.namespace = namespace self.typename = typename self.outputschema = outputschema self.prefixes = prefixes self.repository = repository if 'DescribeRecord' in model['operations']: model['operations']['DescribeRecord']['parameters']\ ['typeName']['values'].append(self.typename) model['operations']['GetRecords']['parameters']['outputSchema']\ ['values'].append(self.outputschema) model['operations']['GetRecords']['parameters']['typeNames']\ ['values'].append(self.typename) model['operations']['GetRecordById']['parameters']['outputSchema']\ ['values'].append(self.outputschema) if 'Harvest' in model['operations']: model['operations']['Harvest']['parameters']['ResourceType']\ ['values'].append(self.outputschema) # namespaces core_namespaces.update(added_namespaces) # repository model['typenames'][self.typename] = self.repository def extend_core(self, model, namespaces, config): ''' Extend config.model and config.namespaces ''' raise NotImplementedError def check_parameters(self): ''' Perform extra parameters checking. Return dict with keys "locator", "code", "text" or None ''' raise NotImplementedError def get_extendedcapabilities(self): ''' Return ExtendedCapabilities child as lxml.etree.Element ''' raise NotImplementedError def get_schemacomponents(self): ''' Return schema components as lxml.etree.Element list ''' raise NotImplementedError def check_getdomain(self, kvp): '''Perform extra profile specific checks in the GetDomain request''' raise NotImplementedError def write_record(self, result, esn, outputschema, queryables): ''' Return csw:SearchResults child as lxml.etree.Element ''' raise NotImplementedError def transform2dcmappings(self, queryables): ''' Transform information model mappings into csw:Record mappings ''' raise NotImplementedError def load_profiles(path, cls, profiles): ''' load CSW profiles, return dict by class name ''' def look_for_subclass(modulename): module = __import__(modulename) dmod = module.__dict__ for modname in modulename.split('.')[1:]: dmod = dmod[modname].__dict__ for key, entry in dmod.items(): if key == cls.__name__: continue try: if issubclass(entry, cls): aps['plugins'][key] = entry except TypeError: continue aps = {} aps['plugins'] = {} aps['loaded'] = {} for prof in profiles: # fgdc, atom, dif, gm03 are supported in core # no need to specify them explicitly anymore # provide deprecation warning # https://github.com/geopython/pycsw/issues/118 if prof in ['fgdc', 'atom', 'dif', 'gm03']: warnings.warn('%s is now a core module, and does not need to be' ' specified explicitly. So you can remove %s from ' 'server.profiles' % (prof, prof)) else: modulename='%s.%s.%s' % (path.replace(os.sep, '.'), prof, prof) look_for_subclass(modulename) return aps ================================================ FILE: pycsw/plugins/repository/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/plugins/repository/odc/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/plugins/repository/odc/odc.py ================================================ #-*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from django.db import connection from django.db.models import Max, Min, Count from django.conf import settings from pycsw.core import repository, util from OpenDataCatalog.opendata.models import Resource class OpenDataCatalogRepository(object): ''' Class to interact with underlying repository ''' def __init__(self, context, repo_filter=None): ''' Initialize repository ''' self.context = context self.filter = repo_filter self.fts = False self.dbtype = settings.DATABASES['default']['ENGINE'].split('.')[-1] # ODC PostgreSQL installs are not PostGIS enabled if self.dbtype == 'postgresql_psycopg2': self.dbtype = 'postgresql' if self.dbtype in ['sqlite', 'sqlite3']: # load SQLite query bindings cursor = connection.cursor() connection.connection.create_function( 'query_spatial', 4, util.query_spatial) connection.connection.create_function( 'get_anytext', 1, repository.get_anytext) connection.connection.create_function( 'get_geometry_area', 1, util.get_geometry_area) # generate core queryables db and obj bindings self.queryables = {} for tname in self.context.model['typenames']: for qname in self.context.model['typenames'][tname]['queryables']: self.queryables[qname] = {} for qkey, qvalue in \ self.context.model['typenames'][tname]['queryables'][qname].items(): self.queryables[qname][qkey] = qvalue # flatten all queryables # TODO smarter way of doing this self.queryables['_all'] = {} for qbl in self.queryables: self.queryables['_all'].update(self.queryables[qbl]) self.queryables['_all'].update(self.context.md_core_model['mappings']) def query_ids(self, ids): ''' Query by list of identifiers ''' # identifiers are URN masked, where the last token of the identifier # is opendata.models.Resource.id (integer) # if ids are passed which are not int, silently return (does not exist) try: return self._get_repo_filter(Resource.objects).filter(id__in=[s.split(':')[-1] for s in ids]).all() except Exception as err: return [] def query_domain(self, domain, typenames, domainquerytype='list', count=False): ''' Query by property domain values ''' objects = self._get_repo_filter(Resource.objects) if domainquerytype == 'range': return [tuple(objects.aggregate( Min(domain), Max(domain)).values())] else: if count: return [(d[domain], d['%s__count' % domain]) \ for d in objects.values(domain).annotate(Count(domain))] else: return objects.values_list(domain).distinct() def query_insert(self, direction='max'): ''' Query to get latest (default) or earliest update to repository ''' if direction == 'min': return Resource.objects.aggregate( Min('last_updated'))['last_updated__min'].strftime('%Y-%m-%dT%H:%M:%SZ') return self._get_repo_filter(Resource.objects).aggregate( Max('last_updated'))['last_updated__max'].strftime('%Y-%m-%dT%H:%M:%SZ') def query_source(self, source): ''' Query by source ''' return self._get_repo_filter(Resource.objects).filter(source=source) def query(self, constraint, sortby=None, typenames=None, maxrecords=10, startposition=0): ''' Query records from underlying repository ''' # run the raw query and get total if 'where' in constraint: # GetRecords with constraint query = self._get_repo_filter(Resource.objects).extra(where=[constraint['where']], params=constraint['values']) else: # GetRecords sans constraint query = self._get_repo_filter(Resource.objects) total = query.count() # apply sorting, limit and offset if sortby is not None: if 'spatial' in sortby and sortby['spatial']: # spatial sort desc = False if sortby['order'] == 'DESC': desc = True query = query.all() return [str(total), sorted(query, key=lambda x: float(util.get_geometry_area(getattr(x, sortby['propertyname']))), reverse=desc)[startposition:startposition+int(maxrecords)]] if sortby['order'] == 'DESC': pname = '-%s' % sortby['propertyname'] else: pname = sortby['propertyname'] return [str(total), \ query.order_by(pname)[startposition:startposition+int(maxrecords)]] else: # no sort return [str(total), query.all()[startposition:startposition+int(maxrecords)]] def _get_repo_filter(self, query): ''' Apply repository wide side filter / mask query ''' if self.filter is not None: return query.extra(where=[self.filter]) return query ================================================ FILE: pycsw/server.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2015 Angelos Tzotsos # Copyright (c) 2016 James Dickens # Copyright (c) 2016 Ricardo Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import logging import os from urllib.parse import parse_qsl, urlparse from io import StringIO import sys from time import time import wsgiref.util from pycsw.core.etree import etree from pycsw import oaipmh, opensearch, sru from pycsw.plugins.profiles import profile as pprofile import pycsw.plugins.outputschemas from pycsw.core import config, log, util from pycsw.ogc.api.util import yaml_load from pycsw.ogc.csw import csw2, csw3 LOGGER = logging.getLogger(__name__) class Csw(object): """ Base CSW server """ def __init__(self, rtconfig=None, env=None, version='3.0.0'): """ Initialize CSW """ self.environ = env or os.environ self.context = config.StaticContext() # Lazy load this when needed # (it will permanently update global cfg namespaces) self.sruobj = None self.opensearchobj = None self.oaipmhobj = None # init kvp self.kvp = {} self.mode = 'csw' self.asynchronous = False self.soap = False self.request = None self.exception = False self.status = 'OK' self.profiles = None self.manager = False self.outputschemas = {} self.mimetype = 'application/xml; charset=UTF-8' self.encoding = 'UTF-8' self.pretty_print = 0 self.domainquerytype = 'list' self.orm = 'django' self.language = {'639_code': 'en', 'text': 'english'} self.process_time_start = time() self.xslts = [] # define CSW implementation object (default CSW3) self.iface = csw3.Csw3(server_csw=self) self.request_version = version if self.request_version == '2.0.2': self.iface = csw2.Csw2(server_csw=self) self.context.set_model('csw') # load user configuration try: LOGGER.info('Loading user configuration') if isinstance(rtconfig, dict): # dictionary self.config = rtconfig else: # configuration file with open(rtconfig, encoding='utf8') as fh: self.config = yaml_load(fh) except Exception as err: msg = 'Could not load configuration' LOGGER.exception('%s %s: %s', msg, rtconfig, err) self.response = self.iface.exceptionreport( 'NoApplicableCode', 'service', msg) return # set server.home safely # TODO: make this more abstract self.config['server']['home'] = os.path.dirname(os.path.join(os.path.dirname(__file__), '..')) if 'PYCSW_IS_CSW' in self.environ and self.environ['PYCSW_IS_CSW']: self.config['server']['url'] = self.config['server']['url'].rstrip('/') + '/csw' if 'PYCSW_IS_OPENSEARCH' in self.environ and self.environ['PYCSW_IS_OPENSEARCH']: self.config['server']['url'] = self.config['server']['url'].rstrip('/') + '/opensearch' self.mode = 'opensearch' self.context.pycsw_home = self.config['server'].get('home') self.context.url = self.config['server']['url'] self.context.server = self log.setup_logger(self.config.get('logging', {})) LOGGER.info('running configuration %s', rtconfig) LOGGER.debug('QUERY_STRING: %s', self.environ['QUERY_STRING']) # set OGC schemas location if 'ogc_schemas_base' not in self.config['server']: self.config['server']['ogc_schemas_base'] = self.context.ogc_schemas_base # set mimetype if 'mimetype' in self.config['server']: self.mimetype = self.config['server']['mimetype'].encode() # set encoding if 'encoding' in self.config['server']: self.encoding = self.config['server']['encoding'] # set domainquerytype if 'domainquerytype' in self.config['server']: self.domainquerytype = self.config['server']['domainquerytype'] # set XML pretty print if self.config['server'].get('pretty_print', False): self.pretty_print = 1 # set Spatial Ranking option if self.config['server'].get('spatial_ranking', False): util.ranking_enabled = True # set language default if 'language' in self.config['server']: try: LOGGER.info('Setting language') lang_code = self.config['server']['language'].split('-')[0] self.language['639_code'] = lang_code self.language['text'] = self.context.languages[lang_code] except Exception as err: LOGGER.exception('Could not set language: %s', err) pass LOGGER.debug('Configuration: %s.', self.config) LOGGER.debug('Model: %s.', self.context.model) # load user-defined mappings if they exist custom_mappings_path = self.config['repository'].get('mappings') if custom_mappings_path is not None: md_core_model = util.load_custom_repo_mappings(custom_mappings_path) if md_core_model is not None: self.context.md_core_model = md_core_model self.context.refresh_dc(md_core_model) else: LOGGER.exception('Could not load custom mappings: %s') self.response = self.iface.exceptionreport( 'NoApplicableCode', 'service', 'Could not load repository.mappings') # load user-defined max attempt to retry db connection self.max_retries = int(self.config['repository'].get('max_retries', 5)) # load outputschemas LOGGER.info('Loading outputschemas') for osch in pycsw.plugins.outputschemas.__all__: output_schema_module = __import__( 'pycsw.plugins.outputschemas.%s' % osch) mod = getattr(output_schema_module.plugins.outputschemas, osch) self.outputschemas[mod.NAMESPACE] = mod LOGGER.debug('Outputschemas loaded: %s.', self.outputschemas) LOGGER.debug('Namespaces: %s', self.context.namespaces) LOGGER.info('Loading XSLT transformations') for x in self.config.get('xslt', []): LOGGER.debug('Loading XSLT %s' % x['transform']) input_os = x['input_os'] output_os = x['output_os'] self.xslts.append({ f'xslt:{input_os},{output_os}': x['transform'] }) # TODO: add output schemas to namespace prefixes def expand_path(self, path): """ return safe path for WSGI environments """ if 'local.app_root' in self.environ and not os.path.isabs(path): return os.path.join(self.environ['local.app_root'], path) else: return path def dispatch_wsgi(self): """ WSGI handler """ if hasattr(self, 'response'): return self._write_response() LOGGER.debug('WSGI mode detected') if self.environ['REQUEST_METHOD'] == 'POST': try: request_body_size = int(self.environ.get('CONTENT_LENGTH', 0)) except (ValueError): request_body_size = 0 self.requesttype = 'POST' self.request = self.environ['wsgi.input'].read(request_body_size) LOGGER.debug('Request type: POST. Request:\n%s\n', self.request) else: # it's a GET request self.requesttype = 'GET' self.request = wsgiref.util.request_uri(self.environ) try: if '{' in self.request or '%7D' in self.request: LOGGER.debug('Looks like an OpenSearch URL template') query_part = self.request.split('?', 1)[-1] else: query_part = urlparse(self.request).query self.kvp = dict(parse_qsl(query_part, keep_blank_values=True)) except AttributeError as err: LOGGER.exception('Could not parse query string') self.kvp = {} LOGGER.debug('Request type: GET. Request:\n%s\n', self.request) return self.dispatch() def opensearch(self): """ enable OpenSearch """ if not self.opensearchobj: self.opensearchobj = opensearch.OpenSearch(self.context) return self.opensearchobj def sru(self): """ enable SRU """ if not self.sruobj: self.sruobj = sru.Sru(self.context) return self.sruobj def oaipmh(self): """ enable OAI-PMH """ if not self.oaipmhobj: self.oaipmhobj = oaipmh.OAIPMH(self.context, self.config) return self.oaipmhobj def dispatch(self, writer=sys.stdout, write_headers=True): """ Handle incoming HTTP request """ error = 0 if self.requesttype == 'GET': self.kvp = self.normalize_kvp(self.kvp) version_202 = ('version' in self.kvp and self.kvp['version'] == '2.0.2') accept_version_202 = ('acceptversions' in self.kvp and '2.0.2' in self.kvp['acceptversions']) if version_202 or accept_version_202: self.request_version = '2.0.2' elif self.requesttype == 'POST': if self.request.find(b'cat/csw/2.0.2') != -1: self.request_version = '2.0.2' elif self.request.find(b'cat/csw/3.0') != -1: self.request_version = '3.0.0' if 'PYCSW_IS_OAIPMH' in self.environ and self.environ['PYCSW_IS_OAIPMH']: self.config['server']['url'] = self.config['server']['url'].rstrip('/') + '/oaipmh' self.kvp['mode'] = 'oaipmh' if 'PYCSW_IS_SRU' in self.environ and self.environ['PYCSW_IS_SRU']: self.config['server']['url'] = self.config['server']['url'].rstrip('/') + '/sru' self.kvp['mode'] = 'sru' if (not isinstance(self.kvp, str) and 'mode' in self.kvp and self.kvp['mode'] == 'sru'): self.mode = 'sru' self.request_version = '2.0.2' LOGGER.info('SRU mode detected; processing request') self.kvp = self.sru().request_sru2csw(self.kvp) if (not isinstance(self.kvp, str) and 'mode' in self.kvp and self.kvp['mode'] == 'oaipmh'): self.mode = 'oaipmh' self.request_version = '2.0.2' LOGGER.info('OAI-PMH mode detected; processing request.') self.oaiargs = dict((k, v) for k, v in self.kvp.items() if k) self.kvp = self.oaipmh().request(self.kvp) if self.request_version == '2.0.2': self.iface = csw2.Csw2(server_csw=self) self.context.set_model('csw') # configure transaction support, if specified in config self._gen_manager() namespaces = self.context.namespaces ops = self.context.model['operations'] constraints = self.context.model['constraints'] # generate domain model # NOTE: We should probably avoid this sort of mutable state for WSGI if 'GetDomain' not in ops: ops['GetDomain'] = self.context.gen_domains() # generate distributed search model, if specified in config if 'federatedcatalogues' in self.config: LOGGER.info('Configuring distributed search') constraints['FederatedCatalogues'] = {'values': []} for fedcat in self.config['federatedcatalogues']: LOGGER.debug('federated catalogue: %s', fedcat) if fedcat['type'] == 'CSW': constraints['FederatedCatalogues']['values'].append(fedcat['url']) for key, value in self.outputschemas.items(): get_records_params = ops['GetRecords']['parameters'] get_records_params['outputSchema']['values'].append( value.NAMESPACE) get_records_by_id_params = ops['GetRecordById']['parameters'] get_records_by_id_params['outputSchema']['values'].append( value.NAMESPACE) if 'Harvest' in ops: harvest_params = ops['Harvest']['parameters'] harvest_params['ResourceType']['values'].append( value.NAMESPACE) LOGGER.info('Setting MaxRecordDefault') if 'maxrecords' in self.config['server']: constraints['MaxRecordDefault']['values'] = [ self.config['server']['maxrecords']] # load profiles if 'profiles' in self.config: self.profiles = pprofile.load_profiles( os.path.join('pycsw', 'plugins', 'profiles'), pprofile.Profile, self.config['profiles'] ) for prof in self.profiles['plugins'].keys(): tmp = self.profiles['plugins'][prof](self.context.model, namespaces, self.context) key = tmp.outputschema # to ref by outputschema self.profiles['loaded'][key] = tmp self.profiles['loaded'][key].extend_core(self.context.model, namespaces, self.config) LOGGER.debug('Profiles loaded: %s' % list(self.profiles['loaded'].keys())) # init repository # look for tablename, set 'records' as default if 'table' not in self.config['repository']: self.config['repository']['table'] = 'records' repo_filter = self.config['repository'].get('filter') if 'source' in self.config['repository']: # load custom repository rs = self.config['repository']['source'] rs_modname, rs_clsname = rs.rsplit('.', 1) rs_mod = __import__(rs_modname, globals(), locals(), [rs_clsname]) rs_cls = getattr(rs_mod, rs_clsname) try: connection_done = False max_attempts = 0 while not connection_done and max_attempts <= self.max_retries: try: self.repository = rs_cls(self.context, repo_filter) LOGGER.debug('Custom repository %s loaded (%s)', rs, self.repository.dbtype) connection_done = True except Exception as err: LOGGER.debug(f'Repository not loaded retry connection {max_attempts}: {err}') max_attempts += 1 except Exception as err: msg = 'Could not load custom repository %s: %s' % (rs, err) LOGGER.exception(msg) error = 1 code = 'NoApplicableCode' locator = 'service' text = 'Could not initialize repository. Check server logs' else: # load default repository self.orm = 'sqlalchemy' from pycsw.core import repository try: LOGGER.info('Loading default repository') connection_done = False max_attempts = 0 while not connection_done and max_attempts <= self.max_retries: try: self.repository = repository.Repository( self.config['repository']['database'], self.context, self.environ.get('local.app_root', None), self.config['repository'].get('table'), repo_filter, self.config['repository'].get('stable_sort', False) ) LOGGER.debug( 'Repository loaded (local): %s.' % self.repository.dbtype) connection_done = True except Exception as err: LOGGER.debug(f'Repository not loaded retry connection {max_attempts}: {err}') max_attempts += 1 except Exception as err: msg = 'Could not load repository (local): %s' % err LOGGER.exception(msg) error = 1 code = 'NoApplicableCode' locator = 'service' text = 'Could not initialize repository. Check server logs' if self.requesttype == 'POST': LOGGER.debug('HTTP POST request') LOGGER.debug('CSW version: %s', self.iface.version) self.kvp = self.iface.parse_postdata(self.request) if isinstance(self.kvp, str): # it's an exception error = 1 locator = 'service' text = self.kvp if (self.kvp.find('the document is not valid') != -1 or self.kvp.find('document not well-formed') != -1): code = 'NoApplicableCode' else: code = 'InvalidParameterValue' LOGGER.debug('HTTP Headers:\n%s.', self.environ) LOGGER.debug('Parsed request parameters: %s', self.kvp) if (not isinstance(self.kvp, str) and 'mode' in self.kvp and self.kvp['mode'] == 'opensearch'): self.mode = 'opensearch' LOGGER.info('OpenSearch mode detected; processing request.') self.kvp['outputschema'] = 'http://www.w3.org/2005/Atom' if ((len(self.kvp) == 0 and self.request_version == '3.0.0') or (len(self.kvp) == 1 and 'config' in self.kvp)): LOGGER.info('Turning on default csw30:Capabilities for base URL') self.kvp = { 'service': 'CSW', 'acceptversions': '3.0.0', 'request': 'GetCapabilities' } http_accept = self.environ.get('HTTP_ACCEPT', '') if 'application/opensearchdescription+xml' in http_accept: self.mode = 'opensearch' self.kvp['outputschema'] = 'http://www.w3.org/2005/Atom' if error == 0: # test for the basic keyword values (service, version, request) basic_options = ['service', 'request'] request = self.kvp.get('request', '') own_version_integer = util.get_version_integer( self.request_version) if self.request_version == '2.0.2': basic_options.append('version') if self.request_version == '3.0.0' and 'version' not in self.kvp and self.requesttype == 'POST': if 'service' not in self.kvp: self.kvp['service'] = 'CSW' basic_options.append('service') self.kvp['version'] = self.request_version basic_options.append('version') for k in basic_options: if k not in self.kvp: if (k in ['version', 'acceptversions'] and request == 'GetCapabilities'): pass else: error = 1 locator = k code = 'MissingParameterValue' text = 'Missing keyword: %s' % k break # test each of the basic keyword values if error == 0: # test service if self.kvp['service'] != 'CSW': error = 1 locator = 'service' code = 'InvalidParameterValue' text = 'Invalid value for service: %s.\ Value MUST be CSW' % self.kvp['service'] # test version kvp_version = self.kvp.get('version', '') try: kvp_version_integer = util.get_version_integer(kvp_version) except Exception as err: kvp_version_integer = 'invalid_value' if (request != 'GetCapabilities' and kvp_version_integer != own_version_integer): error = 1 locator = 'version' code = 'InvalidParameterValue' text = ('Invalid value for version: %s. Value MUST be ' '2.0.2 or 3.0.0' % kvp_version) # check for GetCapabilities acceptversions if 'acceptversions' in self.kvp: for vers in self.kvp['acceptversions'].split(','): vers_integer = util.get_version_integer(vers) if vers_integer == own_version_integer: break else: error = 1 locator = 'acceptversions' code = 'VersionNegotiationFailed' text = ('Invalid parameter value in ' 'acceptversions: %s. Value MUST be ' '2.0.2 or 3.0.0' % self.kvp['acceptversions']) # test request if self.kvp['request'] not in \ self.context.model['operations']: error = 1 locator = 'request' if request in ['Transaction', 'Harvest']: code = 'OperationNotSupported' text = '%s operations are not supported' % request else: code = 'InvalidParameterValue' text = 'Invalid value for request: %s' % request if error == 1: # return an ExceptionReport LOGGER.error('basic service options error: %s, %s, %s', code, locator, text) self.response = self.iface.exceptionreport(code, locator, text) else: # process per the request value if 'responsehandler' in self.kvp: # set flag to process asynchronously import threading self.asynchronous = True request_id = self.kvp.get('requestid', None) if request_id is None: import uuid self.kvp['requestid'] = str(uuid.uuid4()) if self.kvp['request'] == 'GetCapabilities': self.response = self.iface.getcapabilities() elif self.kvp['request'] == 'DescribeRecord': self.response = self.iface.describerecord() elif self.kvp['request'] == 'GetDomain': self.response = self.iface.getdomain() elif self.kvp['request'] == 'GetRecords': if self.asynchronous: # process asynchronously threading.Thread(target=self.iface.getrecords).start() self.response = self.iface._write_acknowledgement() else: self.response = self.iface.getrecords() elif self.kvp['request'] == 'GetRecordById': self.response = self.iface.getrecordbyid() elif self.kvp['request'] == 'GetRepositoryItem': self.response = self.iface.getrepositoryitem() elif self.kvp['request'] == 'Transaction': self.response = self.iface.transaction() elif self.kvp['request'] == 'Harvest': if self.asynchronous: # process asynchronously threading.Thread(target=self.iface.harvest).start() self.response = self.iface._write_acknowledgement() else: self.response = self.iface.harvest() else: self.response = self.iface.exceptionreport( 'InvalidParameterValue', 'request', 'Invalid request parameter: %s' % self.kvp['request'] ) LOGGER.info('Request processed') if self.mode == 'sru': LOGGER.info('SRU mode detected; processing response.') self.response = self.sru().response_csw2sru(self.response, self.environ) elif self.mode == 'opensearch': LOGGER.info('OpenSearch mode detected; processing response.') self.response = self.opensearch().response_csw2opensearch( self.response, self.config) elif self.mode == 'oaipmh': LOGGER.info('OAI-PMH mode detected; processing response.') self.response = self.oaipmh().response( self.response, self.oaiargs, self.repository, self.config['server']['url'] ) return self._write_response() def getcapabilities(self): """ Handle GetCapabilities request """ return self.iface.getcapabilities() def describerecord(self): """ Handle DescribeRecord request """ return self.iface.describerecord() def getdomain(self): """ Handle GetDomain request """ return self.iface.getdomain() def getrecords(self): """ Handle GetRecords request """ return self.iface.getrecords() def getrecordbyid(self, raw=False): """ Handle GetRecordById request """ return self.iface.getrecordbyid(raw) def getrepositoryitem(self): """ Handle GetRepositoryItem request """ return self.iface.getrepositoryitem() def transaction(self): """ Handle Transaction request """ return self.iface.transaction() def harvest(self): """ Handle Harvest request """ return self.iface.harvest() def _write_response(self): """ Generate response """ # set HTTP response headers and XML declaration xmldecl = '' appinfo = '' LOGGER.info('Writing response.') if hasattr(self, 'soap') and self.soap: self._gen_soap_wrapper() if etree.__version__ >= '3.5.0': # remove superfluous namespaces etree.cleanup_namespaces(self.response, keep_ns_prefixes=self.context.keep_ns_prefixes) response = etree.tostring(self.response, pretty_print=self.pretty_print, encoding='unicode') if (isinstance(self.kvp, dict) and 'outputformat' in self.kvp and self.kvp['outputformat'] == 'application/json'): self.contenttype = self.kvp['outputformat'] from pycsw.core.formats import fmt_json response = fmt_json.xml2json(response, self.context.namespaces, self.pretty_print) else: # it's XML if 'outputformat' in self.kvp: self.contenttype = self.kvp['outputformat'] else: self.contenttype = self.mimetype xmldecl = ('' '\n' % self.encoding) appinfo = '\n' % self.context.version if isinstance(self.contenttype, bytes): self.contenttype = self.contenttype.decode() s = (u'%s%s%s' % (xmldecl, appinfo, response)).encode(self.encoding) LOGGER.debug('Response code: %s', self.context.response_codes[self.status]) LOGGER.debug('Response:\n%s', s) return [self.context.response_codes[self.status], s] def _gen_soap_wrapper(self): """ Generate SOAP wrapper """ LOGGER.info('Writing SOAP wrapper.') node = etree.Element( util.nspath_eval('soapenv:Envelope', self.context.namespaces), nsmap=self.context.namespaces ) schema_location_ns = util.nspath_eval('xsi:schemaLocation', self.context.namespaces) node.attrib[schema_location_ns] = '%s %s' % ( self.context.namespaces['soapenv'], self.context.namespaces['soapenv'] ) node2 = etree.SubElement( node, util.nspath_eval('soapenv:Body', self.context.namespaces)) if self.exception: node3 = etree.SubElement( node2, util.nspath_eval('soapenv:Fault', self.context.namespaces) ) node4 = etree.SubElement( node3, util.nspath_eval('soapenv:Code', self.context.namespaces) ) etree.SubElement( node4, util.nspath_eval('soapenv:Value', self.context.namespaces) ).text = 'soap:Server' node4 = etree.SubElement( node3, util.nspath_eval('soapenv:Reason', self.context.namespaces) ) etree.SubElement( node4, util.nspath_eval('soapenv:Text', self.context.namespaces) ).text = 'A server exception was encountered.' node4 = etree.SubElement( node3, util.nspath_eval('soapenv:Detail', self.context.namespaces) ) node4.append(self.response) else: node2.append(self.response) self.response = node def _gen_manager(self): """ Update self.context.model with CSW-T advertising """ if util.str2bool(self.config['manager'].get('transactions', False)): self.manager = True self.context.model['operations_order'].append('Transaction') self.context.model['operations']['Transaction'] = { 'methods': {'get': False, 'post': True}, 'parameters': {} } schema_values = [ 'http://www.opengis.net/cat/csw/2.0.2', 'http://www.opengis.net/cat/csw/3.0', 'http://www.opengis.net/wms', 'http://www.opengis.net/wmts/1.0', 'http://www.opengis.net/wfs', 'http://www.opengis.net/wfs/2.0', 'http://www.opengis.net/wcs', 'http://www.opengis.net/wps/1.0.0', 'http://www.opengis.net/sos/1.0', 'http://www.opengis.net/sos/2.0', 'http://www.isotc211.org/2005/gmi', 'urn:geoss:waf', ] self.context.model['operations_order'].append('Harvest') self.context.model['operations']['Harvest'] = { 'methods': {'get': False, 'post': True}, 'parameters': { 'ResourceType': {'values': schema_values} } } self.context.model['operations']['Transaction'] = { 'methods': {'get': False, 'post': True}, 'parameters': { 'TransactionSchemas': {'values': sorted(schema_values)} } } self.csw_harvest_pagesize = int(self.config['manager'].get('csw_harvest_pagesize', 10)) def _test_manager(self): """ Verify that transactions are allowed """ if not util.str2bool(self.config['manager'].get('transactions', False)): raise RuntimeError('CSW-T interface is disabled') # get the client first forwarded ip if 'HTTP_X_FORWARDED_FOR' in self.environ: ipaddress = self.environ['HTTP_X_FORWARDED_FOR'].split(',')[0].strip() else: ipaddress = self.environ['REMOTE_ADDR'] if 'allowed_ips' not in self.config['manager'] or not \ util.ipaddress_in_whitelist(ipaddress, self.config['manager'].get('allowed_ips', [])): raise RuntimeError( 'CSW-T operations not allowed for this IP address: %s' % ipaddress) def _cql_update_queryables_mappings(self, cql, mappings): """ Transform CQL query's properties to underlying DB columns """ LOGGER.debug('Raw CQL text = %s', cql) LOGGER.debug(str(list(mappings.keys()))) if cql is not None: for key in mappings.keys(): try: cql = cql.replace(key, mappings[key]['dbcol']) except KeyError: LOGGER.debug('Setting without dbcol key') cql = cql.replace(key, mappings[key]) LOGGER.debug('Interpolated CQL text = %s.', cql) return cql def _process_responsehandler(self, xml): """ Process response handler """ if self.kvp['responsehandler'] is not None: LOGGER.info('Processing responsehandler %s' % self.kvp['responsehandler']) uprh = urlparse(self.kvp['responsehandler']) if uprh.scheme == 'mailto': # email import smtplib LOGGER.debug('Email detected') smtp_host = 'localhost' smtp_user = '' smtp_pass = '' smtp_ssl = False if 'smtp_host' in self.config['server']: smtp_host = self.config['server']['smtp_host'] if 'smtp_user' in self.config['server']: smtp_user = self.config['server']['smtp_user'] if 'smtp_pass' in self.config['server']: smtp_pass = self.config['server']['smtp_pass'] if 'smtp_ssl' in self.config['server']: smtp_ssl = self.config['server'].get('smtp_ssl', False) body = ('Subject: pycsw %s results\n\n%s' % (self.kvp['request'], xml)) try: LOGGER.info('Sending email') if smtp_ssl: msg = smtplib.SMTP_SSL(smtp_host, port=smtplib.SMTP_SSL_PORT) msg.login(smtp_user, smtp_pass) else: msg = smtplib.SMTP(smtp_host) msg.sendmail( self.config['metadata']['contact']['email'], uprh.path, body) msg.quit() LOGGER.debug('Email sent successfully.') except Exception as err: LOGGER.exception('Error processing email') elif uprh.scheme in ['ftp', 'ftps']: import ftplib LOGGER.debug(f'{uprh.scheme} detected.') try: LOGGER.info(f'Sending to {uprh.scheme} server.') if uprh.scheme == 'ftps': ftp = ftplib.FTP_TLS(uprh.hostname) else: ftp = ftplib.FTP(uprh.hostname) if uprh.username is not None: ftp.login(uprh.username, uprh.password) if uprh.scheme == 'ftps': ftp.prot_p() ftp.storbinary('STOR %s' % uprh.path[1:], StringIO(xml)) ftp.quit() LOGGER.debug(f'{uprh.scheme} sent successfully.') except Exception as err: LOGGER.exception(f'Error processing {uprh.scheme}') def _render_xslt(self, res): ''' Validate and render XSLT ''' LOGGER.debug('Rendering XSLT') try: input_os = res.schema output_os = self.kvp['outputschema'] xslt_id = 'xslt:%s,%s' % (input_os, output_os) xslt_dict = next(d for i, d in enumerate(self.xslts) if xslt_id in d) LOGGER.debug('XSLT ID: %s' % xslt_id) LOGGER.debug('Found matching XSLT transformation') xslt = xslt_dict[xslt_id] transform = etree.XSLT(etree.parse(xslt)) doc = etree.fromstring(res.xml, self.context.parser) result_tree = transform(doc).getroot() return result_tree except StopIteration: LOGGER.debug('No matching XSLT found') pass except Exception as err: LOGGER.warning('XSLT transformation failed: %s' % str(err)) raise RuntimeError() @staticmethod def normalize_kvp(kvp): """Normalize Key Value Pairs. This method will transform all keys to lowercase and leave values unchanged, as specified in the CSW standard (see for example note C on Table 62 - KVP Encoding for DescribeRecord operation request of the CSW standard version 2.0.2) :arg kvp: a mapping with Key Value Pairs :type kvp: dict :returns: A new dictionary with normalized parameters """ result = dict() for name, value in kvp.items(): result[name.lower()] = value return result ================================================ FILE: pycsw/sru.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2015 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from pycsw.core import util from pycsw.core.etree import etree from pycsw.ogc.fes import fes1 class Sru(object): """SRU wrapper class""" def __init__(self, context): self.sru_version = '1.1' self.namespaces = { 'zd': 'http://www.loc.gov/zing/srw/diagnostic/', 'sru': 'http://www.loc.gov/zing/srw/', 'zr': 'http://explain.z3950.org/dtd/2.1/', 'zs': 'http://www.loc.gov/zing/srw/', 'srw_dc': 'info:srw/schema/1/dc-schema' } self.mappings = { 'csw:Record': { 'schema': { 'name': 'dc', 'identifier': 'info:srw/cql-context-set/1/dc-v1.1', }, 'index': { # map OGC queryables to XPath expressions 'title': '4', 'creator': '1003', 'subject': '29', 'abstract': '62', 'publisher': '1018', 'contributor': 'TBD', 'modified': 'TBD', 'date': '30', 'type': '1031', 'format': '1034', 'identifier': '12', 'source': 'TBD', 'language': 'TBD', 'relation': 'TBD', 'rights': 'TBD', # bbox and full text map to internal fixed columns #'ows:BoundingBox': 'bbox', #'csw:AnyText': 'xml' } } } self.context = context self.context.namespaces.update(self.namespaces) def request_sru2csw(self, kvpin): """transform an SRU request into a CSW request""" kvpout = {'service': 'CSW', 'version': '2.0.2', 'mode': 'sru'} if 'operation' in kvpin: if kvpin['operation'] == 'explain': kvpout['request'] = 'GetCapabilities' elif kvpin['operation'] == 'searchRetrieve': kvpout['request'] = 'GetRecords' if 'startrecord' in kvpin: kvpout['startposition'] = int(kvpin['startrecord']) if 'maximumrecords' in kvpin: kvpout['maxrecords'] = int(kvpin['maximumrecords']) else: kvpout['maxrecords'] = 0 # TODO: make smarter typename fetching kvpout['typenames'] = 'csw:Record' kvpout['elementsetname'] = 'brief' kvpout['constraintlanguage'] = 'CQL_TEXT' kvpout['resulttype'] = 'results' if 'query' in kvpin: pname_in_query = False for coops in fes1.MODEL['ComparisonOperators'].keys(): if kvpin['query'].find(fes1.MODEL['ComparisonOperators'][coops]['opvalue']) != -1: pname_in_query = True break kvpout['constraint'] = {'type': 'cql'} if not pname_in_query: kvpout['constraint'] = 'csw:AnyText like \'%%%s%%\'' % kvpin['query'] else: kvpout['constraint'] = kvpin['query'] else: kvpout['request'] = 'GetCapabilities' return kvpout def response_csw2sru(self, element, environ): """transform a CSW response into an SRU response""" response_name = etree.QName(element).localname if response_name == 'Capabilities': # explain node = etree.Element(util.nspath_eval('sru:explainResponse', self.namespaces), nsmap=self.namespaces) etree.SubElement(node, util.nspath_eval('sru:version', self.namespaces)).text = self.sru_version record = etree.SubElement(node, util.nspath_eval('sru:record', self.namespaces)) etree.SubElement(record, util.nspath_eval('sru:recordPacking', self.namespaces)).text = 'XML' etree.SubElement(record, util.nspath_eval('sru:recordSchema', self.namespaces)).text = 'http://explain.z3950.org/dtd/2.1/' recorddata = etree.SubElement(record, util.nspath_eval('sru:recordData', self.namespaces)) explain = etree.SubElement(recorddata, util.nspath_eval('zr:explain', self.namespaces)) serverinfo = etree.SubElement(explain, util.nspath_eval('zr:serverInfo', self.namespaces), protocol='SRU', version=self.sru_version, transport='http', method='GET POST SOAP') etree.SubElement(serverinfo, util.nspath_eval('zr:host', self.namespaces)).text = environ.get('HTTP_HOST', environ["SERVER_NAME"]) # WSGI allows for either of these etree.SubElement(serverinfo, util.nspath_eval('zr:port', self.namespaces)).text = environ['SERVER_PORT'] etree.SubElement(serverinfo, util.nspath_eval('zr:database', self.namespaces)).text = 'pycsw' databaseinfo = etree.SubElement(explain, util.nspath_eval('zr:databaseInfo', self.namespaces)) etree.SubElement(databaseinfo, util.nspath_eval('zr:title', self.namespaces), lang='en', primary='true').text = element.xpath('//ows:Title|//ows20:Title', namespaces=self.context.namespaces)[0].text etree.SubElement(databaseinfo, util.nspath_eval('zr:description', self.namespaces), lang='en', primary='true').text = element.xpath('//ows:Abstract|//ows20:Abstract', namespaces=self.context.namespaces)[0].text indexinfo = etree.SubElement(explain, util.nspath_eval('zr:indexInfo', self.namespaces)) etree.SubElement(indexinfo, util.nspath_eval('zr:set', self.namespaces), name='dc', identifier='info:srw/cql-context-set/1/dc-v1.1') for key, value in sorted(self.mappings['csw:Record']['index'].items()): zrindex = etree.SubElement(indexinfo, util.nspath_eval('zr:index', self.namespaces), id=value) etree.SubElement(zrindex, util.nspath_eval('zr:title', self.namespaces)).text = key zrmap = etree.SubElement(zrindex, util.nspath_eval('zr:map', self.namespaces)) etree.SubElement(zrmap, util.nspath_eval('zr:map', self.namespaces), set='dc').text = key zrindex = etree.SubElement(indexinfo, util.nspath_eval('zr:index', self.namespaces)) zrmap = etree.SubElement(zrindex, util.nspath_eval('zr:map', self.namespaces)) etree.SubElement(zrmap, util.nspath_eval('zr:name', self.namespaces), set='dc').text = 'title222' schemainfo = etree.SubElement(explain, util.nspath_eval('zr:schemaInfo', self.namespaces)) zrschema = etree.SubElement(schemainfo, util.nspath_eval('zr:schema', self.namespaces), name='dc', identifier='info:srw/schema/1/dc-v1.1') etree.SubElement(zrschema, util.nspath_eval('zr:title', self.namespaces)).text = 'Simple Dublin Core' configinfo = etree.SubElement(explain, util.nspath_eval('zr:configInfo', self.namespaces)) etree.SubElement(configinfo, util.nspath_eval('zr:default', self.namespaces), type='numberOfRecords').text = '0' elif response_name == 'GetRecordsResponse': recpos = int(element.xpath('//@nextRecord')[0]) - int(element.xpath('//@numberOfRecordsReturned')[0]) node = etree.Element(util.nspath_eval('zs:searchRetrieveResponse', self.namespaces), nsmap=self.namespaces) etree.SubElement(node, util.nspath_eval('zs:version', self.namespaces)).text = self.sru_version etree.SubElement(node, util.nspath_eval('zs:numberOfRecords', self.namespaces)).text = element.xpath('//@numberOfRecordsMatched')[0] for rec in element.xpath('//csw:BriefRecord', namespaces=self.context.namespaces): record = etree.SubElement(node, util.nspath_eval('zs:record', self.namespaces)) etree.SubElement(node, util.nspath_eval('zs:recordSchema', self.namespaces)).text = 'info:srw/schema/1/dc-v1.1' etree.SubElement(node, util.nspath_eval('zs:recordPacking', self.namespaces)).text = 'xml' recorddata = etree.SubElement(record, util.nspath_eval('zs:recordData', self.namespaces)) rec.tag = util.nspath_eval('srw_dc:srw_dc', self.namespaces) recorddata.append(rec) etree.SubElement(record, util.nspath_eval('zs:recordPosition', self.namespaces)).text = str(recpos) recpos += 1 elif response_name == 'ExceptionReport': node = self.exceptionreport2diagnostic(element) return node def exceptionreport2diagnostic(self, element): """transform a CSW exception into an SRU diagnostic""" node = etree.Element( util.nspath_eval('zs:searchRetrieveResponse', self.namespaces), nsmap=self.namespaces) etree.SubElement(node, util.nspath_eval('zs:version', self.namespaces)).text = self.sru_version diagnostics = etree.SubElement(node, util.nspath_eval('zs:diagnostics', self.namespaces)) diagnostic = etree.SubElement( diagnostics, util.nspath_eval('zs:diagnostic', self.namespaces)) etree.SubElement(diagnostic, util.nspath_eval('zd:diagnostic', self.namespaces)).text = \ 'info:srw/diagnostic/1/7' etree.SubElement(diagnostic, util.nspath_eval('zd:message', self.namespaces)).text = \ element.xpath('//ows:Exception/ows:ExceptionText|//ows20:Exception/ows20:ExceptionText', namespaces=self.context.namespaces)[0].text etree.SubElement(diagnostic, util.nspath_eval('zd:details', self.namespaces)).text = \ element.xpath('//ows:Exception|//ows20:Exception', namespaces=self.context.namespaces)[0].attrib.get('exceptionCode') return node ================================================ FILE: pycsw/stac/__init__.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2023 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= ================================================ FILE: pycsw/stac/api.py ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from copy import deepcopy import json import logging import os from pygeofilter.parsers.ecql import parse as parse_ecql import requests from pycsw import __version__ from pycsw.core.pygeofilter_evaluate import to_filter from pycsw.ogc.api.oapi import gen_oapi from pycsw.ogc.api.records import API, build_anytext from pycsw.core.util import geojson_geometry2bbox, str2bool, wkt2geom LOGGER = logging.getLogger(__name__) # Return headers for requests (e.g:X-Powered-By) HEADERS = { 'Content-Type': 'application/json', 'X-Powered-By': f'pycsw {__version__}' } THISDIR = os.path.dirname(os.path.realpath(__file__)) CONFORMANCE_CLASSES = [ 'http://www.opengis.net/spec/ogcapi-common-1/1.0/conf/core', 'http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/collections', 'http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/simple-query', 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core', 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables', 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables-query-parameters', 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/filter', 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/features-filter', 'http://www.opengis.net/spec/ogcapi-features-4/1.0/conf/create-replace-delete', 'http://www.opengis.net/spec/cql2/1.0/conf/cql2-json', 'http://www.opengis.net/spec/cql2/1.0/conf/cql2-text', 'https://api.stacspec.org/v1.0.0/core', 'https://api.stacspec.org/v1.0.0/ogcapi-features', 'https://api.stacspec.org/v1.0.0/item-search', 'https://api.stacspec.org/v1.0.0/item-search#filter', 'https://api.stacspec.org/v1.0.0/item-search#free-text', 'https://api.stacspec.org/v1.0.0/item-search#sort', 'https://api.stacspec.org/v1.0.0-rc.1/collection-search', 'https://api.stacspec.org/v1.0.0-rc.1/collection-search#free-text', 'https://api.stacspec.org/v1.0.0/collections/extensions/transaction', 'https://api.stacspec.org/v1.0.0/ogcapi-features/extensions/transaction' ] class STACAPI(API): """STAC API object""" def __init__(self, config: dict): """ constructor :param config: pycsw configuration dict :returns: `pycsw.ogc.api.STACAPI` instance """ super().__init__(config) self.mode = 'stac-api' self.config['server']['url'] += '/stac' LOGGER.debug(f"Server URL: {self.config['server']['url']}") def landing_page(self, headers_, args): """ Provide API landing page :param headers_: copy of HEADERS object :param args: request parameters :returns: tuple of headers, status code, content """ headers_['Content-Type'] = 'application/json' response = { 'stac_version': '1.0.0', 'id': 'pycsw-catalogue', 'type': 'Catalog', 'conformsTo': CONFORMANCE_CLASSES, 'links': [], 'title': self.config['metadata']['identification']['title'], 'description': self.config['metadata']['identification']['description'], 'keywords': self.config['metadata']['identification']['keywords'] } LOGGER.debug('Creating links') response['links'] = [{ 'rel': 'self', 'type': 'application/json', 'href': f"{self.config['server']['url']}/" }, { 'rel': 'root', 'type': 'application/json', 'href': f"{self.config['server']['url']}/" }, { 'rel': 'service-doc', 'type': 'text/html', 'href': f"{self.config['server']['url']}/openapi?f=html" }, { 'rel': 'service-desc', 'type': 'application/vnd.oai.openapi+json;version=3.0', 'href': f"{self.config['server']['url']}/openapi?f=json" }, { 'rel': 'conformance', 'type': 'application/json', 'href': f"{self.config['server']['url']}/conformance" }, { 'rel': 'data', 'type': 'application/json', 'href': f"{self.config['server']['url']}/collections" }, { 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables', 'type': 'application/schema+json', 'title': 'Queryables', 'href': f"{self.config['server']['url']}/queryables" }, { 'rel': 'search', 'type': 'application/geo+json', 'href': f"{self.config['server']['url']}/search" } ] if self.pubsub_client is not None and self.pubsub_client.show_link: LOGGER.debug('Adding PubSub broker link') pubsub_link = { 'rel': 'hub', 'type': 'application/json', 'title': 'Pub/Sub broker', 'href': self.pubsub_client.broker_safe_url } response['links'].append(pubsub_link) return self.get_response(200, headers_, response) def openapi(self, headers_, args): """ Provide OpenAPI document / Swagger :param headers_: copy of HEADERS object :param args: request parameters :returns: tuple of headers, status code, content """ headers_['Content-Type'] = self.get_content_type(headers_, args) if headers_['Content-Type'] == 'application/json': headers_['Content-Type'] = 'application/vnd.oai.openapi+json;version=3.0' filepath = f"{THISDIR}/../core/schemas/ogc/ogcapi/records/part1/1.0/ogcapi-records-1.yaml" response = gen_oapi(self.config, filepath, self.mode) return self.get_response(200, headers_, response, 'openapi.html') def conformance(self, headers_, args): """ Provide API conformance :param headers_: copy of HEADERS object :param args: request parameters :returns: tuple of headers, status code, content """ headers_['Content-Type'] = 'application/json' headers_['Accept'] = 'application/json' response = { 'conformsTo': CONFORMANCE_CLASSES } return self.get_response(200, headers_, response) def collections(self, headers_, args): """ Provide API collections :param headers_: copy of HEADERS object :param args: request parameters :returns: tuple of headers, status code, content """ headers_['Content-Type'] = 'application/json' collections = [] # LOGGER.debug('Generating default metadata:main collection') # collection_info = self.get_collection_info() # collections.append(collection_info) LOGGER.debug('Generating virtual collections') filters = None query_args = [] LOGGER.debug('Handling collection level search') for k, v in args.items(): if k == 'bbox': query_args.append(f'BBOX(geometry, {v})') elif k == 'datetime': if '/' not in v: query_args.append(f'date = "{v}"') else: begin, end = v.split('/') if begin != '..': query_args.append(f'time_begin >= "{begin}"') if end != '..': query_args.append(f'time_end <= "{end}"') elif k == 'q': if v not in [None, '']: query_args.append(build_anytext('anytext', v)) limit = int(args.get('limit', self.config['server'].get('maxrecords', 10))) if query_args: ast = parse_ecql(' AND '.join(query_args)) LOGGER.debug(f'Abstract syntax tree: {ast}') filters = to_filter(ast, self.repository.dbtype, self.repository.query_mappings) LOGGER.debug(f'Filter: {filters}') virtual_collections = self.repository.query_collections(filters, limit) for virtual_collection in virtual_collections: virtual_collection_info = self.get_collection_info( virtual_collection.identifier, virtual_collection) collections.append(virtual_collection_info) response = { 'collections': collections } LOGGER.debug('Generating STAC collections') query_args.append("typename = 'stac:Collection'") ast = parse_ecql(' AND '.join(query_args)) LOGGER.debug(f'Abstract syntax tree: {ast}') filters = to_filter(ast, self.repository.dbtype, self.repository.query_mappings) LOGGER.debug(f'Filter: {filters}') sc_query = self.repository.session.query( self.repository.dataset).filter(filters).limit(limit).all() for sc in sc_query: id_found = False for collection_ in response['collections']: if sc.identifier == collection_['id']: id_found = True if not id_found: LOGGER.debug('Adding STAC collection') sc2 = sc sc2.title = sc.title or sc.identifier sc2.abstract = sc.abstract or sc.identifier response['collections'].append(self.get_collection_info( sc2.identifier, sc2 )) url_base = f"{self.config['server']['url']}/collections" for collection in response['collections']: collection['links'].append({ 'rel': 'self', 'type': 'application/json', 'href': f"{url_base}/{collection['id']}" }) collection['links'].append({ 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables', 'type': 'application/schema+json', 'href': f"{url_base}/{collection['id']}/queryables" }) response['links'] = [{ 'rel': 'self', 'type': 'application/json', 'href': url_base }, { 'rel': 'root', 'type': 'application/json', 'href': f"{self.config['server']['url']}/" }, { 'rel': 'parent', 'type': 'application/json', 'href': self.config['server']['url'] }] response['collections'] = response['collections'][:limit] response['numberMatched'] = len(response['collections']) response['numberReturned'] = len(response['collections']) return self.get_response(200, headers_, response) def collection(self, headers_, args, collection='metadata:main'): """ Provide API collections :param headers_: copy of HEADERS object :param args: request parameters :param collection: collection name :returns: tuple of headers, status code, content """ headers_['Content-Type'] = 'application/json' LOGGER.debug(f'Generating {collection} collection') if collection == 'metadata:main': collection_info = self.get_collection_info() else: try: virtual_collection = self.repository.query_ids([collection])[0] collection_info = self.get_collection_info( virtual_collection.identifier, virtual_collection) except IndexError: return self.get_exception( 404, headers_, 'InvalidParameterValue', 'STAC collection not found') response = collection_info url_base = f"{self.config['server']['url']}/collections/{collection}" response['links'] = [{ 'rel': 'self', 'type': 'application/json', 'href': url_base }, { 'rel': 'root', 'type': 'application/json', 'href': f"{self.config['server']['url']}/" }, { 'rel': 'parent', 'type': 'application/json', 'href': f"{self.config['server']['url']}/collections" }, { 'rel': 'items', 'type': 'application/geo+json', 'href': f"{url_base}/items" }] return self.get_response(200, headers_, response) def queryables(self, headers_, args, collection='metadata:main'): """ Provide collection queryables :param headers_: copy of HEADERS object :param args: request parameters :param collection: name of collection :returns: tuple of headers, status code, content """ headers_['Accept'] = 'application/json' headers, status, response = super().queryables(headers_, args, collection) response = json.loads(response) if 'properties' in response: eo_schema = 'https://raw.githubusercontent.com/ceos-org/stac-collection-and-granule-discovery-best-practices/refs/heads/main/schemas/opensearch-eo.json' eo_props = { 'platform': 'platform', 'instrument': 'instrument', 'sensortype': 'sensorType', 'cloudcover': 'cloudCover', 'illuminationelevationangle': 'illuminationElevationAngle' } for key, value in eo_props.items(): if key in response['properties']: response['properties'][key]['$id'] = f'{eo_schema}#/properties/{eo_props[key]}' return self.get_response(status, headers, response) def items(self, headers_, json_post_data, args, collection='metadata:main'): """ Provide collection items :param headers_: copy of HEADERS object :param json_post_data: `dict` of JSON POST data :param args: request parameters :param collection: collection name :returns: tuple of headers, status code, content """ cql_ops = [] json_post_data2 = {} distributed_search_args = {} distributed = str2bool(args.get('distributedSearch', False)) if distributed: LOGGER.debug('Setting distributed search args') args.pop('distributedSearch', None) distributed_search_args = deepcopy(args) distributed_search_args.pop('type', None) if collection not in self.get_all_collections(): msg = 'Invalid collection' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) headers_['Accept'] = 'application/json' if json_post_data is None: LOGGER.debug('Empty JSON payload') json_post_data = {} json_post_data2 = deepcopy(json_post_data) if 'bbox' in json_post_data2: LOGGER.debug('Detected bbox query parameter') cql_ops.append({ 'op': 's_intersects', 'args': [{ 'property': 'geometry' }, {'bbox': json_post_data2.pop('bbox')}] }) if 'limit' in json_post_data2: LOGGER.debug('Detected limit parameter') args['limit'] = json_post_data2.pop('limit') if 'sortby' in json_post_data2: LOGGER.debug('Detected sortby parameter') args['sortby'] = json_post_data2['sortby'] if 'collections' in json_post_data2: LOGGER.debug('Detected collections query parameter') cql_ops.append({ 'op': 'in', 'args': [{ 'property': 'collections', }, json_post_data2.pop('collections') ] }) if 'ids' in json_post_data2: LOGGER.debug('Detected ids query parameter') cql_ops.append({ 'op': 'in', 'args': [{ 'property': 'identifier', }, json_post_data2.pop('ids') ] }) if 'intersects' in json_post_data2: LOGGER.debug('Detected intersects query parameter') # TODO if 'datetime' in json_post_data2: if '/' not in json_post_data2['datetime']: cql_ops.append({ 'op': '=', 'args': [ {'property': 'date'}, json_post_data2.pop('datetime') ] }) else: begin, end = json_post_data2.pop('datetime').split('/') if begin != '..': cql_ops.append({ 'op': '>=', 'args': [ {'property': 'time_begin'}, begin ] }) if end != '..': cql_ops.append({ 'op': '<=', 'args': [ {'property': 'time_end'}, end ] }) if 'filter' in json_post_data2: LOGGER.debug('Detected filter query parameter') json_post_data2 = json_post_data2.pop('filter') if not json_post_data2 and not cql_ops: LOGGER.debug('No JSON POST data or CQL ops') args['type'] = 'item' elif not json_post_data2 and cql_ops: LOGGER.debug('No JSON POST data left') cql_ops.append({ 'op': '=', 'args': [ {'property': 'type'}, 'item' ] }) json_post_data2 = { 'op': 'and', 'args': cql_ops } else: LOGGER.debug('JSON POST data is CQL2 JSON') cql_ops.append({ 'op': '=', 'args': [ {'property': 'type'}, 'item' ] }) LOGGER.debug('Adding STAC API query parameters to CQL2 JSON') if json_post_data2.get('op') in ['and', 'or']: json_post_data2['args'].extend(cql_ops) else: op_, args_ = json_post_data2.get('op'), json_post_data2.get('args') if None not in [op_, args_]: cql_ops.append({ 'op': op_, 'args': args_, }) json_post_data2 = { 'op': 'and', 'args': cql_ops } else: json_post_data2['filter-lang'] = 'cql2-json' json_post_data2['filter'] = { 'op': 'and', 'args': cql_ops } headers, status, response = super().items(headers_, json_post_data2, args, collection) response = json.loads(response) response2 = deepcopy(response) response2['features'] = [] LOGGER.debug('Filtering on STAC items') for record in response.get('features', []): if record.get('stac_version') is None: record['links'].extend([{ 'rel': 'self', 'type': 'application/geo+json', 'href': f"{self.config['server']['url']}/collections/{collection}/items/{record['id']}" }, { 'rel': 'root', 'type': 'application/json', 'href': f"{self.config['server']['url']}/" }, { 'rel': 'parent', 'type': 'application/json', 'href': f"{self.config['server']['url']}/collections/{collection}" }]) response2['features'].append(links2stacassets(collection, record)) else: response2['features'].append(record) if record.get('bbox') is None: geometry = record.get('geometry') if geometry is not None: LOGGER.debug('Calculating bbox from geometry') bbox = geojson_geometry2bbox(geometry) record['bbox'] = [float(t) for t in bbox.split(',')] for link in record['links']: if link.get('rel') is None: LOGGER.debug('Missing link relation; adding rel=related') link['rel'] = 'related' links2 = [] for link in response2.get('links', []): if json_post_data: LOGGER.debug('Adding link method and body') link['method'] = 'POST' link['body'] = json_post_data if link['rel'] in ['alternate', 'collection']: continue link['href'] = link['href'].replace('collections/metadata:main/items', 'search') links2.append(link) if distributed: for fc in self.config.get('federatedcatalogues', []): distributed_search_args2 = deepcopy(distributed_search_args) if 'collections' in fc: if 'collections' in distributed_search_args2: distributed_search_args2['collections'] += ','.join(fc['collections']) else: distributed_search_args2['collections'] = ','.join(fc['collections']) if fc['type'] != 'STAC-API': LOGGER.debug(f"Federated catalogue type {fc['type']} not supported; skipping") continue LOGGER.debug(f"Running distributed search against {fc['url']}") url = get_stac_search_url(fc['url']) if url is None: LOGGER.debug('Unable to detect STAC API search URL; skipping') continue response2['federatedSearchResults'][fc['id']] = { 'type': 'FeatureCollection', 'features': [] } try: LOGGER.debug(f'Querying STAC API search: {url}') stac_search_results = requests.get(url, params=distributed_search_args2).json() for feature in stac_search_results['features']: response2['federatedSearchResults'][fc['id']]['features'].append(feature) except Exception as err: LOGGER.warning(err) response2['links'] = links2 response2['links'].extend([{ 'rel': 'root', 'type': 'application/json', 'href': f"{self.config['server']['url']}/" } ]) if 'code' in response2: response2.pop('features') response2.pop('links') return self.get_response(status, headers, response2) def item(self, headers_, args, collection, item): """ Provide collection item :param headers_: copy of HEADERS object :param args: request parameters :param collection: name of collection :param item: record identifier :returns: tuple of headers, status code, content """ if collection not in self.get_all_collections(): msg = 'Invalid collection' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) headers_['Accept'] = 'application/geo+json' headers, status, response = super().item(headers_, args, collection, item) response = json.loads(response) if 'id' not in response: return self.get_exception( 404, headers_, 'InvalidParameterValue', 'item not found') response = links2stacassets(collection, response) return self.get_response(status, headers_, response) def get_collection_info(self, collection_name: str = 'metadata:main', collection_info: dict = {}) -> dict: """ Generate collection metadata :param collection_name: name of collection default is 'metadata:main' main collection :param collection_info: `dict` of collection info :returns: `dict` of collection """ if 'json' in collection_info.metadata_type and collection_info.type == 'collection': return json.loads(collection_info.metadata) if collection_name == 'metadata:main': id_ = collection_name title = self.config['metadata']['identification']['title'] description = self.config['metadata']['identification']['description'] # noqa else: id_ = collection_name title = collection_info.title description = collection_info.abstract collection_ = { 'id': id_, 'stac_version': '1.0.0', 'license': 'other', 'extent': { 'spatial': { 'bbox': [wkt2geom(collection_info.wkt_geometry)] }, 'temporal': {'interval': [[ collection_info.time_begin, collection_info.time_end ]]} }, 'title': title, 'description': description, 'type': 'Collection', 'links': [{ 'rel': 'collection', 'type': 'application/json', 'href': f"{self.config['server']['url']}/collections/{collection_name}" }, { 'rel': 'items', 'type': 'application/geo+json', 'href': f"{self.config['server']['url']}/collections/{collection_name}/items" }] } date_types = { 'date_creation': 'created', 'date_modified': 'updated', 'date_publication': 'published' } for key, value in date_types.items(): value2 = getattr(collection_info, key) if value2 is not None: collection_[date_types[key]] = value2 return collection_ def manage_collection_item(self, headers_, action='create', item=None, data=None, collection=None): if action in ['create', 'update']: if (data is not None and data.get('type', '') == 'Feature' and collection not in self.get_all_collections()): msg = 'Invalid collection' LOGGER.exception(msg) return self.get_exception(400, headers_, 'InvalidParameterValue', msg) if action == 'create' and data is not None and 'features' in data: LOGGER.debug('STAC ItemCollection detected') for feature in data['features']: data2 = feature if collection is not None: data2['collection'] = collection headers, status, content = super().manage_collection_item( headers_=headers_, action='create', data=data2) return self.get_response(201, headers_, {}) else: # default/super LOGGER.debug('STAC Collection detected') if collection is not None: data['collection'] = collection if data is not None and 'id' in data: item = data['id'] return super().manage_collection_item( headers_=headers_, action=action, item=item, data=data) def links2stacassets(collection: str, record: dict) -> dict: """ Transform record enclosure links to STAC assets :param collection: `str` of collection :param record: `dict` of record :returns: `dict` of updated record with link assets """ LOGGER.debug('Transforming enclosure links to STAC assets') if 'stac_version' not in record: record['stac_version'] = '1.0.0' if 'collection' not in record: record['collection'] = collection links_assets = [i for i in record['links'] if i.get('rel', '') == 'enclosure'] links_to_keep = [i for i in record['links'] if i.get('rel', '') != 'enclosure'] record['links'] = links_to_keep LOGGER.debug('Adding assets') if links_assets: if 'assets' not in record: record['assets'] = {} for count, asset in enumerate(links_assets): if 'name' in asset: asset_key = asset.pop('name') else: asset_key = count record['assets'][asset_key] = asset return record def get_stac_search_url(url: str) -> str: """ Get STAC search URL from a STAC API :param url: `str` of STAC API landing page :returns: `str` of STAC API search URL """ stac_search_url = None LOGGER.debug(f'Deriving STAC API search URL from {url}') stac_root = requests.get(url).json() for link in stac_root['links']: if all([ link['rel'] == 'search', link['type'] == 'application/geo+json', link.get('method', 'GET') == 'GET' ]): LOGGER.debug(f"Found STAC search URL at {link['href']}") stac_search_url = link['href'] break return stac_search_url ================================================ FILE: pycsw/templates/_base.html ================================================ {% block title %}{{ config['metadata']['identification']['title'] }} -{% endblock %} {% for link in data['links'] %} {% if (link['rel']=="self" and link['type']=="text/html") %} {% endif %} {% endfor %} {% block extrahead %} {% endblock %}
pycsw website

{{ config['metadata']['identification']['title'] }}

{% block crumbs %} Home {% endblock %}
{% set links_found = namespace(json=0) %} {% for link in data['links'] %} {% if link['rel'] == 'alternate' and link['type'] and link['type'] in ['application/json', 'application/geo+json'] %} {% set links_found.json = 1 %} JSON {% endif %} {% endfor %} {% if links_found.json == 0 %} JSON {% endif %} | Contact


{% block body %} {% endblock %}

Powered by {{ version }}
{% block extrafoot %} {% endblock %} ================================================ FILE: pycsw/templates/collection.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} {{ data['title'] }} {% endblock %} {% block crumbs %} {{ super() }} / Collections / {{ data['title'] }} {% endblock %} {% block body %}

{{ data['title'] }}

Name Type Description
{{ data['title'] | striptags | truncate }} {{ data["itemType"] }} {{ data['description'] | striptags | truncate }} items queryables {% if data.id == 'metadata:main' and config['federatedcatalogues'] %} federated catalogs {% endif %}
{% endblock %} ================================================ FILE: pycsw/templates/collections.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} Collections {% endblock %} {% block crumbs %} {{ super() }} / Collections {% endblock %} {% block body %}

Collections

{% for col in data['collections'] %} {% endfor %}
Name Type Description
{{ col['title'] | striptags | truncate }} {{ col["itemType"] }} {{ col['description'] | striptags | truncate }} items queryables {% if col.id == 'metadata:main' and config['federatedcatalogues'] %} federated catalogs {% endif %}
{% endblock %} ================================================ FILE: pycsw/templates/conformance.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} Conformance {% endblock %} {% block crumbs %} {{ super() }} / Conformance {% endblock %} {% block body %}

Conformance

    {% for link in data['conformsTo'] %}
  • {{ link }}
  • {% endfor %}
{% endblock %} ================================================ FILE: pycsw/templates/exception.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} Exception {% endblock %} {% block body %}

Exception

{{ data['description'] | striptags }}

{% endblock %} ================================================ FILE: pycsw/templates/federatedcatalog.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} Federated catalog {% endblock %} {% block crumbs %} {{ super() }} / Collections / {{ data['title'] }} / Federated catalogs / {{ data['fedcat']['title'] }} {% endblock %} {% block body %}

Federated catalog

{{ data['title'] }}

Id Type Title URL
{{ data['fedcat']['id'] }} {{ data['fedcat']['type'] }} {{ data['fedcat']['title'] }} {{ data['fedcat']['url'] }}
{% endblock %} ================================================ FILE: pycsw/templates/federatedcatalogs.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} Federated catalogs {% endblock %} {% block crumbs %} {{ super() }} / Collections / {{ data['title'] }} / Federated catalogs {% endblock %} {% block body %}

Federated catalogs

{{ data['title'] }}

{% for fc in data['fedcats'] %} {% endfor %}
Id Type Title
{{ fc['id'] }} {{ fc['type'] }} {{ fc['title'] }}
{% endblock %} ================================================ FILE: pycsw/templates/item.html ================================================ {% extends "_base.html" %} {% block title %}{{ data.get('properties',{}).get('title',data['id']) }} - {{ super() }}{% endblock %} {% block extrahead %} {% endblock %} {% block crumbs %} {{ super() }} / Collections / {{ data['title'] }} / Items / {{ data['id'] }} {% endblock %} {% block body %}
{{ (data.get('properties',{}).get('type') or '').split('/').pop() | capitalize }}

{{ data.get('properties',{}).get('title',data['id']) }}

{{ data.get('properties',{}).get('description','') | urlize }}

{% if 'properties' in data %} {% for key, value in data['properties'].items() %} {% if key == 'keywords' %} {% elif key == 'formats' %} {% elif key == 'themes' %} {% elif key == 'externalIds' %} {% elif key == 'contacts' %} {% else %} {% if key in ['title','description'] %} {% else %} {% endif %} {% endif %} {% endfor %} {% endif %} {% if data['time'] %} {% endif %} {% if 'assets' in data %} {% endif %}
Property Value
{{ key | capitalize }}
    {% for keyword in value %}
  • {{ keyword }}
  • {% endfor %}
    {% for f in value %}
  • {{ f.get('name') }}
  • {% endfor %}
{% for theme in value %} {{ theme['scheme'] }} {% endfor %}
    {% for id in value %}
  • {{ id['scheme'] | urlize }} {{ id['value'] | urlize }}
  • {% endfor %}
{% for cnt in data['properties']['contacts'] %} {% if cnt.name %} {% endif %} {% if cnt.position %} {% endif %} {% for address in cnt.addresses %} {% endfor %}
Name: {{ cnt.name }}
Roles: {{ cnt.roles | join(',') }}
Position: {{ cnt['position'] }}
Addresses
Address: {{ address['deliveryPoint'] | join(',') }}
City: {{ address['city'] }}
Administrative area: {{ address['administrativeArea'] }}
Postal code: {{ address['postalCode'] }}
Country: {{ address['country'] }}
Phone: {{ cnt.phones | map(attribute='value') | join(', ') }}
Email: {{ cnt.emails | map(attribute='value') | join(', ') }}
Links:
    {% for link in cnt.links %}
  • {{ link.href | urlize }}
  • {% endfor %}
{% endfor %}
{{ value | truncate(80, False, '...') }}{{ value | urlize }}
Temporal {% if data['time'].get('date') %} {{ data['time']['date'] }} {% elif data['time'].get('timestamp') %} {{ data['time']['timestamp'] }} {% elif data['time'].get('interval') %}
  • begin: {{ data['time']['interval'][0] }}
  • end: {{ data['time']['interval'][1] }}
{% endif %} {% if data['time'].get('resolution') %} Resolution: {{ data['time']['resolution'] }} {% endif %}
Links
Assets
    {% for key, value in data['assets'].items() %} {% if value['title'] %}
  • {{ key }}
  • {% else %}
  • {{ key }}
  • {% endif %} {% endfor %}
{% endblock %} {% block extrafoot %} {% endblock %} ================================================ FILE: pycsw/templates/items.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} Items {% endblock %} {% block extrahead %} {% endblock %} {% block crumbs %} {{ super() }} / Collections / {{ data['title'] }} / Items {% endblock %} {% block body %}
{% set nav_links = namespace(prev=None, next=None, self=None) %} {% for link in data['links'] %} {% if link['rel'] == 'prev' %} {% set nav_links.prev = link['href'] %} {% endif %} {% if link['rel'] == 'self' %} {% set nav_links.self = link['href'] %} {% endif %} {% if link['rel'] == 'next' %} {% set nav_links.next = link['href'] %} {% endif %} {% endfor %} {# parse the querystring as dict #} {% set attrs = {} %} {% if '?' in nav_links.self %} {% for kv in nav_links.self.split('#')[0].split('?').pop().split('&') %} {% if kv.split('=')[0] not in [None,''] %} {{ attrs.update({kv.split('=')[0] : kv.split('=')[1]}) or '' }} {% endif %} {% endfor %} {% else %} {% set nav_links.self = link['href'].split('#')[0] + '?' %} {% endif %} {# update existing url with new key,val. indent prevents spaces in output #} {# reset pagination, else you may end up in empty result #} {% macro updateurl(key=None,val=None) %}{{ nav_links.self.split('?')[0] }}?{% for at in attrs.keys() %}{% if at != 'offset' %}{% if attrs[at] not in [None,''] %}{% if key not in [None,''] and key == at %}{% if val != '' %}&{{ at }}={{ val }}{% endif %}{% else %}&{{ at }}={{ attrs[at] }}{% endif %}{% endif %}{% endif %}{% endfor %}{% if key not in attrs.keys() %}&{{ key }}={{ val }}{% endif %}{% endmacro %} {% macro reseturl(key,val) %}{{ nav_links.self.split('?')[0]}}?facets=true{% if 'q' in attrs %}&q={{ attrs['q'] }}{% endif %}{% if 'sortby' in attrs %}&sortby={{ attrs['sortby'] }}{% endif %}{% endmacro %}

{{ data['numberMatched'] }} results.
Apply
{% if 'facets=true' in nav_links.self %} Reset {% endif %}
{% if data['facets'] %} {% for facet in data['facets'].keys() %} {% if data['facets'][facet]['buckets']|length > 0 %}
{{ facet }} {% if facet in attrs.keys() %} Reset {% endif %}
{% for bucket in data['facets'][facet]['buckets'] %} {% if loop.index == 8 %}
{% endif %} {% if bucket['value'] %} {{(bucket['value'] or "") | truncate(20, False, '..') | capitalize }} {{bucket['count']}}
{% endif %} {% endfor %} {% if data['facets'][facet]['buckets']|length > 7 %}
{% endif %}
{% endif %} {% endfor %} {% endif %}
{% for rec in data['features'] %} {% if 'properties' in rec %} {% else %} {% endif %} {% if 'properties' in rec %} {% if 'type' in rec['properties'] %} {% elif rec.get('type') == 'Feature' and 'stac_version' not in rec %} {% elif rec.get('type') == 'Feature' and 'stac_version' in rec %} {% else%} {% endif %} {% else %} {% if rec.get('type') == 'Feature' and 'stac_version' not in rec %} {% elif rec.get('type') == 'Feature' and 'stac_version' in rec %} {% elif rec.get('type') == 'Collection' and 'stac_version' in rec %} {% elif rec.get('type') == 'Catalog' and 'stac_version' in rec %} {% else%} {% endif %} {% endif %} {% if 'properties' in rec %} {% endif %} {% endfor %}
Title Type Date
{{ rec['properties'].get('title', rec['id']) }}{{ rec.get('title', rec['id']) }}{{ rec['properties']['type'] }}recorditem{{ rec.get('type') }}recorditemcollectioncatalog{{ rec.get('type') }}{{ rec['properties'].get('updated', '').split('T')[0].replace('-','/') }}
{% if nav_links.prev %} {% else %} {% endif %}
Showing {{ data['numberReturned'] }} of {{ data['numberMatched'] }} results.
{% if nav_links.next %} {% else %} {% endif %}
{% endblock %} {% block extrafoot %} {% endblock %} ================================================ FILE: pycsw/templates/landing_page.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} Home {% endblock %} {% block body %} {% endblock %} ================================================ FILE: pycsw/templates/openapi.html ================================================ Swagger UI - {{ config['metadata']['identification']['title'] }}
================================================ FILE: pycsw/templates/queryables.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} Queryables {% endblock %} {% block crumbs %} {{ super() }} / Collections / {{ data['title'] }} / Queryables {% endblock %} {% block body %}

Queryables

{{ data['title'] }}

{% for qname, qinfo in data['properties'].items() %} {% if qname == 'geometry' %} {% else %} {% endif %} {% endfor %}
Name Type
{{ qname }}
{{ qname }} {{ qinfo['type'] }} {% if 'enum' in qinfo %}
    {% for value in qinfo['enum'] %}
  • {{ value }}
  • {% endfor %}
{% endif %}
{% endblock %} ================================================ FILE: pycsw/templates/stac_items.html ================================================ {% extends "_base.html" %} {% block title %}{{ super() }} Items {% endblock %} {% block extrahead %} {% endblock %} {% block crumbs %} {{ super() }} / Search {% endblock %} {% block body %}
{% set nav_links = namespace(prev=None, next=None) %} {% for link in data['links'] %} {% if link['rel'] == 'prev' %} {% set nav_links.prev = link['href'] %} {% endif %} {% if link['rel'] == 'next' %} {% set nav_links.next = link['href'] %} {% endif %} {% endfor %}
{% if nav_links.prev %} {% else %} {% endif %} {% if nav_links.next %} {% else %} {% endif %}
{% for rec in data['features'] %} {% if 'properties' in rec %} {% else %} {% endif %} {% if 'properties' in rec %} {% if 'type' in rec['properties'] %} {% elif rec.get('type') == 'Feature' and 'stac_version' not in rec %} {% elif rec.get('type') == 'Feature' and 'stac_version' in rec %} {% else%} {% endif %} {% else %} {% if rec.get('type') == 'Feature' and 'stac_version' not in rec %} {% elif rec.get('type') == 'Feature' and 'stac_version' in rec %} {% elif rec.get('type') == 'Collection' and 'stac_version' in rec %} {% elif rec.get('type') == 'Catalog' and 'stac_version' in rec %} {% else%} {% endif %} {% endif %} {% endfor %}
Title Type
{{ rec['properties']['title'] }}{{ rec.get('title', rec['id']) }}{{ rec['properties']['type'] }}recorditem{{ rec.get('type') }}recorditemcollectioncatalog{{ rec.get('type') }}
{% if nav_links.prev %} {% else %} {% endif %} {% if nav_links.next %} {% else %} {% endif %}
{% endblock %} {% block extrafoot %} {% if data['features'] %} {% endif %} {% endblock %} ================================================ FILE: pycsw/wsgi.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Adam Hinz # Ricardo Garcia Silva # Tom Kralidis # # Copyright (c) 2015 Adam Hinz # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= # WSGI wrapper for pycsw # # Apache mod_wsgi configuration # # ServerName host1 # WSGIDaemonProcess host1 home=/var/www/pycsw processes=2 # WSGIProcessGroup host1 # # WSGIScriptAlias /pycsw-wsgi /var/www/pycsw/wsgi.py # # # Order deny,allow # Allow from all # # # or invoke this script from the command line: # # $ python3 ./pycsw/wsgi.py # # which will publish pycsw to: # # http://localhost:8000/ # import gzip from io import BytesIO import os import sys from urllib.parse import unquote from pycsw import server def application(env, start_response): """WSGI wrapper""" status, headers, contents = application_dispatcher(env) start_response(status, list(headers.items())) return [contents] def application_dispatcher(env): pycsw_root = get_pycsw_root_path(os.environ, env) configuration_path = get_configuration_path(os.environ, env, pycsw_root) env['local.app_root'] = pycsw_root if 'HTTP_HOST' in env and ':' in env['HTTP_HOST']: env['HTTP_HOST'] = env['HTTP_HOST'].split(':')[0] csw = server.Csw(configuration_path, env) status, contents = csw.dispatch_wsgi() headers = { 'Content-Length': str(len(contents)), 'Content-Type': str(csw.contenttype) } if "gzip" in env.get("HTTP_ACCEPT_ENCODING", ""): try: compression_level = int( csw.config["server"]["gzip_compresslevel"]) contents, compress_headers = compress_response( contents, compression_level) headers.update(compress_headers) except KeyError: print( "The client requested a gzip compressed response. However, " "the server does not specify the 'gzip_compresslevel' option. " "Returning an uncompressed response..." ) return status, headers, contents def compress_response(response, compression_level): """Compress pycsw's response with gzip Parameters ---------- response: str The already processed CSW request compression_level: int Level of compression to use in gzip algorithm Returns ------- bytes The full binary contents of the compressed response dict Extra HTTP headers that are useful for the response """ buf = BytesIO() gzipfile = gzip.GzipFile(mode='wb', fileobj=buf, compresslevel=compression_level) gzipfile.write(response) gzipfile.close() compressed_response = buf.getvalue() compression_headers = { 'Content-Encoding': 'gzip', 'Content-Length': str(len(compressed_response)), } return compressed_response, compression_headers def get_pycsw_root_path(process_environment, request_environment=None, root_path_key="PYCSW_ROOT"): """Get pycsw's root path. The root path will be searched in the ``process_environment`` first, then in the ``request_environment``. If it cannot be found then it is determined based on the location on disk. Parameters ---------- process_environment: dict A mapping with the process environment. request_environment: dict, optional A mapping with the request environment. Typically the WSGI's environment root_path_key: str Name of the key in both the ``process_environment`` and the ``request_environment`` parameters that specifies the path to pycsw's root path. Returns ------- str Path to pycsw's root path, as read from the supplied configuration. """ req_env = ( dict(request_environment) if request_environment is not None else {}) app_root = process_environment.get( root_path_key, req_env.get( root_path_key, os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ) ) return app_root def get_configuration_path(process_environment, request_environment, pycsw_root, config_path_key="PYCSW_CONFIG"): """Get the path for pycsw configuration file. The configuration file path is searched in the following: * The presence of a ``config`` parameter in the request's query string; * A ``PYCSW_CONFIG`` environment variable; * A ``PYCSW_CONFIG`` WSGI variable. Parameters ---------- process_environment: dict A mapping with the process environment. request_environment: dict A mapping with the request's environment. Typically the WSGI's environment pycsw_root: str pycsw's default root path config_path_key: str, optional Name of the variable that specifies the path to pycsw's configuration file. Returns ------- str Path where pycsw expects to find its own configuration file """ # scan from config= or PYCSW_CONFIG environment variable query_string = request_environment.get("QUERY_STRING", "").lower() for kvp in query_string.split('&'): if "config" in kvp: configuration_path = unquote(kvp.split('=')[1]) break else: # did not find any `config` parameter in the request # lets try the process env, request env and fallback to # /default.yml configuration_path = process_environment.get( config_path_key, request_environment.get( config_path_key, os.path.join(pycsw_root, "default.yml") ) ) return configuration_path if __name__ == '__main__': # run inline using WSGI reference implementation from wsgiref.simple_server import make_server port = 8000 if len(sys.argv) > 1: port = int(sys.argv[1]) httpd = make_server('', port, application) print(f'Serving on port {port}...') httpd.serve_forever() ================================================ FILE: pycsw/wsgi_flask.py ================================================ # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2021 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import os import sys from flask import Flask, Blueprint, make_response, request from pycsw.ogc.api.records import API from pycsw.ogc.api.util import STATIC, yaml_load from pycsw.stac.api import STACAPI from pycsw.wsgi import application_dispatcher APP = Flask(__name__, static_folder=STATIC, static_url_path='/static') APP.url_map.strict_slashes = False with open(os.getenv('PYCSW_CONFIG'), encoding='utf8') as fh: APP.config['PYCSW_CONFIG'] = yaml_load(fh) BLUEPRINT = Blueprint('pycsw', __name__, static_folder=STATIC, static_url_path='/static') api_ = API(APP.config['PYCSW_CONFIG']) with open(os.getenv('PYCSW_CONFIG'), encoding='utf8') as fh: stacapi = STACAPI(yaml_load(fh)) BLUEPRINT.config = api_.config def get_api_type(urlpath): """ Decorator to detect API type :param urlpath: URL path :returns: `str` of API typ """ api_type = 'ogcapi-records' if 'stac' in urlpath: api_type = 'stac-api' return api_type def get_response(result: tuple): """ Creates a Flask Response object and updates matching headers. :param result: The result of the API call. This should be a tuple of (headers, status, content). :returns: A Response instance. """ headers, status, content = result response = make_response(content, status) if headers: response.headers = headers return response @BLUEPRINT.route('/') @BLUEPRINT.route('/stac') def landing_page(): """ OGC API landing page endpoint :returns: HTTP response """ if get_api_type(request.url_rule.rule) == 'stac-api': return get_response(stacapi.landing_page(dict(request.headers), request.args)) # noqa else: return get_response(api_.landing_page(dict(request.headers), request.args)) @BLUEPRINT.route('/openapi') @BLUEPRINT.route('/stac/openapi') def openapi(): """ OGC API OpenAPI document endpoint :returns: HTTP response """ if get_api_type(request.url_rule.rule) == 'stac-api': return get_response(stacapi.openapi(dict(request.headers), request.args)) else: return get_response(api_.openapi(dict(request.headers), request.args)) @BLUEPRINT.route('/conformance') @BLUEPRINT.route('/stac/conformance') def conformance(): """ OGC API conformance endpoint :returns: HTTP response """ if get_api_type(request.url_rule.rule) == 'stac-api': return get_response(stacapi.conformance(dict(request.headers), request.args)) else: return get_response(api_.conformance(dict(request.headers), request.args)) @BLUEPRINT.route('/collections', methods=['GET', 'POST']) @BLUEPRINT.route('/stac/collections', methods=['GET', 'POST']) def collections(): """ OGC API collections endpoint :returns: HTTP response """ if get_api_type(request.url_rule.rule) == 'stac-api': if request.method == 'POST': data = request.get_json(silent=True) return get_response(stacapi.manage_collection_item(dict(request.headers), 'create', data=data)) else: return get_response(stacapi.collections(dict(request.headers), request.args)) else: return get_response(api_.collections(dict(request.headers), request.args)) @BLUEPRINT.route('/collections/', methods=['GET', 'PUT', 'DELETE']) @BLUEPRINT.route('/stac/collections/', methods=['GET', 'PUT', 'DELETE']) def collection(collection='metadata:main'): """ OGC API collection endpoint :param collection: collection name :returns: HTTP response """ if get_api_type(request.url_rule.rule) == 'stac-api': if request.method == 'PUT': return get_response( stacapi.manage_collection_item( dict(request.headers), 'update', collection=collection, data=request.get_json(silent=True))) elif request.method == 'DELETE': return get_response( stacapi.manage_collection_item(dict(request.headers), 'delete', collection)) else: return get_response(stacapi.collection(dict(request.headers), request.args, collection)) else: return get_response(api_.collection(dict(request.headers), request.args, collection)) @BLUEPRINT.route('/collections//queryables') @BLUEPRINT.route('/stac/queryables') @BLUEPRINT.route('/stac/collections//queryables') def queryables(collection='metadata:main'): """ OGC API collection queryables endpoint :param collection: collection name :returns: HTTP response """ if get_api_type(request.url_rule.rule) == 'stac-api': return get_response(stacapi.queryables(dict(request.headers), request.args, collection)) else: return get_response(api_.queryables(dict(request.headers), request.args, collection)) @BLUEPRINT.route('/collections//federatedCatalogs') def federated_catalogues(collection='metadata:main'): """ OGC API collection federated catalogues endpoint :param collection: collection name :returns: HTTP response """ return get_response(api_.federated_catalogues(dict(request.headers), request.args, collection)) @BLUEPRINT.route('/collections//federatedCatalogs/') def federated_catalogue(collection='metadata:main', catalogue=None): """ OGC API collection federated catalogue endpoint :param collection: collection name :param catalogue: catalogue :returns: HTTP response """ return get_response(api_.federated_catalogue(dict(request.headers), request.args, collection, catalogue)) @BLUEPRINT.route('/collections//items', methods=['GET', 'POST']) @BLUEPRINT.route('/stac/search', methods=['GET', 'POST']) @BLUEPRINT.route('/stac/collections//items', methods=['GET', 'POST']) def items(collection='metadata:main'): """ OGC API collection items endpoint STAC API items search endpoint :param collection: collection name :returns: HTTP response """ if all([get_api_type(request.url_rule.rule) == 'ogcapi-records', request.method == 'POST', request.content_type not in [None, 'application/json']]): # OGC API Transaction - create data = None if request.content_type == 'application/geo+json': # JSON grammar data = request.get_json(silent=True) elif 'xml' in request.content_type: # XML grammar data = request.data return get_response(api_.manage_collection_item(dict(request.headers), 'create', collection=collection, data=data)) elif request.method == 'POST' and get_api_type(request.url_rule.rule) == 'stac-api': if request.url_rule.rule.endswith('items'): # STAC API transaction - create data = request.get_json(silent=True) return get_response(stacapi.manage_collection_item(dict(request.headers), 'create', collection=collection, data=data)) else: # STAC API search return get_response(stacapi.items(dict(request.headers), request.get_json(silent=True), dict(request.args), collection)) elif get_api_type(request.url_rule.rule) == 'stac-api': return get_response(stacapi.items(dict(request.headers), request.get_json(silent=True), dict(request.args), collection)) else: # OGC API - Records items search return get_response(api_.items(dict(request.headers), request.get_json(silent=True), dict(request.args), collection)) @BLUEPRINT.route('/collections//items/', methods=['GET', 'PUT', 'DELETE']) @BLUEPRINT.route('/stac/collections//items/', methods=['GET', 'PUT', 'DELETE']) def item(collection='metadata:main', item=None): """ OGC API collection items endpoint :param collection: collection name :param item: item identifier :returns: HTTP response """ if request.method == 'PUT': return get_response( api_.manage_collection_item( dict(request.headers), 'update', collection, item, data=request.get_json(silent=True))) elif request.method == 'DELETE': return get_response( api_.manage_collection_item(dict(request.headers), 'delete', collection, item)) else: if get_api_type(request.url_rule.rule) == 'stac-api': return get_response(stacapi.item(dict(request.headers), request.args, collection, item)) else: return get_response(api_.item(dict(request.headers), request.args, collection, item)) @BLUEPRINT.route('/csw', methods=['GET', 'POST']) def csw(): """ CSW endpoint :returns: HTTP response """ request.environ['PYCSW_IS_CSW'] = True status, headers, content = application_dispatcher(request.environ) return get_response((headers, status, content)) @BLUEPRINT.route('/opensearch', methods=['GET']) def opensearch(): """ OpenSearch endpoint :returns: HTTP response """ request.environ['PYCSW_IS_OPENSEARCH'] = True status, headers, content = application_dispatcher(request.environ) return get_response((headers, status, content)) @BLUEPRINT.route('/oaipmh', methods=['GET']) def oaipmh(): """ OpenSearch endpoint :returns: HTTP response """ request.environ['PYCSW_IS_OAIPMH'] = True status, headers, content = application_dispatcher(request.environ) return get_response((headers, status, content)) @BLUEPRINT.route('/sru', methods=['GET']) def sru(): """ OpenSearch endpoint :returns: HTTP response """ request.environ['PYCSW_IS_SRU'] = True status, headers, content = application_dispatcher(request.environ) return get_response((headers, status, content)) APP.register_blueprint(BLUEPRINT) if __name__ == '__main__': port = 8000 if len(sys.argv) > 1: port = int(sys.argv[1]) print(f'Serving on port {port}') APP.run(debug=True, host='0.0.0.0', port=port) ================================================ FILE: pyproject.toml ================================================ [build-system] requires = ["setuptools>=46.4", "wheel"] build-backend = "setuptools.build_meta" ================================================ FILE: requirements-dev.txt ================================================ -r requirements.txt -r requirements-standalone.txt -r requirements-pg.txt pytest==6.2.4 pytest-cov==2.12.0 pytest-flake8==1.0.7 pytest-timeout==1.4.2 sphinx twine ================================================ FILE: requirements-pg.txt ================================================ psycopg2 ================================================ FILE: requirements-pubsub.txt ================================================ paho-mqtt ================================================ FILE: requirements-standalone.txt ================================================ SQLAlchemy<2.0.0 Flask Jinja2 pygeofilter PyYAML pygeoif ================================================ FILE: requirements.txt ================================================ click geolinks legacy-cgi; python_version >= '3.13' lxml OWSLib pyproj python-dateutil PyYAML Shapely xmltodict ================================================ FILE: setup.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Tom Kralidis # Ricardo Garcia Silva # # Copyright (c) 2025 Tom Kralidis # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import io import os import re from setuptools import find_packages, setup def read(filename, encoding="utf-8"): full_path = os.path.join(os.path.dirname(__file__), filename) with io.open(full_path, encoding=encoding) as fh: contents = fh.read().strip() return contents def get_package_version(): """get version from top-level package init""" version_file = read('pycsw/__init__.py') version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M) if version_match: return version_match.group(1) raise RuntimeError('Unable to find version string.') DESCRIPTION = ('pycsw is an OGC API - Records and OGC CSW server ' 'implementation written in Python') # ensure a fresh MANIFEST file is generated if (os.path.exists('MANIFEST')): os.unlink('MANIFEST') setup( name='pycsw', version=get_package_version(), description=DESCRIPTION.strip(), long_description=read("README.md"), long_description_content_type='text/markdown', license='MIT', platforms='all', keywords=" ".join([ 'pycsw', 'csw', 'catalogue', 'catalog', 'metadata', 'discovery', 'search', 'ogc', 'iso', 'fgdc', 'dif', 'ebrim', 'inspire', 'ISO 19115-3 XML' ]), author='Tom Kralidis', author_email='tomkralidis@gmail.com', maintainer='Tom Kralidis', maintainer_email='tomkralidis@gmail.com', url='https://pycsw.org/', install_requires=read("requirements.txt").splitlines(), packages=find_packages(), include_package_data=True, entry_points={ 'console_scripts': [ 'pycsw-admin.py=pycsw.core.admin:cli' ] }, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Scientific/Engineering :: GIS' ] ) ================================================ FILE: tests/README.txt ================================================ See https://docs.pycsw.org/en/latest/testing.html ================================================ FILE: tests/conftest.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # # Copyright (c) 2016 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """pytest configuration file""" import pytest def pytest_configure(config): """Configure pytest. This function adds additional markers to pytest. """ config.addinivalue_line( "markers", "functional: Run only functional tests" ) config.addinivalue_line( "markers", "unit: Run only unit tests" ) def pytest_addoption(parser): """Add additional command-line parameters to pytest.""" parser.addoption( "--database-backend", choices=["sqlite", "postgresql"], default="sqlite", help="Database backend to use when performing functional tests" ) parser.addoption( "--database-user-postgresql", default="postgres", help="Username to use for creating and accessing local postgres " "databases used for functional tests." ) parser.addoption( "--database-password-postgresql", default="", help="Password to use for creating and accessing local postgres " "databases used for functional tests." ) parser.addoption( "--database-name-postgresql", default="test_pycsw", help="Name of the postgres database that is to be used for testing." ) parser.addoption( "--database-host-postgresql", default="127.0.0.1", help="hostname or ip of the host that is running the postgres " "database server to use in testing." ) parser.addoption( "--database-port-postgresql", default="5432", help="Port where the postgres server is listening for connections." ) parser.addoption( "--pycsw-loglevel", default="warning", help="Log level for the pycsw server." ) parser.addoption( "--functional-prefer-diffs", action="store_true", help="When running functional tests, compare results with their " "expected values by using diffs instead of XML canonicalisation " "(the default)." ) parser.addoption( "--functional-save-results-directory", help="When running functional tests, save each test's result under " "the input directory path." ) @pytest.fixture(scope="session") def log_level(request): """Log level to use when instantiating a new pycsw server. The value for this fixture is retrieved from the `--pycsw.loglevel` command-line parameter. """ return request.config.getoption("pycsw_loglevel").upper() ================================================ FILE: tests/functionaltests/conftest.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # Tom Kralidis # # Copyright (c) 2016 Ricardo Garcia Silva # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """pytest configuration file for functional tests""" from collections import namedtuple import logging import os import re import psycopg2 import pytest from pycsw.core import admin from pycsw.core.config import StaticContext from pycsw.core.repository import Repository, setup from pycsw.ogc.api.util import yaml_load TESTS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SuiteDirs = namedtuple("SuiteDirs", [ "get_tests_dir", "post_tests_dir", "data_tests_dir", "expected_results_dir", "export_tests_dir", ]) def pytest_configure(config): config.addinivalue_line("markers", "unit: Run only unit tests") config.addinivalue_line("markers", "functional: Run only functional tests") def pytest_generate_tests(metafunc): """Parametrize tests programmatically. This function scans the filesystem directories under ``tests/functionaltests/suites`` and automatically generates pytest tests based on the available test suites. Each suite directory has the following structure: * A mandatory ``default.yml`` file specifying the configuration for the pycsw instance to use in the tests of the suite. * An optional ``get/`` subdirectory containing a ``requests.txt`` file with any HTTP GET requests for which to generate tests for. Each request is specified in a new line, with the following pattern: * , * An optional ``post/`` subdirectory containing files that are used as the payload for HTTP POST requests. The name of each file is used as the name of the test (without the file's extension); * An optional ``data/`` subdirectory. This directory, if present, indicates that the suite uses a custom database. The database is populated with any additional files that are contained inside this directory. If the ``data`` directory does not exist then the suite's tests will use the CITE database; * An ``expected/`` subdirectory containing a file for each of the expected test outcomes. The tests are autogenerated by parametrizing the ``tests/functionaltests/test_suites_functional::test_suites`` function Notes ----- Check pytest's documentation for information on autogenerating parametrized tests for further details on how the ``pytest_generate_tests`` function can be used: http://pytest.org/latest/parametrize.html#basic-pytest-generate-tests-example """ global TESTS_ROOT if metafunc.function.__name__ == "test_xml_based_suites": suites_root_dir = os.path.join(TESTS_ROOT, "functionaltests", "suites") suite_names = os.listdir(suites_root_dir) arg_values = [] test_ids = [] logging.basicConfig(level=getattr( logging, metafunc.config.getoption("--pycsw-loglevel").upper())) if metafunc.config.getoption("--database-backend") == "postgresql": _recreate_postgresql_database(metafunc.config) for suite in suite_names: suite_dir = os.path.join(suites_root_dir, suite) config_path = os.path.join(suite_dir, "default.yml") if not os.path.isfile(config_path): print(f"Directory {suite_dir} does not have a suite " "configuration file") continue print(f"Generating tests for suite {suite}") normalize_ids = True if suite in ("harvesting", "manager") else False suite_dirs = _get_suite_dirs(suite) if suite_dirs.post_tests_dir is not None: post_argvalues, post_ids = _get_post_parameters( post_tests_dir=suite_dirs.post_tests_dir, expected_tests_dir=suite_dirs.expected_results_dir, config_path=config_path, suite_name=suite, normalize_ids=normalize_ids, ) arg_values.extend(post_argvalues) test_ids.extend(post_ids) if suite_dirs.get_tests_dir is not None: get_argvalues, get_ids = _get_get_parameters( get_tests_dir=suite_dirs.get_tests_dir, expected_tests_dir=suite_dirs.expected_results_dir, config_path=config_path, suite_name=suite, normalize_ids=normalize_ids, ) arg_values.extend(get_argvalues) test_ids.extend(get_ids) metafunc.parametrize( argnames=["configuration", "request_method", "request_data", "expected_result", "normalize_identifier_fields"], argvalues=arg_values, indirect=["configuration"], ids=test_ids, ) @pytest.fixture() def test_identifier(request): """Extract a meaningful identifier from the request's node.""" return re.search(r"[\w_]+\[(.*)\]", request.node.name).group(1) @pytest.fixture() def use_xml_canonicalisation(request): return not request.config.getoption("--functional-prefer-diffs") @pytest.fixture() def save_results_directory(request): return request.config.getoption("--functional-save-results-directory") @pytest.fixture() def configuration(request, tests_directory, log_level): """Configure a suite for execution in tests. This function is executed once for each individual test request, after tests have been collected. The configuration file for each test suite is read into memory. Some configuration parameters, like the repository's url and table name are adjusted. The suite's repository is also created, if needed. Parameters ---------- request: pytest.fixtures.FixtureRequest tests_directory: py.path.local Directory created by pytest where any test artifacts are to be saved log_level: str Log level for the pycsw server instance that will be created during tests. """ config_path = request.param with open(config_path, encoding="utf-8") as fh: config = yaml_load(fh) suite_name = config_path.split(os.path.sep)[-2] suite_dirs = _get_suite_dirs(suite_name) data_dir = suite_dirs.data_tests_dir export_dir = suite_dirs.export_tests_dir if data_dir is not None: # suite has its own database repository_url = _get_repository_url(request.config, suite_name, tests_directory) else: # suite uses the CITE database data_dir, export_dir = _get_cite_suite_dirs() repository_url = _get_repository_url(request.config, "cite", tests_directory) table_name = _get_table_name(suite_name, config, repository_url) if not _repository_exists(repository_url, table_name): _initialize_database(repository_url=repository_url, table_name=table_name, data_dir=data_dir, test_dir=tests_directory, export_dir=export_dir) config["logging"]["level"] = log_level config["repository"]["database"] = repository_url config["repository"]["table"] = table_name return config @pytest.fixture(scope="session", name="tests_directory") def fixture_tests_directory(tmpdir_factory): """Create a temporary directory for each test session. This directory is typically situated under ``/tmp`` and is used to create eventual sqlite databases for each suite. This functionality is mostly provided by pytest's built-in ``tmpdir_factory`` fixture. More information on this is available at: http://doc.pytest.org/en/2.9.0/tmpdir.html#the-tmpdir-factory-fixture """ tests_dir = tmpdir_factory.mktemp("functional_tests") return tests_dir def _get_cite_suite_dirs(): """Return the path to the data directory of the CITE test suite.""" global TESTS_ROOT suites_root_dir = os.path.join(TESTS_ROOT, "functionaltests", "suites") suite_dir = os.path.join(suites_root_dir, "cite") data_tests_dir = os.path.join(suite_dir, "data") export_tests_dir = os.path.join(suite_dir, "export") data_dir = data_tests_dir if os.path.isdir(data_tests_dir) else None export_dir = export_tests_dir if os.path.isdir(export_tests_dir) else None return data_dir, export_dir def _get_get_parameters(get_tests_dir, expected_tests_dir, config_path, suite_name, normalize_ids): """Return the parameters suitable for parametrizing HTTP GET tests.""" method = "GET" test_argvalues = [] test_ids = [] requests_file_path = os.path.join(get_tests_dir, "requests.txt") with open(requests_file_path) as fh: for line in fh: test_name, test_params = [i.strip() for i in line.partition(",")[::2]] expected_result_path = os.path.join( expected_tests_dir, f"{method.lower()}_{test_name}.xml" ) test_argvalues.append( (config_path, method, test_params, expected_result_path, normalize_ids) ) test_ids.append( f"{suite_name}_{method.lower()}_{test_name}" ) return test_argvalues, test_ids def _get_post_parameters(post_tests_dir, expected_tests_dir, config_path, suite_name, normalize_ids): """Return the parameters suitable for parametrizing HTTP POST tests.""" method = "POST" test_argvalues = [] test_ids = [] # we are sorting the directory contents because the # `harvesting` suite requires tests to be executed in alphabetical order directory_contents = sorted(os.listdir(post_tests_dir)) for request_file_name in directory_contents: request_path = os.path.join(post_tests_dir, request_file_name) expected_result_path = os.path.join( expected_tests_dir, f"{method.lower()}_{request_file_name}" ) test_argvalues.append( (config_path, method, request_path, expected_result_path, normalize_ids) ) test_ids.append( f"{suite_name}_{method.lower()}_{os.path.splitext(request_file_name)[0]}" ) return test_argvalues, test_ids def _get_repository_url(conf, suite_name, test_dir): """Return the repository_url for the input parameters. Returns ------- repository_url: str SQLAlchemy URL for the repository in use. """ db_type = conf.getoption("--database-backend") if db_type == "sqlite": repository_url = f"sqlite:///{test_dir}/{suite_name}.db" elif db_type == "postgresql": user = conf.getoption("--database-user-postgresql") password = conf.getoption("--database-password-postgresql") host = conf.getoption("--database-host-postgresql") port = conf.getoption("--database-port-postgresql") database = conf.getoption("--database-name-postgresql") repository_url = f"postgresql://{user}:{password}@{host}:{port}/{database}" else: raise NotImplementedError return repository_url def _get_suite_dirs(suite_name): """Get the paths to relevant suite directories. Parameters ---------- suite_name: str Name of the site Returns ------- SuiteDirs A four element named tuple with the input suite's relevant test directories. """ global TESTS_ROOT suites_root_dir = os.path.join(TESTS_ROOT, "functionaltests", "suites") suite_dir = os.path.join(suites_root_dir, suite_name) data_tests_dir = os.path.join(suite_dir, "data") post_tests_dir = os.path.join(suite_dir, "post") get_tests_dir = os.path.join(suite_dir, "get") export_tests_dir = os.path.join(suite_dir, "export") expected_results_dir = os.path.join(suite_dir, "expected") data_dir = data_tests_dir if os.path.isdir(data_tests_dir) else None posts_dir = post_tests_dir if os.path.isdir(post_tests_dir) else None gets_dir = get_tests_dir if os.path.isdir(get_tests_dir) else None expected_dir = (expected_results_dir if os.path.isdir( expected_results_dir) else None) _ = export_tests_dir if os.path.isdir(export_tests_dir) else None return SuiteDirs(get_tests_dir=gets_dir, post_tests_dir=posts_dir, data_tests_dir=data_dir, expected_results_dir=expected_dir, export_tests_dir=export_tests_dir) def _get_table_name(suite, config, repository_url): """Get the name of the table used to store records in the database. Parameters ---------- suite: str Name of the suite. config: dict Configuration for the suite. repository_url: str SQLAlchemy URL for the repository in use. Returns ------- str Name of the table to use in the database """ if repository_url.startswith("sqlite"): result = config['repository']['table'] elif repository_url.startswith("postgresql"): result = f"{suite}_records" else: raise NotImplementedError return result def _initialize_database(repository_url, table_name, data_dir, test_dir, export_dir): """Initialize database for tests. This function will create the database and load any test data that the suite may require. Parameters ---------- repository_url: str URL for the repository, as used by SQLAlchemy engines table_name: str Name of the table that is to be used to store pycsw records data_dir: str Path to a directory that contains sample data records to be loaded into the database test_dir: str Directory where the database is to be created, in case of sqlite. export_dir: str Diretory where the exported records are to be saved, if any """ context = StaticContext() print(f"Setting up {repository_url} repository...") if repository_url.startswith("postgresql"): extra_kwargs = { "create_sfsql_tables": True } else: extra_kwargs = {} setup(repository_url, table_name, **extra_kwargs) repo = Repository(repository_url, context, table=table_name) if len(os.listdir(data_dir)) > 0: print("Loading database data...") loaded = admin.load_records( context=context, database=repository_url, table=table_name, xml_dirpath=data_dir, recursive=True ) repo.optimize_db() if export_dir is not None: # Attempt to export files exported = admin.export_records( context=context, database=repository_url, table=table_name, xml_dirpath=export_dir ) if len(loaded) != len(exported): raise ValueError( "Loaded records (%s) is different from exported records (%s)" % (len(loaded), len(exported)) ) # Remove the files that were exported since this was just a test for toremove in exported: os.remove(toremove) def _parse_postgresql_repository_url(repository_url): """Parse a SQLAlchemy engine URL describing a postgresql database. Parameters ---------- repository_url: str SQLAlchemy URL for the repository in use. Returns ------- dict A mapping with the database's connection parameters. """ info_re = re.search(r"postgresql://(?P[\w_]+):(?P.*?)@" r"(?P[\w_.]+):(?P\d+)/" r"(?P[\w_]+)", repository_url, flags=re.UNICODE) try: db_info = info_re.groupdict() except AttributeError: raise RuntimeError(f"Could not parse repository url {repository_url}") else: return db_info def _recreate_postgresql_database(configuration): """Recreate a postgresql database. This function will try to create a new postgresql database for testing purposes. If the database already exists it is deleted and then recreated. Parameters ---------- configuration: _pytest.config.Config The configuration object used by pytest Raises ------ RuntimeError If a connection to the postgresql server cannot be made """ connection = psycopg2.connect( database="postgres", user=configuration.getoption("--database-user-postgresql"), password=configuration.getoption("--database-password-postgresql"), host=configuration.getoption("--database-host-postgresql"), port=configuration.getoption("--database-port-postgresql") ) connection.set_isolation_level( psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) cursor = connection.cursor() db_name = configuration.getoption("--database-name-postgresql") cursor.execute(f"DROP DATABASE IF EXISTS {db_name}") cursor.execute(f"CREATE DATABASE {db_name}") cursor.execute( "SELECT COUNT(1) FROM pg_available_extensions WHERE name='postgis'") postgis_available = bool(cursor.fetchone()[0]) cursor.close() connection.close() if postgis_available: _create_postgresql_extension(configuration, extension="postgis") def _create_postgresql_extension(configuration, extension): """Create a postgresql extension in a previously created database. Parameters ---------- configuration: _pytest.config.Config The configuration object used by pytest extension: str Name of the extension to be created """ connection = psycopg2.connect( database=configuration.getoption("--database-name-postgresql"), user=configuration.getoption("--database-user-postgresql"), password=configuration.getoption("--database-password-postgresql"), host=configuration.getoption("--database-host-postgresql"), port=configuration.getoption("--database-port-postgresql") ) connection.set_isolation_level( psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) cursor = connection.cursor() cursor.execute(f"CREATE EXTENSION {extension}") cursor.close() connection.close() def _repository_exists(repository_url, table_name): """Test if the database already exists. Parameters ---------- repository_url: str URL for the repository, as used by SQLAlchemy engines table_name: str Name of the table that is to be used to store pycsw records Returns ------- bool Whether the repository exists or not. """ if repository_url.startswith("sqlite"): repository_path = repository_url.replace("sqlite:///", "") result = os.path.isfile(repository_path) elif repository_url.startswith("postgresql"): db_info = _parse_postgresql_repository_url(repository_url) try: connection = psycopg2.connect(user=db_info["user"], password=db_info["password"], host=db_info["host"], port=db_info["port"], database=db_info["database"]) cursor = connection.cursor() cursor.execute("SELECT COUNT(1) FROM {table_name}") except (psycopg2.OperationalError, psycopg2.ProgrammingError): # database or table does not exist yet result = False else: result = True else: raise NotImplementedError return result ================================================ FILE: tests/functionaltests/suites/apiso/data/3e9a8c05.xml ================================================ 3e9a8c05 eng service NTUA tzotsos@gmail.com pointOfContact 2011-04-18 ISO19115 2003/Cor.1:2006 test Title 2011-04-19 creation http://aiolos.survey.ntua.gr ogc test Abstract NTUA tzotsos@gmail.com owner Geographic viewer (humanGeographicViewer) administration GEMET Themes, version 2.3 2011-04-18 publication Conditions unknown no limitation 19.37 29.61 34.80 41.75 2011-04-18 2011-04-20 view http://aiolos.survey.ntua.gr/geoserver/wms service Conformity_001 INSPIRE Corrigendum to INSPIRE Metadata Regulation published in the Official Journal of the European Union, L 328, page 83 2009-12-15 publication See the referenced specification true ================================================ FILE: tests/functionaltests/suites/apiso/data/README.txt ================================================ APISO Data ========== This directory provides data used to check conformance against pycsw APISO support. - pacioos-NS06agg.xml: http://oos.soest.hawaii.edu/pacioos/metadata/NS06agg.html - all other *.xml files are from the Greek National Mapping Agency (metadata submitted to the INSPIRE geoportal) ================================================ FILE: tests/functionaltests/suites/apiso/data/T_aerfo_RAS_1991_GR800P001800000012.xml ================================================ 366f6257-19eb-4f20-ba78-0698ac4aae77 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 366f6257-19eb-4f20-ba78-0698ac4aae77 T_aerfo_RAS_1991_GR800P001800000012.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_aerfo_RAS_1991_GR800P001800000013.xml ================================================ 75a7eb5e-336e-453d-ab06-209b1070d396 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 75a7eb5e-336e-453d-ab06-209b1070d396 T_aerfo_RAS_1991_GR800P001800000013.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_aerfo_RAS_1991_GR800P001800000014.xml ================================================ a7308c0a-b748-48e2-bab7-0a608a51d416 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation a7308c0a-b748-48e2-bab7-0a608a51d416 T_aerfo_RAS_1991_GR800P001800000014.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_aerfo_RAS_1991_GR800P001800000015.xml ================================================ 0173e0d7-6ea9-4407-b846-f29d6bfa9903 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 0173e0d7-6ea9-4407-b846-f29d6bfa9903 T_aerfo_RAS_1991_GR800P001800000015.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_ortho_RAS_1998_284404.xml ================================================ de53e931-778a-4792-94ad-9fe507aca483 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication de53e931-778a-4792-94ad-9fe507aca483 T_ortho_RAS_1998_284404.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.47878421.52731739.7600139.790341 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_ortho_RAS_1998_288395.xml ================================================ 4a5109d7-9ce5-4197-a423-b5fa8c426dee eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication 4a5109d7-9ce5-4197-a423-b5fa8c426dee T_ortho_RAS_1998_288395.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.52833321.57683439.67999939.710309 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_ortho_RAS_1998_288398.xml ================================================ 5f37e0f8-4fb1-4637-b959-b415058bdb68 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication 5f37e0f8-4fb1-4637-b959-b415058bdb68 T_ortho_RAS_1998_288398.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.52736921.57588839.70700439.737315 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_ortho_RAS_1998_288401.xml ================================================ f99cc358-f379-4e79-ab1e-cb2f7709f594 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication f99cc358-f379-4e79-ab1e-cb2f7709f594 T_ortho_RAS_1998_288401.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.52640421.57494139.73400939.764321 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_ortho_RAS_1998_288404.xml ================================================ ae200a05-2800-40b8-b85d-8f8d007b9e30 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication ae200a05-2800-40b8-b85d-8f8d007b9e30 T_ortho_RAS_1998_288404.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.52543721.57399239.76101539.791327 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_pmoed_DTM_1996_276395.xml ================================================ a2744b0c-becd-426a-95a8-46e9850ccc6d eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation a2744b0c-becd-426a-95a8-46e9850ccc6d T_pmoed_DTM_1996_276395.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_pmoed_DTM_1996_276398.xml ================================================ 0dc824a6-b555-46c1-bd7b-bc66cb91a70f eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation 0dc824a6-b555-46c1-bd7b-bc66cb91a70f T_pmoed_DTM_1996_276398.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_pmoed_DTM_1996_276401.xml ================================================ 42c8e55a-2bf6-476d-a7c9-be3bcd697f13 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation 42c8e55a-2bf6-476d-a7c9-be3bcd697f13 T_pmoed_DTM_1996_276401.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_pmoed_DTM_1996_276404.xml ================================================ c3bf29d4-d60a-4959-a415-2c03fb0d4aef eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation c3bf29d4-d60a-4959-a415-2c03fb0d4aef T_pmoed_DTM_1996_276404.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/T_pmoed_DTM_1996_280395.xml ================================================ b8cc2388-5d0a-43d8-9473-0e86dd0396da eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation b8cc2388-5d0a-43d8-9473-0e86dd0396da T_pmoed_DTM_1996_280395.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/data/iso_19115-2_Sentinel-2-scene.xml ================================================ S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE eng utf8 TBD dataset WWW:LINK information pointOfContact 2020-09-02T11:39:10.000000Z ISO 19115:2003 - Geographic information - Metadata ISO 19115:2003 European Petroleum Survey Group (EPSG) Geodetic Parameter Registry 2008-11-12 publication European Petroleum Survey Group http://www.epsg-registry.org originator urn:ogc:def:crs:EPSG:4326 6.18.3 S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE 2020-09-02T11:39:10.000000Z creation 2020-09-02T11:39:10.000000Z publication S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE onGoing continual Orthoimagery Land cover Geographical names theme data set series theme processing theme eo:productType:S2MSI2A eo:orbitNumber:50 eo:orbitDirection:DESCENDING eo:snowCover:0.0 theme otherRestrictions grid utf8 imageryBaseMapsEarthCover 1 22.241087944581203 22.316296604618408 36.95084163397443 37.21692395594552 2020-09-02T09:05:59.024Z 2020-09-02T09:05:59.024Z image image 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 0.082857 Level-2A WWW:LINK information distributor s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/ enclosure product product download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_B02_10m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_B03_10m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_B04_10m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_B08_10m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_TCI_10m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_AOT_10m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_WVP_10m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B02_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B03_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B04_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B05_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B06_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B07_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B8A_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B11_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B12_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_TCI_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_AOT_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_WVP_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_SCL_20m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B01_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B02_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B03_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B04_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B05_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B06_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B07_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B8A_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B09_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B11_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B12_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_TCI_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_AOT_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_WVP_60m.jp2 image/jp2 granule granule download s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_SCL_60m.jp2 image/jp2 granule granule download continual This metadata record was generated by pygeometa-0.7.dev0 (https://github.com/geopython/pygeometa) Sentinel-2B Sentinel-2B INS-NOBS S2MSI2A ================================================ FILE: tests/functionaltests/suites/apiso/data/pacioos-NS06agg.xml ================================================ NS06agg eng UTF8 dataset service Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information pointOfContact 2014-04-16 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 1 0.0 row 1 0.0 temporal 482760 252.0 area PacIOOS Nearshore Sensor 06: Pohnpei, Micronesia 2011-04-12 creation 2011-04-19 issued 2014-03-18 revision org.pacioos NS06agg Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information originator Jim Potemra distributor Data produced by Dr. Margaret McManus (mamc@hawaii.edu). Point of contact: Gordon Walker (gwalker@hawaii.edu). The nearshore sensors are part of the Pacific Islands Ocean Observing System (PacIOOS) and are designed to measure a variety of ocean parameters at fixed point locations. NS06 is located at the dock in Pohnpei lagoon and is mounted to the bottom in about 1 meter of water. The instrument is a Sea-Bird Electronics model 16+ V2 coupled with a WET Labs ECO-FLNTUS combination sensor. PacIOOS provides timely, reliable, and accurate ocean information to support a safe, clean, productive ocean and resilient coastal zone in the U.S. Pacific Islands region. The Pacific Islands Ocean Observing System (PacIOOS) is funded through the National Oceanic and Atmospheric Administration (NOAA) as a Regional Association within the U.S. Integrated Ocean Observing System (IOOS). PacIOOS is coordinated by the University of Hawaii School of Ocean and Earth Science and Technology (SOEST). Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information pointOfContact http://pacioos.org/metadata/browse/NS06agg.png Sample image. Oceans > Ocean Chemistry > Chlorophyll Oceans > Ocean Optics > Turbidity Oceans > Ocean Temperature > Water Temperature Oceans > Salinity/Density > Conductivity Oceans > Salinity/Density > Salinity Oceans > Water Quality theme GCMD Science Keywords Ocean &gt; Pacific Ocean &gt; Western Pacific Ocean &gt; Micronesia &gt; Federated States of Micronesia Ocean &gt; Pacific Ocean &gt; United States of America &gt; Territories Federated States of Micronesia &gt; Pohnpei &gt; Pohnpei Lagoon place GCMD Location Keywords Pacific Islands Ocean Observing System (PacIOOS) project GCMD Project Keywords Pacific Islands Ocean Observing System (PacIOOS) dataCenter GCMD Data Center Keywords sea_water_temperature sea_water_electrical_conductivity sea_water_turbidity mass_concentration_of_chlorophyll_in_sea_water sea_water_salinity depth latitude longitude time theme CF-1.4 The data may be used and redistributed for free but is not intended for legal use, since it may contain inaccuracies. Neither the data Contributor, University of Hawaii, PacIOOS, NOAA, State of Hawaii nor the United States Government, nor any of their employees or contractors, makes any warranty, express or implied, including warranties of merchantability and fitness for a particular purpose, or assumes any legal liability for the accuracy, completeness, or usefulness, of this information. Pacific Islands Ocean Observing System (PacIOOS) largerWorkCitation project Unidata Common Data Model Point largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 158.22402954101562 158.22402954101562 6.955227375030518 6.955227375030518 seconds 2010-05-07T00:00:00Z 2014-03-17T23:56:00Z -1.0 -1.0 PacIOOS Nearshore Sensor 06: Pohnpei, Micronesia 2011-04-12 creation 2011-04-19 issued 2014-03-18 revision Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information originator Jim Potemra distributor The nearshore sensors are part of the Pacific Islands Ocean Observing System (PacIOOS) and are designed to measure a variety of ocean parameters at fixed point locations. NS06 is located at the dock in Pohnpei lagoon and is mounted to the bottom in about 1 meter of water. The instrument is a Sea-Bird Electronics model 16+ V2 coupled with a WET Labs ECO-FLNTUS combination sensor. THREDDS OPeNDAP 1 158.22402954101562 158.22402954101562 6.955227375030518 6.955227375030518 2010-05-07T00:00:00Z 2014-03-17T23:56:00Z -1.0 -1.0 tight OPeNDAP Client Access http://oos.soest.hawaii.edu/thredds/dodsC/pacioos/nss/ns06agg OPeNDAP THREDDS OPeNDAP download temp float Temperature (sea_water_temperature) cond float Conductivity (sea_water_electrical_conductivity) turb float Turbidity (sea_water_turbidity) flor float Chlorophyll (mass_concentration_of_chlorophyll_in_sea_water) salt float Salinity (sea_water_salinity) z float depth below mean sea level (depth) lat float Latitude (latitude) lon float Longitude (longitude) time float Time (time) Pacific Islands Ocean Observing System (PacIOOS) jimp@hawaii.edu http://pacioos.org http web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://oos.soest.hawaii.edu/thredds/idd/nss_pacioos.html?dataset=NS06agg THREDDS Catalog This URL provides a catalog page for this dataset within THREDDS Data Server (TDS). download http://oos.soest.hawaii.edu/thredds/dodsC/pacioos/nss/ns06agg.html File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://pacioos.org/voyager/index.html?b=6.874279%2C158.077126%2C7.050468%2C158.369808&tz=pont&o=qual:2::p0NS06p1 PacIOOS Voyager (Google Maps API) This URL provides a viewer for this dataset. download http://oos.soest.hawaii.edu/dchart/index.html?dsetid=54cd0688ada08d86748b9c5762509f DChart This URL provides a viewer for this dataset. download http://oos.soest.hawaii.edu/erddap/tabledap/nss06_agg.graph?time%2Ctemperature&.draw=lines ERDDAP This URL provides a viewer for this dataset. download http://pacioos.org/focus/waterquality/wq_fsm.php PacIOOS Water Quality Platforms: FSM This URL provides a viewer for this dataset. download dataset UH/SOEST (M. McManus), PacIOOS asset (05/2010) This record was translated from NcML using UnidataDD2MI.xsl Version 2.3 ================================================ FILE: tests/functionaltests/suites/apiso/data/test.xml ================================================ 437ae0a2-06e2-4015-b296-a66e7f407bf2 eng dataset YPAATypaat@ypaat.grpointOfContact NTUAtzotsos@gmail.compointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 437ae0a2-06e2-4015-b296-a66e7f407bf2 T_aerfo_RAS_1991_GR800P001800000011.tif Aerial Photos YPAATypaat@ypaat.growner NTUAtzotsos@hotmail.comuser OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0038.0024.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/apiso/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/apiso/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true profiles: - apiso logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_DescribeRecord.xml ================================================ This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:05 ====== Basic information about data Graphic that provides an illustration of the dataset (should include a legend for the graphic) See 19119 for further info Brief description of ways in which the dataset is currently used. Keywords, their type and reference source Encapsulates the dataset aggregation information High-level geospatial data thematic classification to assist in the grouping and search of available geospatial datasets This file was generated from ISO TC/211 UML class diagrams == 10-13-2006 11:14:04 ====== ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record gmd:MD_Metadata DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record gmd:MD_Metadata apiso:AccessConstraints apiso:Bands apiso:Classification apiso:CloudCover apiso:ConditionApplyingToAccessAndUse apiso:Contributor apiso:Creator apiso:Degree apiso:IlluminationElevationAngle apiso:Instrument apiso:Lineage apiso:OtherConstraints apiso:Platform apiso:Publisher apiso:Relation apiso:ResponsiblePartyRole apiso:SensorType apiso:SpecificationDate apiso:SpecificationDateType apiso:SpecificationTitle csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox apiso:Abstract apiso:AlternateTitle apiso:AnyText apiso:BoundingBox apiso:CRS apiso:CouplingType apiso:CreationDate apiso:Denominator apiso:DistanceUOM apiso:DistanceValue apiso:Edition apiso:Format apiso:GeographicDescriptionCode apiso:HasSecurityConstraints apiso:Identifier apiso:KeywordType apiso:Language apiso:Modified apiso:OperatesOn apiso:OperatesOnIdentifier apiso:OperatesOnName apiso:Operation apiso:OrganisationName apiso:ParentIdentifier apiso:PublicationDate apiso:ResourceLanguage apiso:RevisionDate apiso:ServiceType apiso:ServiceTypeVersion apiso:Subject apiso:TempExtent_begin apiso:TempExtent_end apiso:Title apiso:TopicCategory apiso:Type brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetDomain-property.xml ================================================ apiso:TopicCategory climatologyMeteorologyAtmosphere elevation geoscientificInformation imageryBaseMapsEarthCover ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecordById-brief.xml ================================================ de53e931-778a-4792-94ad-9fe507aca483 dataset Ortho 2000-01-01 publication 21.48 21.53 39.76 39.79 http://www.ypaat.gr ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecordById-full-dc.xml ================================================ NS06agg PacIOOS Nearshore Sensor 06: Pohnpei, Micronesia dataset Oceans > Ocean Chemistry > Chlorophyll Oceans > Ocean Optics > Turbidity Oceans > Ocean Temperature > Water Temperature Oceans > Salinity/Density > Conductivity Oceans > Salinity/Density > Salinity Oceans > Water Quality Ocean &gt; Pacific Ocean &gt; Western Pacific Ocean &gt; Micronesia &gt; Federated States of Micronesia Ocean &gt; Pacific Ocean &gt; United States of America &gt; Territories Federated States of Micronesia &gt; Pohnpei &gt; Pohnpei Lagoon Pacific Islands Ocean Observing System (PacIOOS) Pacific Islands Ocean Observing System (PacIOOS) sea_water_temperature sea_water_electrical_conductivity sea_water_turbidity mass_concentration_of_chlorophyll_in_sea_water sea_water_salinity depth latitude longitude time climatologyMeteorologyAtmosphere WWW:LINK http://oos.soest.hawaii.edu/thredds/idd/nss_pacioos.html?dataset=NS06agg http://oos.soest.hawaii.edu/thredds/dodsC/pacioos/nss/ns06agg.html http://pacioos.org/voyager/index.html?b=6.874279%2C158.077126%2C7.050468%2C158.369808&tz=pont&o=qual:2::p0NS06p1 http://oos.soest.hawaii.edu/dchart/index.html?dsetid=54cd0688ada08d86748b9c5762509f http://oos.soest.hawaii.edu/erddap/tabledap/nss06_agg.graph?time%2Ctemperature&.draw=lines http://pacioos.org/focus/waterquality/wq_fsm.php http://oos.soest.hawaii.edu/thredds/dodsC/pacioos/nss/ns06agg http://pacioos.org/metadata/browse/NS06agg.png 2014-04-16 The nearshore sensors are part of the Pacific Islands Ocean Observing System (PacIOOS) and are designed to measure a variety of ocean parameters at fixed point locations. NS06 is located at the dock in Pohnpei lagoon and is mounted to the bottom in about 1 meter of water. The instrument is a Sea-Bird Electronics model 16+ V2 coupled with a WET Labs ECO-FLNTUS combination sensor. 2014-04-16 eng 6.96 158.22 6.96 158.22 ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecordById-full.xml ================================================ de53e931-778a-4792-94ad-9fe507aca483 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication de53e931-778a-4792-94ad-9fe507aca483 T_ortho_RAS_1998_284404.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.47878421.52731739.7600139.790341 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecordById-srv-brief.xml ================================================ 3e9a8c05 service test Title 2011-04-19 creation view Geographic viewer (humanGeographicViewer) administration 19.37 29.61 34.8 41.75 http://aiolos.survey.ntua.gr/geoserver/wms ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecords-all-csw-output.xml ================================================ 3e9a8c05 eng service NTUA tzotsos@gmail.com pointOfContact 2011-04-18 ISO19115 2003/Cor.1:2006 test Title 2011-04-19 creation http://aiolos.survey.ntua.gr ogc test Abstract NTUA tzotsos@gmail.com owner Geographic viewer (humanGeographicViewer) administration GEMET Themes, version 2.3 2011-04-18 publication Conditions unknown no limitation 19.37 29.61 34.80 41.75 2011-04-18 2011-04-20 view http://aiolos.survey.ntua.gr/geoserver/wms service Conformity_001 INSPIRE Corrigendum to INSPIRE Metadata Regulation published in the Official Journal of the European Union, L 328, page 83 2009-12-15 publication See the referenced specification true 366f6257-19eb-4f20-ba78-0698ac4aae77 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 366f6257-19eb-4f20-ba78-0698ac4aae77 T_aerfo_RAS_1991_GR800P001800000012.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test 75a7eb5e-336e-453d-ab06-209b1070d396 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 75a7eb5e-336e-453d-ab06-209b1070d396 T_aerfo_RAS_1991_GR800P001800000013.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test a7308c0a-b748-48e2-bab7-0a608a51d416 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation a7308c0a-b748-48e2-bab7-0a608a51d416 T_aerfo_RAS_1991_GR800P001800000014.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test 0173e0d7-6ea9-4407-b846-f29d6bfa9903 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 0173e0d7-6ea9-4407-b846-f29d6bfa9903 T_aerfo_RAS_1991_GR800P001800000015.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecords-all.xml ================================================ 3e9a8c05 eng service NTUA tzotsos@gmail.com pointOfContact 2011-04-18 ISO19115 2003/Cor.1:2006 test Title 2011-04-19 creation http://aiolos.survey.ntua.gr ogc test Abstract NTUA tzotsos@gmail.com owner Geographic viewer (humanGeographicViewer) administration GEMET Themes, version 2.3 2011-04-18 publication Conditions unknown no limitation 19.37 29.61 34.80 41.75 2011-04-18 2011-04-20 view http://aiolos.survey.ntua.gr/geoserver/wms service Conformity_001 INSPIRE Corrigendum to INSPIRE Metadata Regulation published in the Official Journal of the European Union, L 328, page 83 2009-12-15 publication See the referenced specification true 366f6257-19eb-4f20-ba78-0698ac4aae77 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 366f6257-19eb-4f20-ba78-0698ac4aae77 T_aerfo_RAS_1991_GR800P001800000012.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test 75a7eb5e-336e-453d-ab06-209b1070d396 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 75a7eb5e-336e-453d-ab06-209b1070d396 T_aerfo_RAS_1991_GR800P001800000013.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test a7308c0a-b748-48e2-bab7-0a608a51d416 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation a7308c0a-b748-48e2-bab7-0a608a51d416 T_aerfo_RAS_1991_GR800P001800000014.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test 0173e0d7-6ea9-4407-b846-f29d6bfa9903 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 0173e0d7-6ea9-4407-b846-f29d6bfa9903 T_aerfo_RAS_1991_GR800P001800000015.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecords-cql-title.xml ================================================ a2744b0c-becd-426a-95a8-46e9850ccc6d dataset DTM 2009-10-07 creation 19.0 30.0 34.0 42.0 http://www.ypaat.gr 0dc824a6-b555-46c1-bd7b-bc66cb91a70f dataset DTM 2009-10-07 creation 19.0 30.0 34.0 42.0 http://www.ypaat.gr 42c8e55a-2bf6-476d-a7c9-be3bcd697f13 dataset DTM 2009-10-07 creation 19.0 30.0 34.0 42.0 http://www.ypaat.gr c3bf29d4-d60a-4959-a415-2c03fb0d4aef dataset DTM 2009-10-07 creation 19.0 30.0 34.0 42.0 http://www.ypaat.gr b8cc2388-5d0a-43d8-9473-0e86dd0396da dataset DTM 2009-10-07 creation 19.0 30.0 34.0 42.0 http://www.ypaat.gr ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecords-elementname.xml ================================================ 3e9a8c05 service test Title 2011-04-19 creation view Geographic viewer (humanGeographicViewer) administration 19.37 29.61 34.8 41.75 http://aiolos.survey.ntua.gr/geoserver/wms 366f6257-19eb-4f20-ba78-0698ac4aae77 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr 75a7eb5e-336e-453d-ab06-209b1070d396 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr a7308c0a-b748-48e2-bab7-0a608a51d416 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr 0173e0d7-6ea9-4407-b846-f29d6bfa9903 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecords-filter-and-nested-spatial-or-dateline.xml ================================================ NS06agg eng UTF8 dataset service Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information pointOfContact 2014-04-16 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 1 0.0 row 1 0.0 temporal 482760 252.0 area PacIOOS Nearshore Sensor 06: Pohnpei, Micronesia 2011-04-12 creation 2011-04-19 issued 2014-03-18 revision org.pacioos NS06agg Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information originator Jim Potemra distributor Data produced by Dr. Margaret McManus (mamc@hawaii.edu). Point of contact: Gordon Walker (gwalker@hawaii.edu). The nearshore sensors are part of the Pacific Islands Ocean Observing System (PacIOOS) and are designed to measure a variety of ocean parameters at fixed point locations. NS06 is located at the dock in Pohnpei lagoon and is mounted to the bottom in about 1 meter of water. The instrument is a Sea-Bird Electronics model 16+ V2 coupled with a WET Labs ECO-FLNTUS combination sensor. PacIOOS provides timely, reliable, and accurate ocean information to support a safe, clean, productive ocean and resilient coastal zone in the U.S. Pacific Islands region. The Pacific Islands Ocean Observing System (PacIOOS) is funded through the National Oceanic and Atmospheric Administration (NOAA) as a Regional Association within the U.S. Integrated Ocean Observing System (IOOS). PacIOOS is coordinated by the University of Hawaii School of Ocean and Earth Science and Technology (SOEST). Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information pointOfContact http://pacioos.org/metadata/browse/NS06agg.png Sample image. Oceans > Ocean Chemistry > Chlorophyll Oceans > Ocean Optics > Turbidity Oceans > Ocean Temperature > Water Temperature Oceans > Salinity/Density > Conductivity Oceans > Salinity/Density > Salinity Oceans > Water Quality theme GCMD Science Keywords Ocean &gt; Pacific Ocean &gt; Western Pacific Ocean &gt; Micronesia &gt; Federated States of Micronesia Ocean &gt; Pacific Ocean &gt; United States of America &gt; Territories Federated States of Micronesia &gt; Pohnpei &gt; Pohnpei Lagoon place GCMD Location Keywords Pacific Islands Ocean Observing System (PacIOOS) project GCMD Project Keywords Pacific Islands Ocean Observing System (PacIOOS) dataCenter GCMD Data Center Keywords sea_water_temperature sea_water_electrical_conductivity sea_water_turbidity mass_concentration_of_chlorophyll_in_sea_water sea_water_salinity depth latitude longitude time theme CF-1.4 The data may be used and redistributed for free but is not intended for legal use, since it may contain inaccuracies. Neither the data Contributor, University of Hawaii, PacIOOS, NOAA, State of Hawaii nor the United States Government, nor any of their employees or contractors, makes any warranty, express or implied, including warranties of merchantability and fitness for a particular purpose, or assumes any legal liability for the accuracy, completeness, or usefulness, of this information. Pacific Islands Ocean Observing System (PacIOOS) largerWorkCitation project Unidata Common Data Model Point largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 158.22402954101562 158.22402954101562 6.955227375030518 6.955227375030518 seconds 2010-05-07T00:00:00Z 2014-03-17T23:56:00Z -1.0 -1.0 PacIOOS Nearshore Sensor 06: Pohnpei, Micronesia 2011-04-12 creation 2011-04-19 issued 2014-03-18 revision Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information originator Jim Potemra distributor The nearshore sensors are part of the Pacific Islands Ocean Observing System (PacIOOS) and are designed to measure a variety of ocean parameters at fixed point locations. NS06 is located at the dock in Pohnpei lagoon and is mounted to the bottom in about 1 meter of water. The instrument is a Sea-Bird Electronics model 16+ V2 coupled with a WET Labs ECO-FLNTUS combination sensor. THREDDS OPeNDAP 1 158.22402954101562 158.22402954101562 6.955227375030518 6.955227375030518 2010-05-07T00:00:00Z 2014-03-17T23:56:00Z -1.0 -1.0 tight OPeNDAP Client Access http://oos.soest.hawaii.edu/thredds/dodsC/pacioos/nss/ns06agg OPeNDAP THREDDS OPeNDAP download temp float Temperature (sea_water_temperature) cond float Conductivity (sea_water_electrical_conductivity) turb float Turbidity (sea_water_turbidity) flor float Chlorophyll (mass_concentration_of_chlorophyll_in_sea_water) salt float Salinity (sea_water_salinity) z float depth below mean sea level (depth) lat float Latitude (latitude) lon float Longitude (longitude) time float Time (time) Pacific Islands Ocean Observing System (PacIOOS) jimp@hawaii.edu http://pacioos.org http web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://oos.soest.hawaii.edu/thredds/idd/nss_pacioos.html?dataset=NS06agg THREDDS Catalog This URL provides a catalog page for this dataset within THREDDS Data Server (TDS). download http://oos.soest.hawaii.edu/thredds/dodsC/pacioos/nss/ns06agg.html File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://pacioos.org/voyager/index.html?b=6.874279%2C158.077126%2C7.050468%2C158.369808&tz=pont&o=qual:2::p0NS06p1 PacIOOS Voyager (Google Maps API) This URL provides a viewer for this dataset. download http://oos.soest.hawaii.edu/dchart/index.html?dsetid=54cd0688ada08d86748b9c5762509f DChart This URL provides a viewer for this dataset. download http://oos.soest.hawaii.edu/erddap/tabledap/nss06_agg.graph?time%2Ctemperature&.draw=lines ERDDAP This URL provides a viewer for this dataset. download http://pacioos.org/focus/waterquality/wq_fsm.php PacIOOS Water Quality Platforms: FSM This URL provides a viewer for this dataset. download dataset UH/SOEST (M. McManus), PacIOOS asset (05/2010) This record was translated from NcML using UnidataDD2MI.xsl Version 2.3 ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecords-filter-anytext.xml ================================================ 366f6257-19eb-4f20-ba78-0698ac4aae77 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr 75a7eb5e-336e-453d-ab06-209b1070d396 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr a7308c0a-b748-48e2-bab7-0a608a51d416 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr 0173e0d7-6ea9-4407-b846-f29d6bfa9903 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr 437ae0a2-06e2-4015-b296-a66e7f407bf2 dataset Aerial Photos 2009-10-09 creation 20.0 38.0 24.0 40.0 http://www.ypaat.gr ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecords-filter-bbox-csw-output.xml ================================================ 3e9a8c05 test Title service 34.8 19.37 41.75 29.61 366f6257-19eb-4f20-ba78-0698ac4aae77 Aerial Photos dataset 38.0 20.0 40.0 24.0 75a7eb5e-336e-453d-ab06-209b1070d396 Aerial Photos dataset 38.0 20.0 40.0 24.0 a7308c0a-b748-48e2-bab7-0a608a51d416 Aerial Photos dataset 38.0 20.0 40.0 24.0 0173e0d7-6ea9-4407-b846-f29d6bfa9903 Aerial Photos dataset 38.0 20.0 40.0 24.0 ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecords-filter-bbox.xml ================================================ 3e9a8c05 service test Title 2011-04-19 creation view Geographic viewer (humanGeographicViewer) administration 19.37 29.61 34.8 41.75 http://aiolos.survey.ntua.gr/geoserver/wms 366f6257-19eb-4f20-ba78-0698ac4aae77 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr 75a7eb5e-336e-453d-ab06-209b1070d396 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr a7308c0a-b748-48e2-bab7-0a608a51d416 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr 0173e0d7-6ea9-4407-b846-f29d6bfa9903 dataset Aerial Photos 2009-10-09 creation 20.0 24.0 38.0 40.0 http://www.ypaat.gr ================================================ FILE: tests/functionaltests/suites/apiso/expected/post_GetRecords-filter-servicetype.xml ================================================ 3e9a8c05 service test Title 2011-04-19 creation view Geographic viewer (humanGeographicViewer) administration 19.37 29.61 34.8 41.75 http://aiolos.survey.ntua.gr/geoserver/wms ================================================ FILE: tests/functionaltests/suites/apiso/post/DescribeRecord.xml ================================================ gmd:MD_Metadata ================================================ FILE: tests/functionaltests/suites/apiso/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/apiso/post/GetDomain-property.xml ================================================ apiso:TopicCategory ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecordById-brief.xml ================================================ de53e931-778a-4792-94ad-9fe507aca483 brief ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecordById-full-dc.xml ================================================ NS06agg full ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecordById-full.xml ================================================ de53e931-778a-4792-94ad-9fe507aca483 full ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecordById-srv-brief.xml ================================================ 3e9a8c05 brief ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecords-all-csw-output.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecords-all.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecords-cql-title.xml ================================================ brief apiso:TopicCategory like '%elevation%' ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecords-elementname.xml ================================================ apiso:Title ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecords-filter-and-nested-spatial-or-dateline.xml ================================================ full csw:AnyText *pacioos* ows:BoundingBox 5.0721 17.8247 31.7842 180 ows:BoundingBox 15.0721 -180 31.7842 -151.2378 dc:title ASC ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecords-filter-anytext.xml ================================================ brief apiso:AnyText Aerial% ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecords-filter-bbox-csw-output.xml ================================================ brief apiso:BoundingBox 35 18 42 28 ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecords-filter-bbox.xml ================================================ brief apiso:BoundingBox 35 18 42 28 ================================================ FILE: tests/functionaltests/suites/apiso/post/GetRecords-filter-servicetype.xml ================================================ brief apiso:ServiceType view ================================================ FILE: tests/functionaltests/suites/apiso-inspire/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/apiso-inspire/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true # gzip_compresslevel: 8 #spatial_ranking: true profiles: - apiso logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: true languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/apiso-inspire/expected/get_GetCapabilities-lang.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record gmd:MD_Metadata DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record gmd:MD_Metadata apiso:AccessConstraints apiso:Bands apiso:Classification apiso:CloudCover apiso:ConditionApplyingToAccessAndUse apiso:Contributor apiso:Creator apiso:Degree apiso:IlluminationElevationAngle apiso:Instrument apiso:Lineage apiso:OtherConstraints apiso:Platform apiso:Publisher apiso:Relation apiso:ResponsiblePartyRole apiso:SensorType apiso:SpecificationDate apiso:SpecificationDateType apiso:SpecificationTitle csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox apiso:Abstract apiso:AlternateTitle apiso:AnyText apiso:BoundingBox apiso:CRS apiso:CouplingType apiso:CreationDate apiso:Denominator apiso:DistanceUOM apiso:DistanceValue apiso:Edition apiso:Format apiso:GeographicDescriptionCode apiso:HasSecurityConstraints apiso:Identifier apiso:KeywordType apiso:Language apiso:Modified apiso:OperatesOn apiso:OperatesOnIdentifier apiso:OperatesOnName apiso:Operation apiso:OrganisationName apiso:ParentIdentifier apiso:PublicationDate apiso:ResourceLanguage apiso:RevisionDate apiso:ServiceType apiso:ServiceTypeVersion apiso:Subject apiso:TempExtent_begin apiso:TempExtent_end apiso:Title apiso:TopicCategory apiso:Type brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/apiso-inspire/default.yml&service=CSW&version=2.0.2&request=GetCapabilities application/xml service 2011-02-01 2011-03-30 COMMISSION REGULATION (EU) No 1089/2010 of 23 November 2010 implementing Directive 2007/2/EC of the European Parliament and of the Council as regards interoperability of spatial data sets and services 2010-12-08 OJ:L:2010:323:0011:0102:EN:PDF http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2010:323:0011:0102:EN:PDF application/pdf notEvaluated National Technical University of Athens tzotsos@gmail.com 2011-03-29 discovery infoCatalogueService GEMET - INSPIRE themes 2008-06-01 Utility and governmental services eng eng gre eng gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/apiso-inspire/expected/get_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record gmd:MD_Metadata DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record gmd:MD_Metadata apiso:AccessConstraints apiso:Bands apiso:Classification apiso:CloudCover apiso:ConditionApplyingToAccessAndUse apiso:Contributor apiso:Creator apiso:Degree apiso:IlluminationElevationAngle apiso:Instrument apiso:Lineage apiso:OtherConstraints apiso:Platform apiso:Publisher apiso:Relation apiso:ResponsiblePartyRole apiso:SensorType apiso:SpecificationDate apiso:SpecificationDateType apiso:SpecificationTitle csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox apiso:Abstract apiso:AlternateTitle apiso:AnyText apiso:BoundingBox apiso:CRS apiso:CouplingType apiso:CreationDate apiso:Denominator apiso:DistanceUOM apiso:DistanceValue apiso:Edition apiso:Format apiso:GeographicDescriptionCode apiso:HasSecurityConstraints apiso:Identifier apiso:KeywordType apiso:Language apiso:Modified apiso:OperatesOn apiso:OperatesOnIdentifier apiso:OperatesOnName apiso:Operation apiso:OrganisationName apiso:ParentIdentifier apiso:PublicationDate apiso:ResourceLanguage apiso:RevisionDate apiso:ServiceType apiso:ServiceTypeVersion apiso:Subject apiso:TempExtent_begin apiso:TempExtent_end apiso:Title apiso:TopicCategory apiso:Type brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/apiso-inspire/default.yml&service=CSW&version=2.0.2&request=GetCapabilities application/xml service 2011-02-01 2011-03-30 COMMISSION REGULATION (EU) No 1089/2010 of 23 November 2010 implementing Directive 2007/2/EC of the European Parliament and of the Council as regards interoperability of spatial data sets and services 2010-12-08 OJ:L:2010:323:0011:0102:EN:PDF http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=OJ:L:2010:323:0011:0102:EN:PDF application/pdf notEvaluated National Technical University of Athens tzotsos@gmail.com 2011-03-29 discovery infoCatalogueService GEMET - INSPIRE themes 2008-06-01 Utility and governmental services eng eng gre eng gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/apiso-inspire/get/requests.txt ================================================ GetCapabilities,service=CSW&version=2.0.2&request=GetCapabilities GetCapabilities-lang,service=CSW&version=2.0.2&request=GetCapabilities&lang=gre ================================================ FILE: tests/functionaltests/suites/atom/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #spatial_ranking: true gzip_compresslevel: 9 logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-description.xml ================================================ pycsw Geospatial Catalogue pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery https://pycsw.org/img/favicon.ico Kralidis, Tom tomkralidis@gmail.com pycsw ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-bbox-and-time.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 2 1 2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum PYCSW_TIMESTAMP 44.79 -6.17 51.13 -2.23 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque PYCSW_TIMESTAMP Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-bbox.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 3 1 3 urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd PYCSW_TIMESTAMP Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque PYCSW_TIMESTAMP Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum PYCSW_TIMESTAMP 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-count-and-page1.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 2 1 2 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus PYCSW_TIMESTAMP urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque PYCSW_TIMESTAMP Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-count-and-page2.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 2 1 1 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus PYCSW_TIMESTAMP ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-q-and-bbox.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 1 1 1 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque PYCSW_TIMESTAMP Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-q-and-time.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 1 1 1 urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db Fuscé vitae ligulä PYCSW_TIMESTAMP Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-q.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 1 1 1 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum PYCSW_TIMESTAMP Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-time.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 1 1 1 urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db Fuscé vitae ligulä PYCSW_TIMESTAMP Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-timeend.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 1 1 1 urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db Fuscé vitae ligulä PYCSW_TIMESTAMP Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch-ogc-timestart.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 3 1 3 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum PYCSW_TIMESTAMP 44.79 -6.17 51.13 -2.23 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque PYCSW_TIMESTAMP Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu PYCSW_TIMESTAMP Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. ================================================ FILE: tests/functionaltests/suites/atom/expected/get_opensearch.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/atom/default.yml pycsw Geospatial Catalogue 12 1 10 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum PYCSW_TIMESTAMP Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd PYCSW_TIMESTAMP Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim PYCSW_TIMESTAMP Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus PYCSW_TIMESTAMP urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu PYCSW_TIMESTAMP Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus PYCSW_TIMESTAMP urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 PYCSW_TIMESTAMP Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque PYCSW_TIMESTAMP Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum PYCSW_TIMESTAMP 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet PYCSW_TIMESTAMP ================================================ FILE: tests/functionaltests/suites/atom/expected/post_DescribeRecord.xml ================================================ ================================================ FILE: tests/functionaltests/suites/atom/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/atom/expected/post_GetRecords-filter-bbox.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque PYCSW_TIMESTAMP Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum PYCSW_TIMESTAMP 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/atom/get/requests.txt ================================================ opensearch,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&resulttype=results&elementsetname=brief opensearch-description,mode=opensearch&service=CSW&version=2.0.2&request=GetCapabilities opensearch-ogc-q,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&q=greece opensearch-ogc-bbox,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&bbox=-180,-90,180,90 opensearch-ogc-time,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=2001/2004 opensearch-ogc-timestart,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=2004/ opensearch-ogc-timeend,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=/2004 opensearch-ogc-q-and-time,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=2001/2007&q=vitae opensearch-ogc-bbox-and-time,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=2001/2007&bbox=-180,-90,180,90 opensearch-ogc-q-and-bbox,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&q=vegetation&bbox=-180,-90,180,90 opensearch-ogc-count-and-page1,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&q=vegetation&startposition=1 opensearch-ogc-count-and-page2,mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&q=vegetation&startposition=1&maxrecords=1 ================================================ FILE: tests/functionaltests/suites/atom/post/DescribeRecord.xml ================================================ atom:entry ================================================ FILE: tests/functionaltests/suites/atom/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/atom/post/GetRecords-filter-bbox.xml ================================================ brief ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/cite/data/README.txt ================================================ CITE Data ========= This directory provides data used to check conformance against the Open Geospatial Consortium Compliance and Interoperability Testing Initiative (CITE). * http://cite.opengeospatial.org/teamengine/ The CITE team engine does not offer a specific license for re-distribution, as such it falls under the general guidance provided by the OGC legal page (http://www.opengeospatial.org/legal/) and the following license: * http://www.opengeospatial.org/ogc/software DATA LICENSE ------------ The data directory includes information provided by the Open Geospatial Consortium:: Copyright © 2012 Open Geospatial Consortium, Inc. All Rights Reserved. http://www.opengeospatial.org/ogc/legal The test data is available directly from the following link: * http://cite.opengeospatial.org/teamengine/about/csw/2.0.2/web/ This content has been format shifted from CSW record format into a text based "property file" for release testing. Software Notice --------------- This OGC work (including software, documents, or other related items) is being provided by the copyright holders under the following license. By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions: Permission to use, copy, and modify this software and its documentation, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications, that you make: 1. The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. 2. Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed or derivative code: "Copyright © [$date-of-document] Open Geospatial Consortium, Inc. All Rights Reserved. http://www.opengeospatial.org/ogc/legal (Hypertext is preferred, but a textual representation is permitted.) 3. Notice of any changes or modifications to the OGC files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.) THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders. ================================================ FILE: tests/functionaltests/suites/cite/data/Record_19887a8a-f6b0-4a63-ae56-7fba0e17801f.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/cite/data/Record_1ef30a8b-876d-4828-9246-c37ab4510bbd.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.042 13.754 68.410 17.920 ================================================ FILE: tests/functionaltests/suites/cite/data/Record_66ae76b7-54ba-489b-a582-0f0633d96493.xml ================================================ urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. ================================================ FILE: tests/functionaltests/suites/cite/data/Record_6a3de50b-fa66-4b58-a0e6-ca146fdd18d4.xml ================================================ urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 ================================================ FILE: tests/functionaltests/suites/cite/data/Record_784e2afd-a9fd-44a6-9a92-a3848371c8ec.xml ================================================ urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. ================================================ FILE: tests/functionaltests/suites/cite/data/Record_829babb0-b2f1-49e1-8cd5-7b489fe71a1e.xml ================================================ urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e http://purl.org/dc/dcmitype/Image image/jp2 Vestibulum massa purus urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc ================================================ FILE: tests/functionaltests/suites/cite/data/Record_88247b56-4cbc-4df9-9860-db3f8042e357.xml ================================================ urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms FI-ES Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. ================================================ FILE: tests/functionaltests/suites/cite/data/Record_94bc9c83-97f6-4b40-9eb8-a8e8787a5c63.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 ================================================ FILE: tests/functionaltests/suites/cite/data/Record_9a669547-b69b-469f-a11f-2d875366bbdc.xml ================================================ urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 2005-10-24 44.792 -6.171 51.126 -2.228 ================================================ FILE: tests/functionaltests/suites/cite/data/Record_a06af396-3105-442d-8b40-22b57a90d2f2.xml ================================================ urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI ================================================ FILE: tests/functionaltests/suites/cite/data/Record_ab42a8c4-95e8-4630-bf79-33e59241605a.xml ================================================ urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service Physiography Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam. urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 ================================================ FILE: tests/functionaltests/suites/cite/data/Record_e9330592-0932-474b-be34-c3a3bb67c7db.xml ================================================ urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text Fuscé vitae ligulä 2003-05-09 Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. ================================================ FILE: tests/functionaltests/suites/cite/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/cite/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US #maxrecords: 10 pretty_print: true #spatial_ranking: true gzip_compresslevel: 9 logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: true allowed_ips: - 127.0.0.1 csw_harvest_pagination_size: 10 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: #enabled: true languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/cite/expected/get_27e17158-c57a-4493-92ac-dba8934cf462.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/cite/expected/get_27f69b66-5f05-4311-a89c-73ca55c2686b.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/cite/expected/get_2ab7d1fa-885b-459f-80e4-b6282eab4f8c.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/cite/expected/get_37aa90e2-6ff0-420c-af15-8b9463099a73.xml ================================================ urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset Hydrography-Oceanographic 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/cite/expected/get_3a8a3c47-455f-4f49-9078-03119f3e70b3.xml ================================================ Invalid acceptFormats parameter value: message/example ================================================ FILE: tests/functionaltests/suites/cite/expected/get_4515831f-834a-4699-95f6-ab0c2cbfcfd0.xml ================================================ Missing id parameter ================================================ FILE: tests/functionaltests/suites/cite/expected/get_477b23a3-baa9-47c8-9541-5fe27735ed49.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/cite/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://catalogue.arctic-sdi.org/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://catalogue.arctic-sdi.org/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/cite/expected/get_48f26761-3a9d-48db-bee1-da089f5fb857.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/cite/expected/get_4e38092f-1586-44b8-988e-0acfa5855916.xml ================================================ Invalid outputformat parameter application/bogus_xml ================================================ FILE: tests/functionaltests/suites/cite/expected/get_55c38f00-2553-42c1-99ab-33edbb561ad7.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/cite/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://catalogue.arctic-sdi.org/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://catalogue.arctic-sdi.org/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE ================================================ FILE: tests/functionaltests/suites/cite/expected/get_5ab5db18-c87a-4fbf-a8d8-b7289b09ac81.xml ================================================ Invalid value for service: FOO. Value MUST be CSW ================================================ FILE: tests/functionaltests/suites/cite/expected/get_6a4f57ca-a1bd-4802-89c2-44860dbdb0f0.xml ================================================ urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 ================================================ FILE: tests/functionaltests/suites/cite/expected/get_6c375703-9c00-4aef-bec7-d2e964f849eb.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum PYCSW_TIMESTAMP Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/cite/expected/get_80f31def-4185-48b9-983a-960566918eae.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/cite/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://catalogue.arctic-sdi.org/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://catalogue.arctic-sdi.org/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/cite/expected/get_8e2232ed-05d9-44ae-8b04-0911cbe6a507.xml ================================================ Invalid parameter value in acceptversions: 2006.10.29. Value MUST be 2.0.2 or 3.0.0 ================================================ FILE: tests/functionaltests/suites/cite/expected/get_9697f0aa-3b6a-4125-83a5-61e8826127c4.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/cite/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://catalogue.arctic-sdi.org/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://catalogue.arctic-sdi.org/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/cite/expected/get_9bfd17fa-15dc-4a10-8fa7-b3cff7013dd7.xml ================================================ urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text Fuscé vitae ligulä 2003-05-09 Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. ================================================ FILE: tests/functionaltests/suites/cite/expected/get_b81c3595-06d6-4693-82ea-1ff8650755ac.xml ================================================ ================================================ FILE: tests/functionaltests/suites/cite/expected/get_ba5fc729-3b71-47a0-b7d0-42ec565cd185.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/cite/expected/get_c4ea754f-c158-4d8d-8253-dc8f86021b52.xml ================================================ Missing keyword: service ================================================ FILE: tests/functionaltests/suites/cite/expected/get_f4692ec5-9547-4a05-88ab-e6154af2640a.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/cite/expected/get_f997f25e-c865-4d53-a362-0ed1846337f2.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_0c976d98-c896-4b10-b1fe-a22ef50434e7.xml ================================================ ================================================ FILE: tests/functionaltests/suites/cite/expected/post_19d2a6ed-be28-4866-ae15-e3bb634486cb.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service ================================================ FILE: tests/functionaltests/suites/cite/expected/post_1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml ================================================ full csw:AnyText *lorem* ================================================ FILE: tests/functionaltests/suites/cite/expected/post_1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml ================================================ Invalid outputFormat parameter value: application/xhtml+xml ================================================ FILE: tests/functionaltests/suites/cite/expected/post_1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml ================================================ Invalid Constraint: Invalid Filter request: Invalid PropertyName: /dc:title. '/dc:title' ================================================ FILE: tests/functionaltests/suites/cite/expected/post_2102a460-5d62-465f-9668-d70b3faafbfa.xml ================================================ urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service ================================================ FILE: tests/functionaltests/suites/cite/expected/post_225f455a-0035-486b-a94e-fee7ae881b2b.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset 2006-03-26 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec http://purl.org/dc/dcmitype/Text 2006-05-12 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_2d53ffea-60e4-4652-abf5-36eb23042fd5.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/cite/expected/post_34a019a9-1581-42cb-9827-fbfdda2773b7.xml ================================================ ================================================ FILE: tests/functionaltests/suites/cite/expected/post_3e76fd38-e035-41c9-83dc-61356f680c97.xml ================================================ Invalid value for schemalanguage: http://purl.oclc.org/dsdl/schematron ================================================ FILE: tests/functionaltests/suites/cite/expected/post_418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 2006-03-26 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_420b745e-0c4b-404e-9f2d-61fa580ff05a.xml ================================================ urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset 2005-10-24 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset 2006-03-26 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec http://purl.org/dc/dcmitype/Text 2006-05-12 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_4735d649-a2b1-42fd-a101-14e1d7e4607f.xml ================================================ urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text Marine sediments application/xhtml+xml Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image image/jp2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. ================================================ FILE: tests/functionaltests/suites/cite/expected/post_5c5861bc-f742-40a5-9998-5342615d674b.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms FI-ES Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service Physiography Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam. urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text Marine sediments application/xhtml+xml Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image image/jp2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset Hydrography-Oceanographic 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image image/jpeg ================================================ FILE: tests/functionaltests/suites/cite/expected/post_73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml ================================================ urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 2005-10-24 44.792 -6.171 51.126 -2.228 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_78297c88-4850-4927-adc6-511cd9a3d539.xml ================================================ http://schemas.opengis.net/csw/2.0.2/record.xsd This schema defines the basic record types that must be supported by all CSW implementations. These correspond to full, summary, and brief views based on DCMI metadata terms. CSW is an OGC Standard. Copyright (c) 2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This type encapsulates all of the standard DCMI metadata terms, including the Dublin Core refinements; these terms may be mapped to the profile-specific information model. This type defines a brief representation of the common record format. It extends AbstractRecordType to include only the dc:identifier and dc:type properties. This type defines a summary representation of the common record format. It extends AbstractRecordType to include the core properties. This type extends DCMIRecordType to add ows:BoundingBox; it may be used to specify a spatial envelope for the catalogued resource. ================================================ FILE: tests/functionaltests/suites/cite/expected/post_7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum PYCSW_TIMESTAMP Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd PYCSW_TIMESTAMP Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim PYCSW_TIMESTAMP Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus PYCSW_TIMESTAMP urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu PYCSW_TIMESTAMP Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. ================================================ FILE: tests/functionaltests/suites/cite/expected/post_7e2cd105-daec-4d25-bc8e-d49d21364912.xml ================================================ ================================================ FILE: tests/functionaltests/suites/cite/expected/post_87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 http://purl.org/dc/dcmitype/Text urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec http://purl.org/dc/dcmitype/Text 2006-05-12 urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset 2006-03-26 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset 2005-10-24 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/cite/expected/post_88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml ================================================ Invalid value for outputformat: text/sgml ================================================ FILE: tests/functionaltests/suites/cite/expected/post_898cd63b-2585-4ec0-8720-d554bd324174.xml ================================================ urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image image/jp2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc ================================================ FILE: tests/functionaltests/suites/cite/expected/post_8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db ================================================ FILE: tests/functionaltests/suites/cite/expected/post_928c1896-52d4-4ac7-9832-f98e3eb65f02.xml ================================================ urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text 2003-05-09 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset 2005-10-24 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_93bdbb9d-2734-4f01-92fb-48634cca41de.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml ================================================ urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec http://purl.org/dc/dcmitype/Text 2006-05-12 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset 2006-03-26 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset 2005-10-24 urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text 2003-05-09 urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e http://purl.org/dc/dcmitype/Image urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 http://purl.org/dc/dcmitype/Text ================================================ FILE: tests/functionaltests/suites/cite/expected/post_9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml ================================================ Typename not qualified: Record ================================================ FILE: tests/functionaltests/suites/cite/expected/post_a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/cite/expected/post_ad61686c-d304-42d1-b845-8c1f3070c83e.xml ================================================ Exception: the document is not valid. Error: Element '{http://www.opengis.net/foo}Filter': This element is not expected. Expected is one of ( {http://www.opengis.net/ogc}Filter, {http://www.opengis.net/cat/csw/2.0.2}CqlText ). (<string>, line 0) ================================================ FILE: tests/functionaltests/suites/cite/expected/post_af39c020-7b1d-429c-b474-f45c3164cb79.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image image/jpeg ================================================ FILE: tests/functionaltests/suites/cite/expected/post_b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text Marine sediments application/xhtml+xml Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image image/jp2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset Hydrography-Oceanographic 44.79 -6.17 51.13 -2.23 urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service Physiography urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam. urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db Fuscé vitae ligulä http://purl.org/dc/dcmitype/Text Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. ================================================ FILE: tests/functionaltests/suites/cite/expected/post_ba9b0107-dcee-46ef-823a-a2e25a911a96.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text Marine sediments application/xhtml+xml Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image image/jp2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image image/jpeg ================================================ FILE: tests/functionaltests/suites/cite/expected/post_bb66ebc5-7121-48b5-9f53-b56537d9561b.xml ================================================ urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_c02d1c85-df9f-45ee-bea7-345c35e02a98.xml ================================================ Invalid Constraint: Invalid Filter request: 'NoneType' object has no attribute 'text' ================================================ FILE: tests/functionaltests/suites/cite/expected/post_c311a342-72e3-4983-be39-868e6ed9740f.xml ================================================ http://schemas.opengis.net/csw/2.0.2/record.xsd This schema defines the basic record types that must be supported by all CSW implementations. These correspond to full, summary, and brief views based on DCMI metadata terms. CSW is an OGC Standard. Copyright (c) 2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This type encapsulates all of the standard DCMI metadata terms, including the Dublin Core refinements; these terms may be mapped to the profile-specific information model. This type defines a brief representation of the common record format. It extends AbstractRecordType to include only the dc:identifier and dc:type properties. This type defines a summary representation of the common record format. It extends AbstractRecordType to include the core properties. This type extends DCMIRecordType to add ows:BoundingBox; it may be used to specify a spatial envelope for the catalogued resource. ================================================ FILE: tests/functionaltests/suites/cite/expected/post_c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml ================================================ urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec 2006-05-12 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 2006-03-26 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc 2005-10-24 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_c8588f47-8e65-45f5-ad34-ff4524cad84d.xml ================================================ Invalid Constraint: Invalid Filter request: Invalid ogc:PropertyName in spatial filter: dct:spatial ================================================ FILE: tests/functionaltests/suites/cite/expected/post_da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml ================================================ Invalid Constraint: Invalid Filter request: Invalid PropertyName: /dc:title. '/dc:title' ================================================ FILE: tests/functionaltests/suites/cite/expected/post_dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml ================================================ urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text 2003-05-09 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset 2005-10-24 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset 2006-03-26 ================================================ FILE: tests/functionaltests/suites/cite/expected/post_dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/cite/expected/post_e308f030-c097-4036-a838-44bad74c9ef7.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/cite/expected/post_e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/cite/expected/post_f7976c55-a156-4421-8199-bc0487da4b0f.xml ================================================ http://schemas.opengis.net/csw/2.0.2/record.xsd This schema defines the basic record types that must be supported by all CSW implementations. These correspond to full, summary, and brief views based on DCMI metadata terms. CSW is an OGC Standard. Copyright (c) 2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This type encapsulates all of the standard DCMI metadata terms, including the Dublin Core refinements; these terms may be mapped to the profile-specific information model. This type defines a brief representation of the common record format. It extends AbstractRecordType to include only the dc:identifier and dc:type properties. This type defines a summary representation of the common record format. It extends AbstractRecordType to include the core properties. This type extends DCMIRecordType to add ows:BoundingBox; it may be used to specify a spatial envelope for the catalogued resource. ================================================ FILE: tests/functionaltests/suites/cite/expected/post_f7d79701-f10b-4087-a33c-f62df0a04fd1.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/cite/expected/post_fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml ================================================ urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db Fuscé vitae ligulä http://purl.org/dc/dcmitype/Text ================================================ FILE: tests/functionaltests/suites/cite/expected/post_fe20960f-a26c-4f13-852d-470a0d3233f9.xml ================================================ urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service ================================================ FILE: tests/functionaltests/suites/cite/get/requests.txt ================================================ 27e17158-c57a-4493-92ac-dba8934cf462,service=CSW&version=2.0.2&request=GetCapabilities 27f69b66-5f05-4311-a89c-73ca55c2686b,Service=CSW&Version=2.0.2&Request=GetRecordById&ElementSetName=brief&ID=urn%3Auuid%3A19887a8a-f6b0-4a63-ae56-7fba0e17801f 2ab7d1fa-885b-459f-80e4-b6282eab4f8c,service=CSW&request=GetCapabilities&acceptversions=2.0.2&date=2006-10-20 37aa90e2-6ff0-420c-af15-8b9463099a73,service=CSW&version=2.0.2&request=GetRecordById&id=urn%3Auuid%3A9a669547-b69b-469f-a11f-2d875366bbdc 3a8a3c47-455f-4f49-9078-03119f3e70b3,service=CSW&request=GetCapabilities&acceptformats=message/example 4515831f-834a-4699-95f6-ab0c2cbfcfd0,service=CSW&version=2.0.2&request=GetRecordById 477b23a3-baa9-47c8-9541-5fe27735ed49,service=CSW&request=GetCapabilities§ions= 48f26761-3a9d-48db-bee1-da089f5fb857,sErViCe=CSW&REQUEST=GetCapabilities&version=2.0.2 4e38092f-1586-44b8-988e-0acfa5855916,Service=CSW&Version=2.0.2&Request=GetRecordById&OutputFormat=application/bogus_xml&id=urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2,urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f,urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a 55c38f00-2553-42c1-99ab-33edbb561ad7,service=CSW&request=GetCapabilities§ions=OperationsMetadata,ServiceIdentification 5ab5db18-c87a-4fbf-a8d8-b7289b09ac81,service=FOO&request=GetCapabilities 6a4f57ca-a1bd-4802-89c2-44860dbdb0f0,service=CSW&version=2.0.2&request=GetRecordById&id=urn:uuid:ce8627a0-685c-11db-bd13-0800200c9a66,urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 6c375703-9c00-4aef-bec7-d2e964f849eb,Service=CSW&Version=2.0.2&Request=GetRecordById&OutputSchema=http://www.w3.org/2005/Atom&Id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 80f31def-4185-48b9-983a-960566918eae,service=CSW&request=GetCapabilities 8e2232ed-05d9-44ae-8b04-0911cbe6a507,SERVICE=CSW&REQUEST=GetCapabilities&ACCEPTVERSIONS=2006.10.29 9697f0aa-3b6a-4125-83a5-61e8826127c4,service=CSW&request=GetCapabilities 9bfd17fa-15dc-4a10-8fa7-b3cff7013dd7,Service=CSW&Version=2.0.2&Request=GetRecordById&ElementSetName=full&ID=urn%3Auuid%3Ae9330592-0932-474b-be34-c3a3bb67c7db b81c3595-06d6-4693-82ea-1ff8650755ac,service=CSW&version=2.0.2&request=GetRecordById&id=urn:uuid:ce8627a0-685c-11db-bd13-0800200c9a66 ba5fc729-3b71-47a0-b7d0-42ec565cd185,SERVICE=CSW&REQUEST=GetCapabilities&ACCEPTVERSIONS=2.0.2,2.0.0 c4ea754f-c158-4d8d-8253-dc8f86021b52,request=GetCapabilities f4692ec5-9547-4a05-88ab-e6154af2640a,service=CSW&version=2.0.2&request=GetCapabilities f997f25e-c865-4d53-a362-0ed1846337f2,service=CSW&version=2.0.2&request=GetRecordById&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 ================================================ FILE: tests/functionaltests/suites/cite/post/0c976d98-c896-4b10-b1fe-a22ef50434e7.xml ================================================ dc:identifier ows:BoundingBox ows:BoundingBox 60.0 12.0 70.0 20.0 ================================================ FILE: tests/functionaltests/suites/cite/post/19d2a6ed-be28-4866-ae15-e3bb634486cb.xml ================================================ brief dc:title Fuscé vitae ligulä dc:format DESC ================================================ FILE: tests/functionaltests/suites/cite/post/1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml ================================================ full csw:AnyText *lorem* ================================================ FILE: tests/functionaltests/suites/cite/post/1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml ================================================ summary ================================================ FILE: tests/functionaltests/suites/cite/post/1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml ================================================ brief /dc:title *lorem* ================================================ FILE: tests/functionaltests/suites/cite/post/2102a460-5d62-465f-9668-d70b3faafbfa.xml ================================================ brief dc:subject pHYSIOGRAPHy ================================================ FILE: tests/functionaltests/suites/cite/post/225f455a-0035-486b-a94e-fee7ae881b2b.xml ================================================ dc:identifier dc:type dc:date dc:date 2006-03-26 ================================================ FILE: tests/functionaltests/suites/cite/post/2d53ffea-60e4-4652-abf5-36eb23042fd5.xml ================================================ brief ================================================ FILE: tests/functionaltests/suites/cite/post/34a019a9-1581-42cb-9827-fbfdda2773b7.xml ================================================ brief ================================================ FILE: tests/functionaltests/suites/cite/post/3e76fd38-e035-41c9-83dc-61356f680c97.xml ================================================ csw:Record ================================================ FILE: tests/functionaltests/suites/cite/post/418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml ================================================ dc:identifier dc:date ows:BoundingBox ows:BoundingBox 47.0 -4.5 52.0 1.0 dc:date 2006-01-01 ================================================ FILE: tests/functionaltests/suites/cite/post/420b745e-0c4b-404e-9f2d-61fa580ff05a.xml ================================================ dc:identifier dc:type dc:date dc:date 2004-01-01 ================================================ FILE: tests/functionaltests/suites/cite/post/4735d649-a2b1-42fd-a101-14e1d7e4607f.xml ================================================ summary ================================================ FILE: tests/functionaltests/suites/cite/post/5c5861bc-f742-40a5-9998-5342615d674b.xml ================================================ full csw:AnyText *lorem* ================================================ FILE: tests/functionaltests/suites/cite/post/6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml ================================================ summary ================================================ FILE: tests/functionaltests/suites/cite/post/73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml ================================================ full dc:date 200?-10-* ================================================ FILE: tests/functionaltests/suites/cite/post/78297c88-4850-4927-adc6-511cd9a3d539.xml ================================================ ================================================ FILE: tests/functionaltests/suites/cite/post/7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml ================================================ summary ================================================ FILE: tests/functionaltests/suites/cite/post/7e2cd105-daec-4d25-bc8e-d49d21364912.xml ================================================ csw:DummyRecord ================================================ FILE: tests/functionaltests/suites/cite/post/87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml ================================================ dc:identifier dc:type dc:date ================================================ FILE: tests/functionaltests/suites/cite/post/88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml ================================================ csw:Record ================================================ FILE: tests/functionaltests/suites/cite/post/898cd63b-2585-4ec0-8720-d554bd324174.xml ================================================ summary dc:format image/* dc:relation urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc ================================================ FILE: tests/functionaltests/suites/cite/post/8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml ================================================ dc:identifier ows:BoundingBox ows:BoundingBox 60.0 12.0 70.0 20.0 ================================================ FILE: tests/functionaltests/suites/cite/post/928c1896-52d4-4ac7-9832-f98e3eb65f02.xml ================================================ dc:identifier dc:type dc:date dc:date 2005-10-24 ================================================ FILE: tests/functionaltests/suites/cite/post/93bdbb9d-2734-4f01-92fb-48634cca41de.xml ================================================ dc:identifier ows:BoundingBox /ows:BoundingBox 47.0 -4.5 52.0 1.0 ================================================ FILE: tests/functionaltests/suites/cite/post/948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml ================================================ dc:identifier dc:type dc:date dc:date DESC ================================================ FILE: tests/functionaltests/suites/cite/post/9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml ================================================ Record ================================================ FILE: tests/functionaltests/suites/cite/post/a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml ================================================ brief ================================================ FILE: tests/functionaltests/suites/cite/post/ad61686c-d304-42d1-b845-8c1f3070c83e.xml ================================================ brief dc:title Maecenas enim ================================================ FILE: tests/functionaltests/suites/cite/post/af39c020-7b1d-429c-b474-f45c3164cb79.xml ================================================ summary dc:title Lorem ipsum* ================================================ FILE: tests/functionaltests/suites/cite/post/b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml ================================================ summary dc:title Lorem ipsum* ================================================ FILE: tests/functionaltests/suites/cite/post/ba9b0107-dcee-46ef-823a-a2e25a911a96.xml ================================================ summary dc:format application/*xml dc:type http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/cite/post/bb66ebc5-7121-48b5-9f53-b56537d9561b.xml ================================================ dc:identifier dc:type ows:BoundingBox ows:BoundingBox 40.0 -9.0 50.0 -5.0 dc:type HTTP://purl.org/dc/dcmitype/dataset ================================================ FILE: tests/functionaltests/suites/cite/post/c02d1c85-df9f-45ee-bea7-345c35e02a98.xml ================================================ brief dc:title input.argument ================================================ FILE: tests/functionaltests/suites/cite/post/c311a342-72e3-4983-be39-868e6ed9740f.xml ================================================ csw:Record ================================================ FILE: tests/functionaltests/suites/cite/post/c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml ================================================ dc:identifier dc:date ows:BoundingBox ows:BoundingBox 47.0 -4.5 52.0 1.0 dc:date 2006-01-01 ================================================ FILE: tests/functionaltests/suites/cite/post/c8588f47-8e65-45f5-ad34-ff4524cad84d.xml ================================================ brief dct:spatial 47.0 -4.5 52.0 1.0 ================================================ FILE: tests/functionaltests/suites/cite/post/da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml ================================================ summary /dc:title *lorem* ================================================ FILE: tests/functionaltests/suites/cite/post/dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml ================================================ dc:identifier dc:type dc:date dc:date 2006-05-01 ================================================ FILE: tests/functionaltests/suites/cite/post/dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml ================================================ brief ================================================ FILE: tests/functionaltests/suites/cite/post/e308f030-c097-4036-a838-44bad74c9ef7.xml ================================================ brief ================================================ FILE: tests/functionaltests/suites/cite/post/e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml ================================================ brief dc:identifier ASC ================================================ FILE: tests/functionaltests/suites/cite/post/f7976c55-a156-4421-8199-bc0487da4b0f.xml ================================================ csw:Record ================================================ FILE: tests/functionaltests/suites/cite/post/f7d79701-f10b-4087-a33c-f62df0a04fd1.xml ================================================ brief ================================================ FILE: tests/functionaltests/suites/cite/post/fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml ================================================ brief dc:title Fuscé vitae ligulä ================================================ FILE: tests/functionaltests/suites/cite/post/fe20960f-a26c-4f13-852d-470a0d3233f9.xml ================================================ brief dc:subject pHYSIOGRAPHy ================================================ FILE: tests/functionaltests/suites/csw30/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Demo of gisdata GitHub repository url: https://demo.pycsw.org/gisdata/csw manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_002258f0-627f-457f-b2ad-025777c77ac8.xml ================================================ pycsw Geospatial pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery https://pycsw.org/img/favicon.ico Kralidis, Tom tomkralidis@gmail.com pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_045c600d-973d-41eb-9f60-eba1b717b720.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_0bbcf862-5211-4351-9988-63f8bec49c98.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_0bdf8457-971e-4ed1-be4a-5feca4dcd8fa.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_0d8bbdec-0846-42ca-8dc8-b7f4cba41d67.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_0e1dca37-477a-4060-99fe-7799b52d656c.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_13c87956-51a4-4780-a8e9-6e0b5c0bb473.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text Marine sediments application/xhtml+xml Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. 2006-05-12 urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image image/jp2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset Hydrography-Oceanographic 2005-10-24 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image image/jpeg ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_151d982f-ebd3-4cb2-b507-a667713a1e92.xml ================================================ Invalid acceptFormats parameter value: model/x3d+xml ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_1869e495-1a61-4713-8285-76d1336ee1a6.xml ================================================ Missing keyword: service ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6.xml ================================================ Missing id parameter ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_22f44168-2ccf-4801-ad96-204212566d56.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_2499a9c9-8d33-449c-bc92-d494adfcc84d.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_27f4f39c-d92a-4e3c-b961-c6aa8c24e513.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_28e569df-8596-4128-8d9a-29ad03138915.xml ================================================ urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image image/jpeg ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_2b06a5c8-0df2-4af1-8d2e-a425de11c845.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_2ba1418a-444d-4cce-9cfe-4c94efcf8b55.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. 2006-05-12 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image image/jpeg ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_405e1ff1-5c75-4846-a28b-cfaff2a6921a.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db Fuscé vitae ligulä http://purl.org/dc/dcmitype/Text Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_43cd6471-6ac7-45bd-8ff9-148cb2de9a52.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_4566d2ec-1283-4a02-baed-a74fc5b47e37.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_461bd4c5-6623-490d-9036-d91a2201e87b.xml ================================================ ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_5496894a-3877-4f62-a20b-5d7126f94925.xml ================================================ 4326 coordinates out of range: ['514432', '5429689', '529130', '5451619'] ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_5a015f6a-bf14-4977-b1e3-6577eb0223c8.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset Hydrography-Oceanographic 2005-10-24 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_5c3a2390-1fb9-43f0-b96c-f48c7a69c990.xml ================================================ Invalid outputformat parameter model/vnd.collada+xml ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_5e9e67dc-18d6-4645-8111-c6263c88a61f.xml ================================================ application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_604d9379-741c-42e5-b4cf-92e56c87fa64.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. 2006-05-12 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image image/jpeg ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_60e6af95-d5fc-465a-82e2-fd2e6d85e4af.xml ================================================ Invalid typeNames parameter value: UnknownType ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_62ad94c2-b558-4265-a427-23d6677975d6.xml ================================================ No records found for 'uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a' ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_6a5e247b-0961-4b8a-a0d6-35a491d9cfe7.xml ================================================ Invalid ElementSetName parameter value: undefined-view ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_6a9d0558-9d87-495b-b999-b49a3ef1cf99.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_6bd790c9-6019-4652-9c91-330a894d6700.xml ================================================ urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db Fuscé vitae ligulä http://purl.org/dc/dcmitype/Text Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. 2003-05-09 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_6e9cba43-5e27-415d-adbd-a92851c2c173.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_7630d230-e142-4a09-accf-f091000b90cd.xml ================================================ urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text Marine sediments application/xhtml+xml Pellentesque tempus magna non sapien fringilla blandit. ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_8025978e-1a35-4d70-80c2-e8329e0c7864.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_8184ae4f-536d-4978-8b28-ad703be96967.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_88f63a89-664f-4315-b4f8-04a0b33803a7.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_8987f8f0-4d93-4481-968c-a2ccbd6b8be2.xml ================================================ No repository item found for 'urn:example:1461546298217' ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_8e5fa0f6-3f29-4d1f-abe2-d9866f3def98.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_9000ec29-5649-474e-b2d6-55c00f8a52c0.xml ================================================ Invalid parameter value in acceptversions: 9999.12.31. Value MUST be 2.0.2 or 3.0.0 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_91914d35-7bbf-45e6-9b37-5ef484869a4e.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset Hydrography-Oceanographic 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_92d4844d-57d5-4cf3-8f47-ba50e369dc04.xml ================================================ ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3.xml ================================================ Invalid outputSchema parameter value: urn:uuid:6a29d2a8-9651-47a6-9b14-f05d2b5644f0 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_9d7ffac8-9798-428d-8e27-3cd12497ee6b.xml ================================================ Invalid outputschema parameter http://www.example.org/ns/alpha ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_Exception-GetDomain-value-reference.xml ================================================ dc:title2 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_Exception-GetDomain.xml ================================================ Missing value. One of valuereference or parametername must be specified ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_Exception-GetRecordById-404.xml ================================================ No repository item found for 'does_not_exist2' ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_Exception-GetRecordById-dc.xml.xml ================================================ urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image image/jp2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_Exception-GetRepositoryItem-notfound.xml ================================================ No repository item found for 'NOTFOUND' ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_Exception-invalid-request.xml ================================================ Invalid value for request: GetCapabilities-foo ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_GetCapabilities-base-url.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_GetCapabilities-no-version.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_GetDomain-parameter.xml ================================================ GetRecords.ElementSetName brief full summary ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_GetDomain-value-reference.xml ================================================ dc:title Aliquam fermentum purus quis arcu Fuscé vitae ligulä Lorem ipsum Lorem ipsum dolor sit amet Maecenas enim Mauris sed neque Ut facilisis justo ut lacus Vestibulum massa purus Ñunç elementum ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_GetRepositoryItem.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_OpenSearch-description.xml ================================================ pycsw Geospatial pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery https://pycsw.org/img/favicon.ico Kralidis, Tom tomkralidis@gmail.com pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_a2f18643-e24e-4fa5-b780-6de4a2dbc814.xml ================================================ urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus PYCSW_TIMESTAMP ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_abc90c8c-5868-4405-a73e-64c849be3b2a.xml ================================================ 4326 coordinates out of range: ['514432', '5429689', '529130', '5451619'] ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_ad0c0571-09ed-436a-9a4f-a5de744c88fe.xml ================================================ urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text Marine sediments application/xhtml+xml Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_af502903-f4ee-47ee-b76e-af878d238bcc.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset Hydrography-Oceanographic 2005-10-24 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_b2aafc3f-4f35-47bc-affd-08590972deae.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_b6069623-f7d8-4021-8582-98f0aea0f763.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_b9a07a54-75a8-45bd-b341-2823600211e3.xml ================================================ Invalid Filter query: Exception: document not valid. Error: Reprojection error: Invalid srsName ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_baa4a7d0-0c01-42b6-adc3-0d03e9949fa3.xml ================================================ Invalid value for request: getCapabilities ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_bfbe6409-f64a-4c89-acb3-50f260a5c743.xml ================================================ urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db Fuscé vitae ligulä http://purl.org/dc/dcmitype/Text Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_bfe20134-d1da-42ef-9c0f-8e1307bbf92b.xml ================================================ urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text Marine sediments application/xhtml+xml Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. 2006-05-12 urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image image/jp2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_c03d173a-3f42-4956-89c8-1fe02c3a0873.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_cb43d8c3-e14c-4a9f-9231-4384b7dd21f3.xml ================================================ Invalid ElementName parameter value: u ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_d03c6fd3-e821-4a26-b62f-d20a474e25af.xml ================================================ pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_d4ccbf96-a529-480e-a53d-5b88dc1dea7f.xml ================================================ No records found for 'uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a' ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_d94c801a-1207-4897-b84a-53f3a192515b.xml ================================================ ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_da859e34-91fc-495a-8c09-285a40c0900b.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_dc246fb8-5af5-4fda-82bb-c18b3ecd439c.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_de016645-6d5c-4855-943c-2db07ae9f49a.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_dff3ec6b-bb2d-4887-bd17-8fcf15def042.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text Marine sediments application/xhtml+xml Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus http://purl.org/dc/dcmitype/Image image/jp2 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset Hydrography-Oceanographic 44.79 -6.17 51.13 -2.23 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image image/jpeg ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_e67ca935-d65d-4d8c-8302-1405333dded0.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_e7704509-3441-458f-8ef0-e333c6b6043f.xml ================================================ Only ONE of ElementSetName or ElementName parameter(s) is permitted ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_f1223a49-6d08-44ff-97fe-4c32cbbfad82.xml ================================================ ================================================ FILE: tests/functionaltests/suites/csw30/expected/get_f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18.xml ================================================ Invalid outputFormat parameter value: text/example ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_Exception-GetDomain-parametername-bad.xml ================================================ GetRecords.outputFormat-something ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_Exception-GetDomain-valuereference-bad.xml ================================================ dc:titlena ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_Exception-GetRecordById-404.xml ================================================ No repository item found for 'does_not_exist' ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_Exception-GetRecordById-bad-esn.xml ================================================ Invalid elementsetname parameter bad ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_Exception-bad-xml.xml ================================================ Exception: document not well-formed. Error: Opening and ending tag mismatch: GetCapabilities line 2 and GetCapabilities-bad, line 9, column 29 (<string>, line 9). ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_Exception-not-xml.xml ================================================ Exception: document not well-formed. Error: Start tag expected, '<' not found, line 1, column 1 (<string>, line 1). ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact application/xml text/xml 2.0.2 3.0.0 All Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider GetCapabilities.acceptFormats GetCapabilities.acceptVersions GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.typeNames CQL_TEXT FILTER brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom csw30:Record csw:Record 10 http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities https://demo.pycsw.org/gisdata/csw brief full summary application/atom+xml application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox https://demo.pycsw.org/gisdata/csw 10 SOAP XML allowed TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE http://www.opengis.net/gml/3.2 TRUE en TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE xs:string xs:string xs:string xs:string xs:string xs:string ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_GetDomain-parametername.xml ================================================ GetRecords.outputFormat application/atom+xml application/json application/xml ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_GetDomain-valuereference.xml ================================================ dc:title Aliquam fermentum purus quis arcu Fuscé vitae ligulä Lorem ipsum Lorem ipsum dolor sit amet Maecenas enim Mauris sed neque Ut facilisis justo ut lacus Vestibulum massa purus Ñunç elementum ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_GetRecordById-dc-full.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_GetRecordById-dc.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/csw30/expected/post_GetRecords-anytext.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.59 -4.1 51.22 0.89 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image image/jpeg urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service Physiography urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam. ================================================ FILE: tests/functionaltests/suites/csw30/get/requests.txt ================================================ GetCapabilities-base-url,config=tests/suites/csw30/default.yml GetCapabilities-no-version,service=CSW&request=GetCapabilities GetCapabilities,service=CSW&version=3.0.0&request=GetCapabilities Exception-invalid-request,service=CSW&version=3.0.0&request=GetCapabilities-foo Exception-GetDomain,service=CSW&version=3.0.0&request=GetDomain GetDomain-parameter,service=CSW&version=3.0.0&request=GetDomain¶metername=GetRecords.ElementSetName GetDomain-value-reference,service=CSW&version=3.0.0&request=GetDomain&valuereference=dc:title Exception-GetDomain-value-reference,service=CSW&version=3.0.0&request=GetDomain&valuereference=dc:title2 Exception-GetRecordById-dc.xml,service=CSW&version=3.0.0&request=GetRecordById&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Exception-GetRecordById-404,service=CSW&version=3.0.0&request=GetRecordById&id=does_not_exist2 OpenSearch-description,mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities GetRepositoryItem,service=CSW&version=3.0.0&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Exception-GetRepositoryItem-notfound,service=CSW&version=3.0.0&request=GetRepositoryItem&id=NOTFOUND 002258f0-627f-457f-b2ad-025777c77ac8,mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities 045c600d-973d-41eb-9f60-eba1b717b720,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=Fusc%C3%A9%20Land&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids= 0bbcf862-5211-4351-9988-63f8bec49c98,elementSetName=summary&outputFormat=application/atom%2Bxml&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 0bdf8457-971e-4ed1-be4a-5feca4dcd8fa,config=tests/suites/csw30/default.yml 0d8bbdec-0846-42ca-8dc8-b7f4cba41d67,elementName=tns:title&request=GetRecords&service=CSW&typeNames=Record&namespace=xmlns(tns%3Dhttp://purl.org/dc/elements/1.1/)&version=3.0.0 0e1dca37-477a-4060-99fe-7799b52d656c,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=lpppclq&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids= 13c87956-51a4-4780-a8e9-6e0b5c0bb473,elementSetName=full&maxRecords=20&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 151d982f-ebd3-4cb2-b507-a667713a1e92,acceptFormats=model/x3d%2Bxml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW 1869e495-1a61-4713-8285-76d1336ee1a6,acceptVersions=3.0.0&request=GetCapabilities 1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6,request=GetRecordById&service=CSW&version=3.0.0 22f44168-2ccf-4801-ad96-204212566d56,config=tests/suites/csw30/default.yml 2499a9c9-8d33-449c-bc92-d494adfcc84d,acceptVersions=3.0.0§ions=All&request=GetCapabilities&service=CSW 27f4f39c-d92a-4e3c-b961-c6aa8c24e513,acceptFormats=application/xml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW 28e569df-8596-4128-8d9a-29ad03138915,id=urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2&request=GetRecordById&service=CSW&version=3.0.0 2b06a5c8-0df2-4af1-8d2e-a425de11c845,config=tests/suites/csw30/default.yml 2ba1418a-444d-4cce-9cfe-4c94efcf8b55,maxRecords=2&elementSetName=summary&outputFormat=application/atom%2Bxml&request=GetRecords&service=CSW&typeNames=csw3:Record&startPosition=3&namespace=xmlns(csw3%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0 397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a,service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=ipsum&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids= 3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4,elementSetName=brief&request=GetRecords&service=CSW&typeNames=tns:Record&namespace=xmlns(tns%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0 405e1ff1-5c75-4846-a28b-cfaff2a6921a,elementSetName=summary&recordIds=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f,urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 43cd6471-6ac7-45bd-8ff9-148cb2de9a52,config=tests/suites/csw30/default.yml 4566d2ec-1283-4a02-baed-a74fc5b47e37,acceptVersions=3.0.0§ions=ServiceIdentification&request=GetCapabilities&service=CSW 461bd4c5-6623-490d-9036-d91a2201e87b,acceptVersions=3.0.0§ions=Filter_Capabilities&request=GetCapabilities&service=CSW 5496894a-3877-4f62-a20b-5d7126f94925,service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=514432,5429689,529130,5451619&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids= 5a015f6a-bf14-4977-b1e3-6577eb0223c8,service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-6.17,44.79,17.92,68.41&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids= 5c3a2390-1fb9-43f0-b96c-f48c7a69c990,id=urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357&outputFormat=model/vnd.collada%2Bxml&request=GetRecordById&service=CSW&version=3.0.0 5e9e67dc-18d6-4645-8111-c6263c88a61f,acceptVersions=3.0.0§ions=OperationsMetadata&request=GetCapabilities&service=CSW 604d9379-741c-42e5-b4cf-92e56c87fa64,elementSetName=full&q=amet&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 60e6af95-d5fc-465a-82e2-fd2e6d85e4af,request=GetRecords&service=CSW&typeNames=UnknownType&version=3.0.0 62ad94c2-b558-4265-a427-23d6677975d6,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids=uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a 6a5e247b-0961-4b8a-a0d6-35a491d9cfe7,elementSetName=undefined-view&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 6a9d0558-9d87-495b-b999-b49a3ef1cf99,config=tests/suites/csw30/default.yml 6bd790c9-6019-4652-9c91-330a894d6700,service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=Fusc%C3%A9%20Land&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids= 6e9cba43-5e27-415d-adbd-a92851c2c173,acceptVersions=3.0.0&request=GetCapabilities&service=CSW 7630d230-e142-4a09-accf-f091000b90cd,id=urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493&request=GetRecordById&service=CSW&version=3.0.0 7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf,acceptFormats=text/xml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW 8025978e-1a35-4d70-80c2-e8329e0c7864,config=tests/suites/csw30/default.yml 8184ae4f-536d-4978-8b28-ad703be96967,elementSetName=brief&bbox=44.79,-6.17,68.41,17.92,urn:ogc:def:crs:EPSG::4326&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 88f63a89-664f-4315-b4f8-04a0b33803a7,maxRecords=15&elementSetName=summary&q=Mauris&bbox=-6.17,44.79,17.92,68.41&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 8987f8f0-4d93-4481-968c-a2ccbd6b8be2,id=urn:example:1461546298217&request=GetRecordById&service=CSW&version=3.0.0 8e5fa0f6-3f29-4d1f-abe2-d9866f3def98,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-180,-90,180,90&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids= 9000ec29-5649-474e-b2d6-55c00f8a52c0,acceptVersions=9999.12.31&request=GetCapabilities&service=CSW 91914d35-7bbf-45e6-9b37-5ef484869a4e,elementSetName=summary&bbox=-6.17,44.79,17.92,68.41&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 92d4844d-57d5-4cf3-8f47-ba50e369dc04,elementSetName=full&q=atkovxqmf&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3,elementSetName=brief&outputSchema=urn:uuid:6a29d2a8-9651-47a6-9b14-f05d2b5644f0&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 9d7ffac8-9798-428d-8e27-3cd12497ee6b,id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd&outputSchema=http://www.example.org/ns/alpha&request=GetRecordById&service=CSW&version=3.0.0 a2f18643-e24e-4fa5-b780-6de4a2dbc814,id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e&outputFormat=application/atom%2Bxml&request=GetRecordById&service=CSW&version=3.0.0 abc90c8c-5868-4405-a73e-64c849be3b2a,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=514432,5429689,529130,5451619&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids= ad0c0571-09ed-436a-9a4f-a5de744c88fe,maxRecords=2&elementSetName=summary&request=GetRecords&service=CSW&typeNames=csw3:Record&startPosition=3&namespace=xmlns(csw3%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0 af502903-f4ee-47ee-b76e-af878d238bcc,service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-180,-90,180,90&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids= b2aafc3f-4f35-47bc-affd-08590972deae,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-6.17,44.79,17.92,68.41&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids= b6069623-f7d8-4021-8582-98f0aea0f763,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=3&maxrecords=4&recordids= b9a07a54-75a8-45bd-b341-2823600211e3,elementSetName=brief&bbox=472944,5363287,492722,5455253,urn:ogc:def:crs:EPSG::0000&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 baa4a7d0-0c01-42b6-adc3-0d03e9949fa3,acceptVersions=3.0.0&request=getCapabilities&service=CSW bfbe6409-f64a-4c89-acb3-50f260a5c743,elementSetName=summary&q=Fusc%C3%A9%20Land&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 bfe20134-d1da-42ef-9c0f-8e1307bbf92b,service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=3&maxrecords=4&recordids= c03d173a-3f42-4956-89c8-1fe02c3a0873,SERVICE=CSW&Request=GetCapabilities&acceptversions=3.0.0 cb43d8c3-e14c-4a9f-9231-4384b7dd21f3,elementName=undefined&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 d03c6fd3-e821-4a26-b62f-d20a474e25af,acceptVersions=3.0.0§ions=ServiceProvider&request=GetCapabilities&service=CSW d4ccbf96-a529-480e-a53d-5b88dc1dea7f,service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a d94c801a-1207-4897-b84a-53f3a192515b,service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=lpppclq&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids= da859e34-91fc-495a-8c09-285a40c0900b,id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63&elementSetName=full&request=GetRecordById&service=CSW&version=3.0.0 dc246fb8-5af5-4fda-82bb-c18b3ecd439c,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=ipsum&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids= de016645-6d5c-4855-943c-2db07ae9f49a,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids=urn%3Auuid%3A94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 dff3ec6b-bb2d-4887-bd17-8fcf15def042,elementSetName=summary&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b,id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd&elementSetName=brief&request=GetRecordById&service=CSW&version=3.0.0 e67ca935-d65d-4d8c-8302-1405333dded0,config=tests/suites/csw30/default.yml e7704509-3441-458f-8ef0-e333c6b6043f,elementName=ns1:subject&elementSetName=brief&request=GetRecords&service=CSW&typeNames=Record&namespace=xmlns(ns1%3Dhttp://purl.org/dc/elements/1.1/)&version=3.0.0 f1223a49-6d08-44ff-97fe-4c32cbbfad82,elementSetName=summary&maxRecords=0&q=titles&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18,elementSetName=full&outputFormat=text/example&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0 ================================================ FILE: tests/functionaltests/suites/csw30/post/Exception-GetDomain-parametername-bad.xml ================================================ GetRecords.outputFormat-something ================================================ FILE: tests/functionaltests/suites/csw30/post/Exception-GetDomain-valuereference-bad.xml ================================================ dc:titlena ================================================ FILE: tests/functionaltests/suites/csw30/post/Exception-GetRecordById-404.xml ================================================ does_not_exist ================================================ FILE: tests/functionaltests/suites/csw30/post/Exception-GetRecordById-bad-esn.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f bad ================================================ FILE: tests/functionaltests/suites/csw30/post/Exception-bad-xml.xml ================================================ 3.0.0 application/xml ================================================ FILE: tests/functionaltests/suites/csw30/post/Exception-not-xml.xml ================================================ not an XML payload ================================================ FILE: tests/functionaltests/suites/csw30/post/GetCapabilities.xml ================================================ 3.0.0 application/xml ================================================ FILE: tests/functionaltests/suites/csw30/post/GetDomain-parametername.xml ================================================ GetRecords.outputFormat ================================================ FILE: tests/functionaltests/suites/csw30/post/GetDomain-valuereference.xml ================================================ dc:title ================================================ FILE: tests/functionaltests/suites/csw30/post/GetRecordById-dc-full.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f full ================================================ FILE: tests/functionaltests/suites/csw30/post/GetRecordById-dc.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f ================================================ FILE: tests/functionaltests/suites/csw30/post/GetRecords-anytext.xml ================================================ full csw:AnyText %lorem% ================================================ FILE: tests/functionaltests/suites/default/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/default/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Demo of gisdata GitHub repository url: https://demo.pycsw.org/gisdata/csw manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/default/expected/get_Exception-GetRepositoryItem-notfound.xml ================================================ No repository item found for '['NOTFOUND']' ================================================ FILE: tests/functionaltests/suites/default/expected/get_Exception-GetRepositoryItem-service-invalid1.xml ================================================ 'Invalid value for service: CSW\x00. Value MUST be CSW' ================================================ FILE: tests/functionaltests/suites/default/expected/get_Exception-GetRepositoryItem-service-invalid2.xml ================================================ "Invalid value for service: CSW\x00'. Value MUST be CSW" ================================================ FILE: tests/functionaltests/suites/default/expected/get_Exception-GetRepositoryItem-version-invalid.xml ================================================ Invalid value for version: 2.0.2'. Value MUST be 2.0.2 or 3.0.0 ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetCapabilities-invalid-request.xml ================================================ Invalid value for request: GetCapabilitiese ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://demo.pycsw.org/gisdata/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-all.xml ================================================ ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-empty-maxrecords.xml ================================================ ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-filter-cql-title-or-abstract-with-spaces.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-filter-cql-title-or-abstract.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-filter-cql-title-with-spaces-or-abstract-with-spaces.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-filter-cql-title-with-spaces-or-abstract.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-filter-cql-title-with-spaces.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-filter-cql-title.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-filter.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-sortby-asc.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.042 13.754 68.410 17.920 urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms FI-ES Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service Physiography Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam. urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text Fuscé vitae ligulä 2003-05-09 Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-sortby-desc.xml ================================================ urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 2005-10-24 44.792 -6.171 51.126 -2.228 urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e http://purl.org/dc/dcmitype/Image image/jp2 Vestibulum massa purus urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text Fuscé vitae ligulä 2003-05-09 Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service Physiography Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam. urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-sortby-invalid-order.xml ================================================ Invalid SortBy value: sort order must be "A" or "D" ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRecords-sortby-invalid-propertyname.xml ================================================ Invalid SortBy propertyname: dc:titlei ================================================ FILE: tests/functionaltests/suites/default/expected/get_GetRepositoryItem.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 ================================================ FILE: tests/functionaltests/suites/default/expected/post_DescribeRecord-json.xml ================================================ { "csw:DescribeRecordResponse": { "@xsi:schemaLocation": "http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd", "@xmlns": { "csw": "http://www.opengis.net/cat/csw/2.0.2", "dc": "http://purl.org/dc/elements/1.1/", "dct": "http://purl.org/dc/terms/", "gmd": "http://www.isotc211.org/2005/gmd", "gml": "http://www.opengis.net/gml", "gml32": "http://www.opengis.net/gml/3.2", "ows": "http://www.opengis.net/ows", "xs": "http://www.w3.org/2001/XMLSchema", "xsi": "http://www.w3.org/2001/XMLSchema-instance" }, "csw:SchemaComponent": { "@schemaLanguage": "XMLSCHEMA", "@targetNamespace": "http://www.opengis.net/cat/csw/2.0.2", "xs:schema": { "@id": "csw-record", "@targetNamespace": "http://www.opengis.net/cat/csw/2.0.2", "@elementFormDefault": "qualified", "@version": "2.0.2 2010-01-22", "xs:annotation": { "xs:appinfo": { "dc:identifier": "http://schemas.opengis.net/csw/2.0.2/record.xsd" }, "xs:documentation": { "@http://www.w3.org/XML/1998/namespace:lang": "en", "#text": "This schema defines the basic record types that must be supported\n by all CSW implementations. These correspond to full, summary, and\n brief views based on DCMI metadata terms.\n \n CSW is an OGC Standard.\n Copyright (c) 2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved.\n To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ ." } }, "xs:import": [ { "@namespace": "http://purl.org/dc/terms/", "@schemaLocation": "rec-dcterms.xsd" }, { "@namespace": "http://purl.org/dc/elements/1.1/", "@schemaLocation": "rec-dcmes.xsd" }, { "@namespace": "http://www.opengis.net/ows", "@schemaLocation": "../../ows/1.0.0/owsAll.xsd" } ], "xs:element": [ { "@name": "AbstractRecord", "@id": "AbstractRecord", "@type": "csw:AbstractRecordType", "@abstract": "true" }, { "@name": "DCMIRecord", "@type": "csw:DCMIRecordType", "@substitutionGroup": "csw:AbstractRecord" }, { "@name": "BriefRecord", "@type": "csw:BriefRecordType", "@substitutionGroup": "csw:AbstractRecord" }, { "@name": "SummaryRecord", "@type": "csw:SummaryRecordType", "@substitutionGroup": "csw:AbstractRecord" }, { "@name": "Record", "@type": "csw:RecordType", "@substitutionGroup": "csw:AbstractRecord" } ], "xs:complexType": [ { "@name": "AbstractRecordType", "@id": "AbstractRecordType", "@abstract": "true" }, { "@name": "DCMIRecordType", "xs:annotation": { "xs:documentation": { "@http://www.w3.org/XML/1998/namespace:lang": "en", "#text": "This type encapsulates all of the standard DCMI metadata terms,\n including the Dublin Core refinements; these terms may be mapped\n to the profile-specific information model." } }, "xs:complexContent": { "xs:extension": { "@base": "csw:AbstractRecordType", "xs:sequence": { "xs:group": { "@ref": "dct:DCMI-terms" } } } } }, { "@name": "BriefRecordType", "@final": "#all", "xs:annotation": { "xs:documentation": { "@http://www.w3.org/XML/1998/namespace:lang": "en", "#text": "This type defines a brief representation of the common record\n format. It extends AbstractRecordType to include only the\n dc:identifier and dc:type properties." } }, "xs:complexContent": { "xs:extension": { "@base": "csw:AbstractRecordType", "xs:sequence": { "xs:element": [ { "@ref": "dc:identifier", "@minOccurs": "1", "@maxOccurs": "unbounded" }, { "@ref": "dc:title", "@minOccurs": "1", "@maxOccurs": "unbounded" }, { "@ref": "dc:type", "@minOccurs": "0" }, { "@ref": "ows:BoundingBox", "@minOccurs": "0", "@maxOccurs": "unbounded" } ] } } } }, { "@name": "SummaryRecordType", "@final": "#all", "xs:annotation": { "xs:documentation": { "@http://www.w3.org/XML/1998/namespace:lang": "en", "#text": "This type defines a summary representation of the common record\n format. It extends AbstractRecordType to include the core\n properties." } }, "xs:complexContent": { "xs:extension": { "@base": "csw:AbstractRecordType", "xs:sequence": { "xs:element": [ { "@ref": "dc:identifier", "@minOccurs": "1", "@maxOccurs": "unbounded" }, { "@ref": "dc:title", "@minOccurs": "1", "@maxOccurs": "unbounded" }, { "@ref": "dc:type", "@minOccurs": "0" }, { "@ref": "dc:subject", "@minOccurs": "0", "@maxOccurs": "unbounded" }, { "@ref": "dc:format", "@minOccurs": "0", "@maxOccurs": "unbounded" }, { "@ref": "dc:relation", "@minOccurs": "0", "@maxOccurs": "unbounded" }, { "@ref": "dct:modified", "@minOccurs": "0", "@maxOccurs": "unbounded" }, { "@ref": "dct:abstract", "@minOccurs": "0", "@maxOccurs": "unbounded" }, { "@ref": "dct:spatial", "@minOccurs": "0", "@maxOccurs": "unbounded" }, { "@ref": "ows:BoundingBox", "@minOccurs": "0", "@maxOccurs": "unbounded" } ] } } } }, { "@name": "RecordType", "@final": "#all", "xs:annotation": { "xs:documentation": { "@http://www.w3.org/XML/1998/namespace:lang": "en", "#text": "This type extends DCMIRecordType to add ows:BoundingBox;\n it may be used to specify a spatial envelope for the\n catalogued resource." } }, "xs:complexContent": { "xs:extension": { "@base": "csw:DCMIRecordType", "xs:sequence": { "xs:element": [ { "@name": "AnyText", "@type": "csw:EmptyType", "@minOccurs": "0", "@maxOccurs": "unbounded" }, { "@ref": "ows:BoundingBox", "@minOccurs": "0", "@maxOccurs": "unbounded" } ] } } } }, { "@name": "EmptyType" } ] } } } } ================================================ FILE: tests/functionaltests/suites/default/expected/post_DescribeRecord.xml ================================================ http://schemas.opengis.net/csw/2.0.2/record.xsd This schema defines the basic record types that must be supported by all CSW implementations. These correspond to full, summary, and brief views based on DCMI metadata terms. CSW is an OGC Standard. Copyright (c) 2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved. To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ . This type encapsulates all of the standard DCMI metadata terms, including the Dublin Core refinements; these terms may be mapped to the profile-specific information model. This type defines a brief representation of the common record format. It extends AbstractRecordType to include only the dc:identifier and dc:type properties. This type defines a summary representation of the common record format. It extends AbstractRecordType to include the core properties. This type extends DCMIRecordType to add ows:BoundingBox; it may be used to specify a spatial envelope for the catalogued resource. ================================================ FILE: tests/functionaltests/suites/default/expected/post_Exception-GetRecords-badsrsname.xml ================================================ Invalid Constraint: Invalid Filter request: Reprojection error: Invalid srsName ================================================ FILE: tests/functionaltests/suites/default/expected/post_Exception-GetRecords-elementname.xml ================================================ Invalid ElementName parameter value: dc:foo ================================================ FILE: tests/functionaltests/suites/default/expected/post_Exception-GetRecords-invalid-xml.xml ================================================ Exception: the document is not valid. Error: Element '{http://www.opengis.net/cat/csw/2.0.2}ElementNamefoo': This element is not expected. Expected is one of ( {http://www.opengis.net/cat/csw/2.0.2}ElementSetName, {http://www.opengis.net/cat/csw/2.0.2}ElementName ). (<string>, line 0) ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetCapabilities-SOAP.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://demo.pycsw.org/gisdata/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetCapabilities-sections.xml ================================================ pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetCapabilities-updatesequence.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://demo.pycsw.org/gisdata/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://demo.pycsw.org/gisdata/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetDomain-parameter.xml ================================================ GetRecords.CONSTRAINTLANGUAGE CQL_TEXT FILTER ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetDomain-property.xml ================================================ dc:title Aliquam fermentum purus quis arcu Fuscé vitae ligulä Lorem ipsum Lorem ipsum dolor sit amet Maecenas enim Mauris sed neque Ut facilisis justo ut lacus Vestibulum massa purus Ñunç elementum ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecordById-json.xml ================================================ { "csw:GetRecordByIdResponse": { "@xsi:schemaLocation": "http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd", "@xmlns": { "csw": "http://www.opengis.net/cat/csw/2.0.2", "dc": "http://purl.org/dc/elements/1.1/", "dct": "http://purl.org/dc/terms/", "gmd": "http://www.isotc211.org/2005/gmd", "gml": "http://www.opengis.net/gml", "gml32": "http://www.opengis.net/gml/3.2", "ows": "http://www.opengis.net/ows", "xs": "http://www.w3.org/2001/XMLSchema", "xsi": "http://www.w3.org/2001/XMLSchema-instance" }, "csw:SummaryRecord": { "dc:identifier": "urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63", "dc:title": "Mauris sed neque", "dc:type": "http://purl.org/dc/dcmitype/Dataset", "dc:subject": "Vegetation-Cropland", "dct:abstract": "Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.", "ows:BoundingBox": { "@crs": "urn:x-ogc:def:crs:EPSG:6.11:4326", "@dimensions": "2", "ows:LowerCorner": "47.59 -4.1", "ows:UpperCorner": "51.22 0.89" } } } } ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecordById.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-all-json.xml ================================================ { "csw:GetRecordsResponse": { "@version": "2.0.2", "@xsi:schemaLocation": "http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd", "@xmlns": { "csw": "http://www.opengis.net/cat/csw/2.0.2", "dc": "http://purl.org/dc/elements/1.1/", "dct": "http://purl.org/dc/terms/", "gmd": "http://www.isotc211.org/2005/gmd", "gml": "http://www.opengis.net/gml", "gml32": "http://www.opengis.net/gml/3.2", "ows": "http://www.opengis.net/ows", "xs": "http://www.w3.org/2001/XMLSchema", "xsi": "http://www.w3.org/2001/XMLSchema-instance" }, "csw:SearchStatus": { "@timestamp": "PYCSW_TIMESTAMP" }, "csw:SearchResults": { "@numberOfRecordsMatched": "12", "@numberOfRecordsReturned": "5", "@nextRecord": "6", "@recordSchema": "http://www.opengis.net/cat/csw/2.0.2", "@elementSet": "full", "csw:Record": [ { "dc:identifier": "urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f", "dc:type": "http://purl.org/dc/dcmitype/Image", "dc:format": "image/svg+xml", "dc:title": "Lorem ipsum", "dct:spatial": "GR-22", "dc:subject": "Tourism--Greece", "dct:abstract": "Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu." }, { "dc:identifier": "urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd", "dc:type": "http://purl.org/dc/dcmitype/Service", "dct:abstract": "Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.", "ows:BoundingBox": { "@crs": "urn:x-ogc:def:crs:EPSG:6.11:4326", "ows:LowerCorner": "60.042 13.754", "ows:UpperCorner": "68.410 17.920" } }, { "dc:identifier": "urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493", "dc:title": "Maecenas enim", "dc:type": "http://purl.org/dc/dcmitype/Text", "dc:format": "application/xhtml+xml", "dc:subject": "Marine sediments", "dct:abstract": "Pellentesque tempus magna non sapien fringilla blandit." }, { "dc:identifier": "urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4", "dc:type": "http://purl.org/dc/dcmitype/Service", "dc:title": "Ut facilisis justo ut lacus", "dc:subject": { "@scheme": "http://www.digest.org/2.1", "#text": "Vegetation" }, "dc:relation": "urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63" }, { "dc:identifier": "urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec", "dc:title": "Aliquam fermentum purus quis arcu", "dc:type": "http://purl.org/dc/dcmitype/Text", "dc:subject": "Hydrography--Dictionaries", "dc:format": "application/pdf", "dc:date": "2006-05-12", "dct:abstract": "Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi." } ] } } } ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-all-resulttype-hits.xml ================================================ ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-all-resulttype-validate.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-all-sortby-bbox.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.042 13.754 68.410 17.920 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 2005-10-24 44.792 -6.171 51.126 -2.228 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-all.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.042 13.754 68.410 17.920 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-bbox-filter-crs84.xml ================================================ urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-cql-title-and-abstract.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-cql-title.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-distributedsearch.xml ================================================ urn:uuid:dcc8e03e-932a-11ea-ad6f-823cf448c401 Aquifers vector digital data 32.55 -117.6 33.51 -116.08 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-elementname.xml ================================================ Lorem ipsum Maecenas enim Ut facilisis justo ut lacus Aliquam fermentum purus quis arcu ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-end.xml ================================================ urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service Physiography Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam. urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text Fuscé vitae ligulä 2003-05-09 Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-and-bbox-freetext.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-and-nested-or-multiple.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-and-nested-or.xml ================================================ urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-and-nested-or2.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-anytext-and-not.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-anytext-equal.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-anytext.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-bbox-poslist.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-bbox-reproject.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-bbox-sortby.xml ================================================ urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-bbox.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-between.xml ================================================ urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text Fuscé vitae ligulä 2003-05-09 Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-function-bad.xml ================================================ Invalid Constraint: Invalid Filter request: Invalid ogc:Function: foo ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-function.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-invalid-poslist.xml ================================================ Invalid Constraint: Invalid Filter request: Invalid number of coordinates in geometry ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-not-bbox.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service 60.04 13.75 68.41 17.92 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus http://purl.org/dc/dcmitype/Service urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-or-bbox-freetext.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset 47.59 -4.1 51.22 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum http://purl.org/dc/dcmitype/Dataset 44.79 -6.17 51.13 -2.23 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-or-nested-and.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e http://purl.org/dc/dcmitype/Image image/jp2 Vestibulum massa purus urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms FI-ES Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 2005-10-24 44.792 -6.171 51.126 -2.228 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-filter-or-title-abstract.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-maxrecords.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/default/expected/post_GetRecords-requestid.xml ================================================ ce74a6c8-677a-42b3-a07c-ce44df8ce7ab urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.042 13.754 68.410 17.920 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. ================================================ FILE: tests/functionaltests/suites/default/expected/post_Harvest-default.xml ================================================ Harvest operations are not supported ================================================ FILE: tests/functionaltests/suites/default/expected/post_Harvest-response-handler.xml ================================================ Harvest operations are not supported ================================================ FILE: tests/functionaltests/suites/default/expected/post_Transaction-delete.xml ================================================ Invalid Constraint: Invalid Filter request: Invalid PropertyName: apiso:Identifier. 'apiso:Identifier' ================================================ FILE: tests/functionaltests/suites/default/expected/post_Transaction-insert.xml ================================================ Transaction operations are not supported ================================================ FILE: tests/functionaltests/suites/default/expected/post_Transaction-update-full.xml ================================================ Transaction operations are not supported ================================================ FILE: tests/functionaltests/suites/default/expected/post_Transaction-update-recordproperty.xml ================================================ Transaction operations are not supported ================================================ FILE: tests/functionaltests/suites/default/get/requests.txt ================================================ GetCapabilities,service=CSW&version=2.0.2&request=GetCapabilities GetCapabilities-invalid-request,service=CSW&version=2.0.2&request=GetCapabilitiese GetRecords-all,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full GetRecords-sortby-asc,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:A GetRecords-sortby-desc,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:D GetRecords-sortby-invalid-propertyname,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:titlei:A GetRecords-sortby-invalid-order,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:FOO GetRecords-filter,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=FILTER&constraint=%3Cogc%3AFilter%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%3E%3Cogc%3APropertyIsEqualTo%3E%3Cogc%3APropertyName%3Edc%3Atitle%3C%2Fogc%3APropertyName%3E%3Cogc%3ALiteral%3ELorem%20ipsum%3C%2Fogc%3ALiteral%3E%3C%2Fogc%3APropertyIsEqualTo%3E%3C%2Fogc%3AFilter%3E GetRecords-filter-cql-title,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27 GetRecords-filter-cql-title-with-spaces,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25Lorem%20ipsum%25%27 GetRecords-filter-cql-title-or-abstract,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%25%27 GetRecords-filter-cql-title-with-spaces-or-abstract,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25dolor%20sit%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%25%27 GetRecords-filter-cql-title-or-abstract-with-spaces,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%20in%25%27 GetRecords-filter-cql-title-with-spaces-or-abstract-with-spaces,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25dolor%20sit%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%20in%25%27 GetRecords-empty-maxrecords,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&maxrecords= GetRepositoryItem,service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Exception-GetRepositoryItem-notfound,service=CSW&version=2.0.2&request=GetRepositoryItem&id=NOTFOUND Exception-GetRepositoryItem-service-invalid1,service=CSW%00&version=2.0.2&request=GetRepositoryItem&id=123 Exception-GetRepositoryItem-service-invalid2,service=CSW%00'&version=2.0.2&request=GetRepositoryItem&id=123 Exception-GetRepositoryItem-version-invalid,service=CSW&version=2.0.2'&request=GetRepositoryItem&id=123 ================================================ FILE: tests/functionaltests/suites/default/post/DescribeRecord-json.xml ================================================ csw:Record ================================================ FILE: tests/functionaltests/suites/default/post/DescribeRecord.xml ================================================ csw:Record ================================================ FILE: tests/functionaltests/suites/default/post/Exception-GetRecords-badsrsname.xml ================================================ brief ows:BoundingBox -90 -180 90 180 ================================================ FILE: tests/functionaltests/suites/default/post/Exception-GetRecords-elementname.xml ================================================ dc:foo ================================================ FILE: tests/functionaltests/suites/default/post/Exception-GetRecords-invalid-xml.xml ================================================ dc:foo ================================================ FILE: tests/functionaltests/suites/default/post/GetCapabilities-SOAP.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/default/post/GetCapabilities-sections.xml ================================================ 2.0.2 ServiceProvider application/xml ================================================ FILE: tests/functionaltests/suites/default/post/GetCapabilities-updatesequence.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/default/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/default/post/GetDomain-parameter.xml ================================================ GetRecords.CONSTRAINTLANGUAGE ================================================ FILE: tests/functionaltests/suites/default/post/GetDomain-property.xml ================================================ dc:title ================================================ FILE: tests/functionaltests/suites/default/post/GetRecordById-json.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 summary ================================================ FILE: tests/functionaltests/suites/default/post/GetRecordById.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 summary ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-all-json.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-all-resulttype-hits.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-all-resulttype-validate.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-all-sortby-bbox.xml ================================================ full ows:BoundingBox DESC ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-all.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-bbox-filter-crs84.xml ================================================ brief ows:BoundingBox -180 -90 180 90 ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-cql-title-and-abstract.xml ================================================ brief dc:title like '%ips%' and dct:abstract like '%pharetra%' ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-cql-title.xml ================================================ brief dc:title like '%ips%' ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-distributedsearch.xml ================================================ brief dc:title Aquifers ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-elementname.xml ================================================ dc:title ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-end.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-and-bbox-freetext.xml ================================================ brief csw:AnyText %lor% ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-and-nested-or-multiple.xml ================================================ full dc:type http://purl.org/dc/dcmitype/Image dc:type http://purl.org/dc/dcmitype/Dataset dc:title Mauris% dc:title %neque ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-and-nested-or.xml ================================================ full dc:title Aliquam fermentum purus quis arcu dc:format application/pdf dc:type http://purl.org/dc/dcmitype/Dataset dc:type http://purl.org/dc/dcmitype/Service dc:type http://purl.org/dc/dcmitype/Image dc:type http://purl.org/dc/dcmitype/Text ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-and-nested-or2.xml ================================================ full dc:title Lorem% dc:type http://purl.org/dc/dcmitype/Dataset dc:type http://purl.org/dc/dcmitype/Service dc:type http://purl.org/dc/dcmitype/Image dc:type http://purl.org/dc/dcmitype/Text ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-anytext-and-not.xml ================================================ summary csw:AnyText *lorem* csw:AnyText *ipsum* csw:AnyText *dolor* ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-anytext-equal.xml ================================================ brief csw:AnyText Lor ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-anytext.xml ================================================ brief csw:AnyText %Lor% ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-bbox-poslist.xml ================================================ brief ows:BoundingBox 47.00 -5.00 55.00 -5.00 55.00 20.00 47.00 20.00 47.00 -5.00 ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-bbox-reproject.xml ================================================ brief ows:BoundingBox -72310.84768270838 2013215.2698528299 279667.74290441966 2690819.5081175645 ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-bbox-sortby.xml ================================================ brief ows:BoundingBox 47 -5 55 20 dc:title DESC ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-bbox.xml ================================================ brief ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-between.xml ================================================ full dc:title Aliquam fermentum purus quis arcu Maecenas enim ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-function-bad.xml ================================================ brief dc:title LOREM IPSUM ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-function.xml ================================================ brief dc:title LOREM IPSUM ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-invalid-poslist.xml ================================================ full ows:BoundingBox 11 16 49 17 10 10 ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-not-bbox.xml ================================================ brief ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-or-bbox-freetext.xml ================================================ brief dc:title foo ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-or-nested-and.xml ================================================ full dc:type http://purl.org/dc/dcmitype/Image dc:type http://purl.org/dc/dcmitype/Dataset dc:title Mauris% dc:title %neque ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-filter-or-title-abstract.xml ================================================ full dc:title Mauris% dct:abstract foo ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-maxrecords.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/default/post/GetRecords-requestid.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/default/post/Harvest-default.xml ================================================ http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/examples-ISO19139/dataset2_minimalst.xml http://www.isotc211.org/schemas/2005/gmd/ application/xml ================================================ FILE: tests/functionaltests/suites/default/post/Harvest-response-handler.xml ================================================ http://kralidis.ca/pycsw/trunk/tests/test_iso.xml http://www.isotc211.org/schemas/2005/gmd/ application/xml mailto:tkralidi ================================================ FILE: tests/functionaltests/suites/default/post/Transaction-delete.xml ================================================ apiso:Identifier 12345 ================================================ FILE: tests/functionaltests/suites/default/post/Transaction-insert.xml ================================================ 12345 pycsw 2011-05-17 pycsw record 2011-05-17 Sample metadata record eng -180 180 -90 90 ================================================ FILE: tests/functionaltests/suites/default/post/Transaction-update-full.xml ================================================ 12345 pycsw 2011-05-17 pycsw record 2011-05-17 Sample metadata record eng -180 180 -90 90 ================================================ FILE: tests/functionaltests/suites/default/post/Transaction-update-recordproperty.xml ================================================ apiso:Title NEW_TITLE apiso:Identifier 12345 ================================================ FILE: tests/functionaltests/suites/dif/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/dif/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/dif/expected/post_DescribeRecord.xml ================================================ ================================================ FILE: tests/functionaltests/suites/dif/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/dif/expected/post_GetRecords-filter-bbox.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque Vegetation-Cropland 47.59 51.22 -4.1 0.89 Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. CEOS IDN DIF 9.7 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum Hydrography-Oceanographic 44.79 51.13 -6.17 -2.23 CEOS IDN DIF 9.7 ================================================ FILE: tests/functionaltests/suites/dif/post/DescribeRecord.xml ================================================ dif:DIF ================================================ FILE: tests/functionaltests/suites/dif/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/dif/post/GetRecords-filter-bbox.xml ================================================ brief ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/duplicatefileid/data/isos/tds.maracoos.org/iso/AVHRR.2011.7Agg.xml ================================================ org.maracoos:avhrr.sst eng UTF8 dataset service Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact 2017-10-27 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 4500 0.011113580795732384 row 3661 0.008743169398907104 temporal 1 0.0 area AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) org.maracoos AVHRR.2011.7Agg Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact MARACOOS AVHRR SST UDEL Satellite SST Rutgers EARTH SCIENCE > OCEANS > OCEAN TEMPERATURE > SEA SURFACE TEMPERATURE theme MARACOOS DMAC dataCenter sea_surface_temperature longitude latitude time theme http://www.cgd.ucar.edu/cms/eaton/cf-metadata/standard_name.html Freely Distributed Unidata Common Data Model Grid largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 -100.0 -50.0 20.0 52.0 seconds 2011-08-26T23:37:00Z 2011-08-26T23:37:00Z AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. OPeNDAP:OPeNDAP 1 -100.0 -50.0 20.0 52.0 2011-08-26T23:37:00Z 2011-08-26T23:37:00Z tight OPeNDAP Client Access http://tds.maracoos.org/thredds/dodsC/AVHRR/2011/7Agg OPeNDAP:OPeNDAP OPeNDAP THREDDS OPeNDAP download mcsst float Multichannel Sea Surface Temperature (sea_surface_temperature) grid_topology int lon double Longitude (longitude) lat double Latitude (latitude) time int Time (time) MARACOOS DMAC maracoosinfo@udel.edu http://maracoos.org WWW:LINK web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://tds.maracoos.org/thredds/dodsC/AVHRR/2011/7Agg.html WWW:LINK File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://www.ncdc.noaa.gov/oa/wct/wct-jnlp-beta.php?singlefile=http://tds.maracoos.org/thredds/dodsC/AVHRR/2011/7Agg WWW:LINK Viewer Information This URL provides an NCDC climate and weather toolkit view of an OPeNDAP resource. mapDigital This record was translated from NcML using UnidataDD2MI.xsl Version 2.3.4. (2017-10-27T16:24:57.169-04:00) ================================================ FILE: tests/functionaltests/suites/duplicatefileid/data/isos/tds.maracoos.org/iso/AVHRR.2012.7Agg.xml ================================================ org.maracoos:avhrr.sst eng UTF8 dataset service Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact 2017-10-27 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 4500 0.011113580795732384 row 3661 0.008743169398907104 temporal 1 0.0 area AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) org.maracoos AVHRR.2012.7Agg Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact MARACOOS AVHRR SST UDEL Satellite SST Rutgers EARTH SCIENCE > OCEANS > OCEAN TEMPERATURE > SEA SURFACE TEMPERATURE theme MARACOOS DMAC dataCenter sea_surface_temperature longitude latitude time theme http://www.cgd.ucar.edu/cms/eaton/cf-metadata/standard_name.html Freely Distributed Unidata Common Data Model Grid largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 -100.0 -50.0 20.0 52.0 seconds 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. OPeNDAP:OPeNDAP 1 -100.0 -50.0 20.0 52.0 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z tight OPeNDAP Client Access http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg OPeNDAP:OPeNDAP OPeNDAP THREDDS OPeNDAP download mcsst float Multichannel Sea Surface Temperature (sea_surface_temperature) grid_topology int lon double Longitude (longitude) lat double Latitude (latitude) time int Time (time) MARACOOS DMAC maracoosinfo@udel.edu http://maracoos.org WWW:LINK web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg.html WWW:LINK File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://www.ncdc.noaa.gov/oa/wct/wct-jnlp-beta.php?singlefile=http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg WWW:LINK Viewer Information This URL provides an NCDC climate and weather toolkit view of an OPeNDAP resource. mapDigital This record was translated from NcML using UnidataDD2MI.xsl Version 2.3.4. (2017-10-27T16:24:57.008-04:00) ================================================ FILE: tests/functionaltests/suites/duplicatefileid/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/duplicatefileid/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log #federatedcatalogues: # - id: fedcat01 # type: CSW # title: Arctic SDI # url: https://catalogue.arctic-sdi.org/csw # - id: fedcat02 # type: OARec # title: pycsw OGC CITE demo and Reference Implementation # url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/duplicatefileid/expected/get_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/duplicatefileid/expected/post_GetRecords-all.xml ================================================ org.maracoos:avhrr.sst AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) dataset 20.0 -100.0 52.0 -50.0 ================================================ FILE: tests/functionaltests/suites/duplicatefileid/get/requests.txt ================================================ GetCapabilities,service=CSW&version=2.0.2&request=GetCapabilities ================================================ FILE: tests/functionaltests/suites/duplicatefileid/post/GetRecords-all.xml ================================================ brief ================================================ FILE: tests/functionaltests/suites/ebrim/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/ebrim/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true profiles: - ebrim logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/ebrim/expected/post_DescribeRecord.xml ================================================ rim:Value not allowed in this context: expected wrs:AnyValue. Schema for CSW-ebRIM catalogue profile (OGC 07-110r3). A general record identifier, expressed as an absolute URI that maps to the rim:RegistryObject/@id attribute. It substitutes for the ogc:_Id element in an OGC filter expression. Extends rim:ExtrinsicObjectType to add the following: 1. MTOM/XOP based attachment support. 2. XLink based reference to a part in a multipart/related message structure. NOTE: This content model is planned for RegRep 4.0. Allows complex slot values. Incorporates the attributes defined for use in simple XLink elements. ================================================ FILE: tests/functionaltests/suites/ebrim/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record rim:RegistryObject DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0 hits results validate csw:Record rim:RegistryObject csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0 CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/ebrim/expected/post_GetRecords-filter-bbox-full.xml ================================================ 47.59 -4.1 51.22 0.89 Vegetation-Cropland 44.79 -6.17 51.13 -2.23 Hydrography-Oceanographic ================================================ FILE: tests/functionaltests/suites/ebrim/expected/post_GetRecords-filter-bbox.xml ================================================ ================================================ FILE: tests/functionaltests/suites/ebrim/post/DescribeRecord.xml ================================================ rim:RegistryObject ================================================ FILE: tests/functionaltests/suites/ebrim/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/ebrim/post/GetRecords-filter-bbox-full.xml ================================================ full ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/ebrim/post/GetRecords-filter-bbox.xml ================================================ brief ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/fgdc/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/fgdc/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/fgdc/expected/post_DescribeRecord.xml ================================================ ================================================ FILE: tests/functionaltests/suites/fgdc/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/fgdc/expected/post_GetRecords-filter-bbox.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. -4.1 0.89 51.22 47.59 http://purl.org/dc/dcmitype/Dataset urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc Ñunç elementum Hydrography-Oceanographic -6.17 -2.23 51.13 44.79 http://purl.org/dc/dcmitype/Dataset ================================================ FILE: tests/functionaltests/suites/fgdc/post/DescribeRecord.xml ================================================ fgdc:metadata ================================================ FILE: tests/functionaltests/suites/fgdc/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/fgdc/post/GetRecords-filter-bbox.xml ================================================ brief ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/gm03/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/gm03/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/gm03/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/gm03/expected/post_GetRecords-filter-bbox.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 GM03 2.3 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. Vegetation-Cropland 51.22 47.59 -4.1 0.89 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc GM03 2.3 http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 51.13 44.79 -6.17 -2.23 ================================================ FILE: tests/functionaltests/suites/gm03/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/gm03/post/GetRecords-filter-bbox.xml ================================================ brief ows:BoundingBox 47 -5 55 20 ================================================ FILE: tests/functionaltests/suites/harvesting/data/.gitignore ================================================ # This file exists to force git to include this directory in the code # repository. # # git does not include empty directories in code repositories. # # Functional tests are automatically generated by py.test. The way that the # tests are set up, the presence of a ``data/`` directory inside a test suite # has the following meaning: # # * if a ``data/`` directory does not exist, the tests of the suite use data # from the CITE suite; # # * if an empty ``data/`` directory exists, then a new empty database is # created and used; # # * if the ``data/`` directory exists and has files inside, a new database is # created and the files are loaded into the database as records. # # As such, the current suite needs an empty ``data/`` directory because its # functional tests depend on the existence of an empty database. # ignore all files in this directory (in case some file is put here by mistake, # we do not want it to be sent to the git repository and mess up the functional # tests) * # however, be sure to not ignore this file, as we need at least one file inside # this directory, so that git will aknowledge its existence !.gitignore ================================================ FILE: tests/functionaltests/suites/harvesting/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/harvesting/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true profiles: - apiso logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: true allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/harvesting/data/records.db table: records ================================================ FILE: tests/functionaltests/suites/harvesting/expected/get_Exception-Harvest-invalid-resourcetype.xml ================================================ Invalid resource type parameter: http://www.opengis.net/wms1234. Allowable resourcetype values: http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/,http://www.interlis.ch/INTERLIS2.3,http://www.isotc211.org/2005/gmd,http://www.isotc211.org/2005/gmi,http://www.isotc211.org/schemas/2005/gmd/,http://www.opengis.net/cat/csw/2.0.2,http://www.opengis.net/cat/csw/3.0,http://www.opengis.net/cat/csw/csdgm,http://www.opengis.net/sos/1.0,http://www.opengis.net/sos/2.0,http://www.opengis.net/wcs,http://www.opengis.net/wfs,http://www.opengis.net/wfs/2.0,http://www.opengis.net/wms,http://www.opengis.net/wmts/1.0,http://www.opengis.net/wps/1.0.0,http://www.w3.org/2005/Atom,urn:geoss:waf ================================================ FILE: tests/functionaltests/suites/harvesting/expected/get_Exception-Harvest-missing-resourcetype.xml ================================================ Missing resourcetype parameter ================================================ FILE: tests/functionaltests/suites/harvesting/expected/get_Exception-Harvest-missing-source.xml ================================================ Missing source parameter ================================================ FILE: tests/functionaltests/suites/harvesting/expected/get_Exception-Harvest-waf-bad-value.xml ================================================ Harvest failed: record parsing failed: unknown url type: badvalue ================================================ FILE: tests/functionaltests/suites/harvesting/expected/get_Exception-Harvest-waf-no-records-found.xml ================================================ 0 0 0 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Clear-000-delete-all.xml ================================================ 0 0 0 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Exception-Havest-csw-404.xml ================================================ Harvest failed: record parsing failed: HTTP error: HTTP Error 404: Not Found ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record gmd:MD_Metadata DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record gmd:MD_Metadata apiso:AccessConstraints apiso:Classification apiso:ConditionApplyingToAccessAndUse apiso:Contributor apiso:Creator apiso:Degree apiso:IlluminationElevationAngle apiso:Lineage apiso:OtherConstraints apiso:Publisher apiso:Relation apiso:ResponsiblePartyRole apiso:SpecificationDate apiso:SpecificationDateType apiso:SpecificationTitle csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox apiso:Abstract apiso:AlternateTitle apiso:AnyText apiso:BoundingBox apiso:CRS apiso:CouplingType apiso:CreationDate apiso:Denominator apiso:DistanceUOM apiso:DistanceValue apiso:Format apiso:GeographicDescriptionCode apiso:HasSecurityConstraints apiso:Identifier apiso:KeywordType apiso:Language apiso:Modified apiso:OperatesOn apiso:OperatesOnIdentifier apiso:OperatesOnName apiso:Operation apiso:OrganisationName apiso:ParentIdentifier apiso:PublicationDate apiso:ResourceLanguage apiso:RevisionDate apiso:ServiceType apiso:ServiceTypeVersion apiso:Subject apiso:TempExtent_begin apiso:TempExtent_end apiso:Title apiso:TopicCategory apiso:Type brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.isotc211.org/2005/gmi http://www.isotc211.org/schemas/2005/gmd/ http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_GetDomain-parameter.xml ================================================ Harvest.ResourceType http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.isotc211.org/2005/gmi http://www.isotc211.org/schemas/2005/gmd/ http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-csw-iso.xml ================================================ 34 0 0 PYCSW_IDENTIFIER pycsw Geospatial Catalogue OGC services demo PYCSW_IDENTIFIER 1 Million Scale WMS Layers from the National Atlas of the United States PYCSW_IDENTIFIER-ports1m 1 Million Scale - Ports PYCSW_IDENTIFIER-national1m 1 Million Scale - National Boundary PYCSW_IDENTIFIER-elevation 1 Million Scale - Elevation 100 Meter Resolution PYCSW_IDENTIFIER-impervious 1 Million Scale - Impervious Surface 100 Meter Resolution PYCSW_IDENTIFIER-coast1m 1 Million Scale - Coastlines PYCSW_IDENTIFIER-cdl 1 Million Scale - 113th Congressional Districts PYCSW_IDENTIFIER-states1m 1 Million Scale - States PYCSW_IDENTIFIER-elsli0100g 1 Million Scale - Color-Sliced Elevation 100 Meter Resolution PYCSW_IDENTIFIER-landcov100m 1 Million Scale - Land Cover 100 Meter Resolution PYCSW_IDENTIFIER-cdp 1 Million Scale - 113th Congressional Districts by Party PYCSW_IDENTIFIER-amtrak1m 1 Million Scale - Railroad and Bus Passenger Stations PYCSW_IDENTIFIER-airports1m 1 Million Scale - Airports PYCSW_IDENTIFIER-one_million 1 Million Scale WMS Layers from the National Atlas of the United States PYCSW_IDENTIFIER-satvi0100g 1 Million Scale - Satellite View 100 Meter Resolution PYCSW_IDENTIFIER-srcoi0100g 1 Million Scale - Color Shaded Relief 100 Meter Resolution PYCSW_IDENTIFIER-srgri0100g 1 Million Scale - Gray Shaded Relief 100 Meter Resolution PYCSW_IDENTIFIER-treecanopy 1 Million Scale - Tree Canopy 100 Meter Resolution PYCSW_IDENTIFIER-svsri0100g 1 Million Scale - Satellite View with Shaded Relief 100 Meter Resolution PYCSW_IDENTIFIER Wisconsin Lake Clarity PYCSW_IDENTIFIER-Highways Highways PYCSW_IDENTIFIER-LakesTSI LakesTSI PYCSW_IDENTIFIER-LakeClarity Wisconsin Lake Clarity PYCSW_IDENTIFIER-LakesTSI_0305 LakesTSI_0305 PYCSW_IDENTIFIER-Relief Relief PYCSW_IDENTIFIER-LakeNames_0305 LakeNames_0305 PYCSW_IDENTIFIER-Roads Roads PYCSW_IDENTIFIER-LakeNames LakeNames PYCSW_IDENTIFIER-Counties Counties PYCSW_IDENTIFIER View & download service for EU-DEM data provided by EOX PYCSW_IDENTIFIER-EU-DEM EU-DEM PYCSW_IDENTIFIER-MS View & download service for EU-DEM data provided by EOX PYCSW_IDENTIFIER-eudem_color EU-DEM color shaded ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-csw-run1.xml ================================================ 13 0 0 PYCSW_IDENTIFIER pycsw OGC CITE demo and Reference Implementation PYCSW_IDENTIFIER Lorem ipsum PYCSW_IDENTIFIER PYCSW_IDENTIFIER Maecenas enim PYCSW_IDENTIFIER Ut facilisis justo ut lacus PYCSW_IDENTIFIER Aliquam fermentum purus quis arcu PYCSW_IDENTIFIER Vestibulum massa purus PYCSW_IDENTIFIER PYCSW_IDENTIFIER Mauris sed neque PYCSW_IDENTIFIER Ñunç elementum PYCSW_IDENTIFIER Lorem ipsum dolor sit amet PYCSW_IDENTIFIER PYCSW_IDENTIFIER Fuscé vitae ligulä ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-csw-run2.xml ================================================ 13 13 0 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-dc.xml ================================================ 1 0 0 PYCSW_IDENTIFIER Image2000 Product 1 (at1) Multispectral ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-fgdc.xml ================================================ 1 0 0 PYCSW_IDENTIFIER CPC Merged Analysis of Precipitation Standard [POL 88.75 -88.75 180 -180] ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-iso.xml ================================================ 1 0 0 PYCSW_IDENTIFIER Wasserkörper Linien ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-rdf.xml ================================================ 1 0 0 PYCSW_IDENTIFIER Website_gdb ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-sos100.xml ================================================ 30 0 0 PYCSW_IDENTIFIER Northeastern Regional Association of Coastal Ocean Observing Systems PYCSW_IDENTIFIER-CML Mooring CML data from the COOA (UNH-COOA) located UNH Coastal Marine Lab Field Station PYCSW_IDENTIFIER-F01 Mooring F01 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located Penobscot Bay PYCSW_IDENTIFIER-F02 Mooring F02 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located DeepCwind Castine Test Site PYCSW_IDENTIFIER-SMB-MO-04 Mooring SMB-MO-04 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (SmartBay) located Pilot Boarding Station, Red Island Shoal, Placentia Bay, NL, CA PYCSW_IDENTIFIER-LDLC3 Mooring LDLC3 data from the LISICOS (LISICOS) located New London Ledge Light PYCSW_IDENTIFIER-CDIP154 Mooring CDIP154 data from the COOA (UNH-COOA-CDIP) located Block Island, RI PYCSW_IDENTIFIER-CDIP176 Mooring CDIP176 data from the COOA (UNH-COOA-CDIP) located Halifax Harbor, CA PYCSW_IDENTIFIER-ARTG Mooring ARTG data from the LISICOS (LISICOS) located North of Smithtown Bay PYCSW_IDENTIFIER-M01 Mooring M01 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located Jordan Basin PYCSW_IDENTIFIER-N01 Mooring N01 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located Northeast Channel PYCSW_IDENTIFIER-44039 Mooring 44039 data from the LISICOS (LISICOS) located Central Long Island Sound PYCSW_IDENTIFIER-SMB-MO-01 Mooring SMB-MO-01 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (SmartBay) located Mouth of Placentia Bay, NL, Canada PYCSW_IDENTIFIER-SMB-MO-05 Mooring SMB-MO-05 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (SmartBay) located Come By Chance Point, Placentia Bay, NL, CA PYCSW_IDENTIFIER-D02 Mooring D02 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located Lower Harpswell Sound PYCSW_IDENTIFIER-E02 Mooring E02 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located DeepCwind Test Site PYCSW_IDENTIFIER-E01 Mooring E01 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located Central Maine Shelf PYCSW_IDENTIFIER-B01 Mooring B01 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located Western Maine Shelf PYCSW_IDENTIFIER-EXRX Mooring EXRX data from the LISICOS (LISICOS) located Execution Rocks Long Island Sound PYCSW_IDENTIFIER-44098 Mooring 44098 data from the COOA (UNH-COOA) located Jeffrey's Ledge PYCSW_IDENTIFIER-WLIS Mooring WLIS data from the LISICOS (LISICOS) located Western Long Island Sound PYCSW_IDENTIFIER-CO2 Mooring CO2 data from the COOA (UNH-COOA) located Appledore Island PYCSW_IDENTIFIER-CDIP221 Mooring CDIP221 data from the COOA (UNH-COOA-CDIP) located Cape Cod Bay, MA PYCSW_IDENTIFIER-ALL_PLATFORMS Mooring data for all buoys from the Northeastern Regional Association of Coastal Ocean Observing Systems (NERACOOS) located in the NERACOOS Region PYCSW_IDENTIFIER-A01 Mooring A01 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located Massachusetts Bay PYCSW_IDENTIFIER-MDS02 Mooring MDS02 data from the URI (Univ. of Rhode Is.) located SAMP MD S PYCSW_IDENTIFIER-GREAT_BAY Mooring GREAT_BAY data from the COOA (UNH-COOA) located Great Bay, NH PYCSW_IDENTIFIER-I01 Mooring I01 data from the Northeastern Regional Association of Coastal Ocean Observing Systems (Univ. of Maine) located Eastern Maine Shelf PYCSW_IDENTIFIER-CDIP207 Mooring CDIP207 data from the COOA (UNH-COOA-CDIP) located Fire Island, NY PYCSW_IDENTIFIER-44060 Mooring 44060 data from the LISICOS (LISICOS) located Eastern Long Island Sound ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-sos200.xml ================================================ 2 0 0 PYCSW_IDENTIFIER GIN SOS PYCSW_IDENTIFIER-GW_LEVEL ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-waf.xml ================================================ 3 0 0 PYCSW_IDENTIFIER CPC Merged Analysis of Precipitation Standard [POL 88.75 -88.75 180 -180] PYCSW_IDENTIFIER Image2000 Product 1 (at1) Multispectral PYCSW_IDENTIFIER NOAA_RNC ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-wcs.xml ================================================ 5 0 0 PYCSW_IDENTIFIER WCS Demo Server for MapServer PYCSW_IDENTIFIER-ndvi North Central US MODIS-based NDVI Images for 2002 PYCSW_IDENTIFIER-modis-001 North Central US MODIS Images for 2002-001 PYCSW_IDENTIFIER-fpar North Central US MODIS-based FPAR Images for 2002 PYCSW_IDENTIFIER-modis North Central US MODIS Images for 2002 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-wfs110.xml ================================================ 6 0 0 PYCSW_IDENTIFIER GeoServer Web Feature Service PYCSW_IDENTIFIER-geoss_water_sba:Reservoir Reservoir PYCSW_IDENTIFIER-geoss_water_sba:glwd_1 glwd_1 PYCSW_IDENTIFIER-geoss_water_sba:Dams Dams PYCSW_IDENTIFIER-geoss_water_sba:glwd_2 glwd_2 PYCSW_IDENTIFIER-geoss_water_sba:Lakes Lakes ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-wfs200.xml ================================================ 11 0 0 PYCSW_IDENTIFIER CERA_CERA_TechClasses_WGS84 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-08-16 MBIE_Technical_Classes_WGS84_2012-08-16 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-05-18 MBIE_Technical_Classes_WGS84_2012-05-18 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2013-12-04 MBIE_Technical_Classes_WGS84_2013-12-04 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2011-10-28 MBIE_Technical_Classes_WGS84_2011-10-28 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-02-10 MBIE_Technical_Classes_WGS84_2012-02-10 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-09-14 MBIE_Technical_Classes_WGS84_2012-09-14 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-03-23 MBIE_Technical_Classes_WGS84_2012-03-23 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2011-11-17 MBIE_Technical_Classes_WGS84_2011-11-17 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-08-24 MBIE_Technical_Classes_WGS84_2012-08-24 PYCSW_IDENTIFIER-CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-10-31 MBIE_Technical_Classes_WGS84_2012-10-31 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-wms-run1.xml ================================================ 4 0 0 PYCSW_IDENTIFIER IEM WMS Service PYCSW_IDENTIFIER-nexrad_base_reflect IEM WMS Service PYCSW_IDENTIFIER-time_idx NEXRAD BASE REFLECT PYCSW_IDENTIFIER-nexrad-n0r-wmst NEXRAD BASE REFLECT ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-wms-run2.xml ================================================ 4 4 0 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-wmts.xml ================================================ 8 0 0 PYCSW_IDENTIFIER Web Map Tile Service PYCSW_IDENTIFIER-flwbplmzk Flächenwidmungs- und Bebauungsplan PYCSW_IDENTIFIER-lb Luftbild PYCSW_IDENTIFIER-lb2014 Luftbild 2014 PYCSW_IDENTIFIER-beschriftung Beschriftung PYCSW_IDENTIFIER-lb1938 Luftbild 1938 PYCSW_IDENTIFIER-fmzk MZK Flächen PYCSW_IDENTIFIER-lb1956 Luftbild 1956 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-wps.xml ================================================ 11 0 0 PYCSW_IDENTIFIER Geo Data Portal WPS Implementation PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.filemanagement.CreateNewShapefileDataStore gov.usgs.cida.gdp.wps.algorithm.filemanagement.CreateNewShapefileDataStore PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.discovery.GetGridTimeRange Get Grid Time Range PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.filemanagement.ReceiveFiles gov.usgs.cida.gdp.wps.algorithm.filemanagement.ReceiveFiles PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.discovery.GetWcsCoverages gov.usgs.cida.gdp.wps.algorithm.discovery.GetWcsCoverages PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.filemanagement.GetWatersGeom gov.usgs.cida.gdp.wps.algorithm.filemanagement.GetWatersGeom PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.communication.GeoserverManagementAlgorithm gov.usgs.cida.gdp.wps.algorithm.communication.GeoserverManagementAlgorithm PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.communication.EmailWhenFinishedAlgorithm gov.usgs.cida.gdp.wps.algorithm.communication.EmailWhenFinishedAlgorithm PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.discovery.InterrogateDataset Interogate Dataset URI PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.discovery.ListOpendapGrids List OpendDAP Grids PYCSW_IDENTIFIER-gov.usgs.cida.gdp.wps.algorithm.discovery.CalculateWCSCoverageInfo gov.usgs.cida.gdp.wps.algorithm.discovery.CalculateWCSCoverageInfo ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-zzz-post-GetRecords-filter-ows-dc.xml ================================================ PYCSW_IDENTIFIER pycsw Geospatial Catalogue OGC services demo service catalogue discovery metadata services CSW http://demo.pycsw.org/services/csw pycsw is an OARec and OGC CSW server implementation written in Python Lastname, Firstname Organization Name Lastname, Firstname http://demo.pycsw.org/services/csw None PYCSW_IDENTIFIER pycsw OGC CITE demo and Reference Implementation service ogc cite compliance interoperability reference implementation CSW http://demo.pycsw.org/cite/csw pycsw is an OARec and OGC CSW server implementation written in Python. pycsw fully implements the OpenGIS Catalogue Service Implementation Specification (Catalogue Service for the Web). Initial development started in 2010 (more formally announced in 2011). The project is certified OGC Compliant, and is an OGC Reference Implementation. Since 2015, pycsw is an official OSGeo Project. pycsw allows for the publishing and discovery of [[geospatial]] metadata via numerous APIs (CSW 2/CSW 3, OpenSearch, OAI-PMH, SRU). Existing repositories of geospatial metadata can also be exposed, providing a standards-based metadata and catalogue component of spatial data infrastructures. pycsw is Open Source, released under an MIT license, and runs on all major platforms (Windows, Linux, Mac OS X) Lastname, Firstname Organization Name Lastname, Firstname http://demo.pycsw.org/cite/csw None PYCSW_IDENTIFIER Northeastern Regional Association of Coastal Ocean Observing Systems service NERACOOS SOS OCEANOGRAPHY Ocean Observations Gulf of Maine Long Island Sound Narragansett Bay Cape Cod Boston Harbor Buzzards Bay Weather Ocean Currents Water Temperature Salinity Winds Waves Ocean Color GoMOOS LISICOS Univ. of New Hampshire MVCO Air Temperature OGC:SOS http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi NERACOOS supports data collected from buoys in the Gulf of Maine and Long Island Sound. The six Gulf of Maine buoys carry a comprehensive sensor suite that includes the full complement of meteorological sensors carried by the standard NDBC buoys, and in addition commonly include atmospheric visibility, surface currents, water-column current profiles, temperature and conductivity, and fluorescence (for chlorophyll a estimation) and backscatter at multiple depths. In Long Island Sound, three buoys that measure wind speed and direction, circulation, salinity, temperature and dissolved oxygen. Two buoys will be located in western LIS (WLIS and EXRK stations) and the third will be in the Central Sound (CLIS). The buoys will be equipped with three YSI-SeaBird sensors to measure conductivity, temperature, pressure and dissolved oxygen concentration near the surface, bottom and mid-depth. A buoy in Great Bay measures physical, optical, meteorological and wave data. Eric Bridger NERACOOS Eric Bridger http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi NONE urn:ogc:def:crs:EPSG:6.11:4326 40.58 -73.73 47.79 -54.05 PYCSW_IDENTIFIER GIN SOS service groundwater level monitoring timeseries Alberta Ontario Nova Scotia OGC:SOS http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw Historical groundwater level monitoring stations from Alberta, Ontario and Nova Scotia. This SOS web service delivers the data using OGC's WaterML 2.0. The SOS service federates data from various provincial sources and publishes them as a single service. Many monitoring stations also have water well characteristics available through the GIN WFS web service. Boyan Brodaric Geological Survey of Canada, Earth Sciences Sector, Natural Resources Canada, Government of Canada Boyan Brodaric http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw NONE urn:ogc:def:crs:EPSG:6.11:4326 41.0 -120.0 60.0 -60.0 PYCSW_IDENTIFIER WCS Demo Server for MapServer service WCS MODIS NDVI OGC:WCS http://demo.mapserver.org/cgi-bin/wcs Steve Lime Minnesota DNR Steve Lime http://demo.mapserver.org/cgi-bin/wcs NONE urn:ogc:def:crs:EPSG:6.11:4326 41.03 -97.71 49.67 -80.68 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml ================================================ PYCSW_IDENTIFIER GIN SOS service groundwater level monitoring timeseries Alberta Ontario Nova Scotia OGC:SOS http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw Historical groundwater level monitoring stations from Alberta, Ontario and Nova Scotia. This SOS web service delivers the data using OGC's WaterML 2.0. The SOS service federates data from various provincial sources and publishes them as a single service. Many monitoring stations also have water well characteristics available through the GIN WFS web service. Boyan Brodaric Geological Survey of Canada, Earth Sciences Sector, Natural Resources Canada, Government of Canada Boyan Brodaric http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw NONE urn:ogc:def:crs:EPSG:6.11:4326 41.0 -120.0 60.0 -60.0 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-zzz-post-GetRecords-filter-sos-dc.xml ================================================ PYCSW_IDENTIFIER Northeastern Regional Association of Coastal Ocean Observing Systems service NERACOOS SOS OCEANOGRAPHY Ocean Observations Gulf of Maine Long Island Sound Narragansett Bay Cape Cod Boston Harbor Buzzards Bay Weather Ocean Currents Water Temperature Salinity Winds Waves Ocean Color GoMOOS LISICOS Univ. of New Hampshire MVCO Air Temperature OGC:SOS http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi NERACOOS supports data collected from buoys in the Gulf of Maine and Long Island Sound. The six Gulf of Maine buoys carry a comprehensive sensor suite that includes the full complement of meteorological sensors carried by the standard NDBC buoys, and in addition commonly include atmospheric visibility, surface currents, water-column current profiles, temperature and conductivity, and fluorescence (for chlorophyll a estimation) and backscatter at multiple depths. In Long Island Sound, three buoys that measure wind speed and direction, circulation, salinity, temperature and dissolved oxygen. Two buoys will be located in western LIS (WLIS and EXRK stations) and the third will be in the Central Sound (CLIS). The buoys will be equipped with three YSI-SeaBird sensors to measure conductivity, temperature, pressure and dissolved oxygen concentration near the surface, bottom and mid-depth. A buoy in Great Bay measures physical, optical, meteorological and wave data. Eric Bridger NERACOOS Eric Bridger http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi NONE urn:ogc:def:crs:EPSG:6.11:4326 40.58 -73.73 47.79 -54.05 PYCSW_IDENTIFIER GIN SOS service groundwater level monitoring timeseries Alberta Ontario Nova Scotia OGC:SOS http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw Historical groundwater level monitoring stations from Alberta, Ontario and Nova Scotia. This SOS web service delivers the data using OGC's WaterML 2.0. The SOS service federates data from various provincial sources and publishes them as a single service. Many monitoring stations also have water well characteristics available through the GIN WFS web service. Boyan Brodaric Geological Survey of Canada, Earth Sciences Sector, Natural Resources Canada, Government of Canada Boyan Brodaric http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw NONE urn:ogc:def:crs:EPSG:6.11:4326 41.0 -120.0 60.0 -60.0 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-zzz-post-GetRecords-filter-sos-iso.xml ================================================ PYCSW_IDENTIFIER service Eric Bridger NERACOOS DMAC Coordinator 207 228-1662 350 Commercial St. Portland ME 04101 US ebridger@gmri.org http://www.neracoos.org/ pointOfContact ISO19119 2005/PDAM 1 Northeastern Regional Association of Coastal Ocean Observing Systems NERACOOS supports data collected from buoys in the Gulf of Maine and Long Island Sound. The six Gulf of Maine buoys carry a comprehensive sensor suite that includes the full complement of meteorological sensors carried by the standard NDBC buoys, and in addition commonly include atmospheric visibility, surface currents, water-column current profiles, temperature and conductivity, and fluorescence (for chlorophyll a estimation) and backscatter at multiple depths. In Long Island Sound, three buoys that measure wind speed and direction, circulation, salinity, temperature and dissolved oxygen. Two buoys will be located in western LIS (WLIS and EXRK stations) and the third will be in the Central Sound (CLIS). The buoys will be equipped with three YSI-SeaBird sensors to measure conductivity, temperature, pressure and dissolved oxygen concentration near the surface, bottom and mid-depth. A buoy in Great Bay measures physical, optical, meteorological and wave data. NERACOOS SOS OCEANOGRAPHY Ocean Observations Gulf of Maine Long Island Sound Narragansett Bay Cape Cod Boston Harbor Buzzards Bay Weather Ocean Currents Water Temperature Salinity Winds Waves Ocean Color GoMOOS LISICOS Univ. of New Hampshire MVCO Air Temperature OGC:SOS 1.0.0 NERACOOS SOS OCEANOGRAPHY Ocean Observations Gulf of Maine Long Island Sound Narragansett Bay Cape Cod Boston Harbor Buzzards Bay Weather Ocean Currents Water Temperature Salinity Winds Waves Ocean Color GoMOOS LISICOS Univ. of New Hampshire MVCO Air Temperature -73.73 -54.05 40.58 47.79 tight GetObservation CML GetObservation F01 GetObservation F02 GetObservation SMB-MO-04 GetObservation LDLC3 GetObservation CDIP154 GetObservation CDIP176 GetObservation ARTG GetObservation M01 GetObservation N01 GetObservation 44039 GetObservation SMB-MO-01 GetObservation SMB-MO-05 GetObservation D02 GetObservation E02 GetObservation E01 GetObservation B01 GetObservation EXRX GetObservation 44098 GetObservation WLIS GetObservation CO2 GetObservation CDIP221 GetObservation ALL_PLATFORMS GetObservation A01 GetObservation MDS02 GetObservation GREAT_BAY GetObservation I01 GetObservation CDIP207 GetObservation 44060 GetCapabilities HTTPGet HTTPPost http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi GetObservation HTTPGet HTTPPost http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi DescribeSensor HTTPGet HTTPPost http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi OGC:SOS PYCSW_IDENTIFIER OGC-SOS Sensor Observation Service PYCSW_IDENTIFIER service Boyan Brodaric Geological Survey of Canada, Earth Sciences Sector, Natural Resources Canada, Government of Canada Research Scientist +1-613-992-3562 +1-613-995-9273 615 Booth Street Ottawa K1A 0E9 Canada brodaric at nrcan dot gc dot ca http://gw-info.net pointOfContact ISO19119 2005/PDAM 1 GIN SOS Historical groundwater level monitoring stations from Alberta, Ontario and Nova Scotia. This SOS web service delivers the data using OGC's WaterML 2.0. The SOS service federates data from various provincial sources and publishes them as a single service. Many monitoring stations also have water well characteristics available through the GIN WFS web service. groundwater level monitoring timeseries Alberta Ontario Nova Scotia OGC:SOS 2.0.0 groundwater level monitoring timeseries Alberta Ontario Nova Scotia -120.0 -60.0 41.0 60.0 tight GetObservation GW_LEVEL GetCapabilities HTTPGet HTTPPost http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw DescribeSensor HTTPGet HTTPPost http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw GetObservation HTTPGet HTTPPost http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw GetFeatureOfInterest HTTPGet HTTPPost http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw OGC:SOS PYCSW_IDENTIFIER OGC-SOS Sensor Observation Service ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-zzz-post-GetRecords-filter-wfs-iso.xml ================================================ PYCSW_IDENTIFIER service Matt Austin National Oceanic and Atmospheric Administration Silver Spring Maryland 20910 USA pointOfContact ISO19119 2005/PDAM 1 GeoServer Web Feature Service This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction. WFS WMS GEOSERVER OGC:WFS 1.1.0 WFS WMS GEOSERVER -179.87 179.99 -54.61 83.46 tight GetFeature geoss_water_sba:Reservoir GetFeature geoss_water_sba:glwd_1 GetFeature geoss_water_sba:Dams GetFeature geoss_water_sba:glwd_2 GetFeature geoss_water_sba:Lakes GetCapabilities HTTPGet HTTPPost http://services.ogc.noaa.gov/geoserver/geoss_water_sba/wfs DescribeFeatureType HTTPGet HTTPPost http://services.ogc.noaa.gov/geoserver/geoss_water_sba/wfs GetFeature HTTPGet HTTPPost http://services.ogc.noaa.gov/geoserver/geoss_water_sba/wfs GetGmlObject HTTPGet HTTPPost http://services.ogc.noaa.gov/geoserver/geoss_water_sba/wfs LockFeature HTTPGet HTTPPost http://services.ogc.noaa.gov/geoserver/geoss_water_sba/wfs GetFeatureWithLock HTTPGet HTTPPost http://services.ogc.noaa.gov/geoserver/geoss_water_sba/wfs Transaction HTTPGet HTTPPost http://services.ogc.noaa.gov/geoserver/geoss_water_sba/wfs http://services.ogc.noaa.gov/geoserver/geoss_water_sba/wfs OGC:WFS PYCSW_IDENTIFIER OGC-WFS Web Feature Service PYCSW_IDENTIFIER service http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer pointOfContact ISO19119 2005/PDAM 1 CERA_CERA_TechClasses_WGS84 OGC:WFS 2.0.0 171.11 173.13 -43.9 -42.74 tight GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-08-16 GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-05-18 GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2013-12-04 GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2011-10-28 GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-02-10 GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-09-14 GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-03-23 GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2011-11-17 GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-08-24 GetFeature CERA_CERA_TechClasses_WGS84:MBIE_Technical_Classes_WGS84_2012-10-31 GetCapabilities HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer DescribeFeatureType HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer GetFeature HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ListStoredQueries HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer DescribeStoredQueries HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsSimpleWFS HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsBasicWFS HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsTransactionalWFS HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsLockingWFS HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsInheritance HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsRemoteResolve HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsResultPaging HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsStandardJoins HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsSpatialJoins HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsTemporalJoins HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ImplementsFeatureVersioning HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer ManageStoredQueries HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer KVPEncoding HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer XMLEncoding HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer SOAPEncoding HTTPGet HTTPPost http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer OGC:WFS PYCSW_IDENTIFIER OGC-WFS Web Feature Service ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-zzz-post-GetRecords-filter-wms-dc.xml ================================================ PYCSW_IDENTIFIER 1 Million Scale WMS Layers from the National Atlas of the United States service http://webservices.nationalatlas.gov/wms/1million http://webservices.nationalatlas.gov/wms/1million?version=1.1.1&request=GetCapabilities&service=WMS http://webservices.nationalatlas.gov/wms/1million http://webservices.nationalatlas.gov/wms/1million http://webservices.nationalatlas.gov/wms/1million http://webservices.nationalatlas.gov/wms/1million http://webservices.nationalatlas.gov/wms/1million http://webservices.nationalatlas.gov/wms/1million http://demo.pycsw.org/services/csw 18.92 -179.13 71.4 179.79 PYCSW_IDENTIFIER Wisconsin Lake Clarity service SSEC PAW remote sensing meteorology atmospheric science University of Wisconsin Madison weather land http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=%2Fhome%2Fwms%2Fdata%2Fmapfiles%2Flakestsi.map&version=1.1.1&request=GetCapabilities&service=WMS http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map General: This server hosts a set of experimental OGC Web Services of remote sensing data products for use in a broad range of both desktop and mobile device clients. http://demo.pycsw.org/services/csw 42.41 -93.03 47.13 -86.64 PYCSW_IDENTIFIER View & download service for EU-DEM data provided by EOX service EU-DEM http://data.eox.at/eudem_ows http://data.eox.at/eudem_ows?version=1.1.1&request=GetCapabilities&service=WMS http://data.eox.at/eudem_ows http://data.eox.at/eudem_ows http://data.eox.at/eudem_ows http://data.eox.at/eudem_ows http://data.eox.at/eudem_ows http://data.eox.at/eudem_ows Produced using Copernicus data and information funded by the European Union - EU-DEM layers. http://demo.pycsw.org/services/csw 12.99 -29.09 12.99 -29.09 PYCSW_IDENTIFIER IEM WMS Service service WMS http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi IEM generated CONUS composite of NWS WSR-88D level III base reflectivity. Daryl Herzmann Iowa State University Daryl Herzmann http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi None urn:ogc:def:crs:EPSG:6.11:4326 24.0 -126.0 50.0 -66.0 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-zzz-post-GetRecords-filter-wms-iso.xml ================================================ PYCSW_IDENTIFIER service ISO19119 2005/PDAM 1 1 Million Scale WMS Layers from the National Atlas of the United States OGC:WMS 1.1.1 -179.13 179.79 18.92 71.4 tight GetMap ports1m GetMap national1m GetMap elevation GetMap impervious GetMap coast1m GetMap cdl GetMap states1m GetMap elsli0100g GetMap landcov100m GetMap cdp GetMap amtrak1m GetMap airports1m GetMap one_million GetMap satvi0100g GetMap srcoi0100g GetMap srgri0100g GetMap treecanopy GetMap svsri0100g GetCapabilities HTTPGet HTTPPost http://webservices.nationalatlas.gov/wms/1million GetMap HTTPGet HTTPPost http://webservices.nationalatlas.gov/wms/1million GetFeatureInfo HTTPGet HTTPPost http://webservices.nationalatlas.gov/wms/1million DescribeLayer HTTPGet HTTPPost http://webservices.nationalatlas.gov/wms/1million GetLegendGraphic HTTPGet HTTPPost http://webservices.nationalatlas.gov/wms/1million GetStyles HTTPGet HTTPPost http://webservices.nationalatlas.gov/wms/1million http://webservices.nationalatlas.gov/wms/1million OGC:WMS PYCSW_IDENTIFIER OGC-WMS Web Map Service http://webservices.nationalatlas.gov/wms/1million?version=1.1.1&request=GetCapabilities&service=WMS OGC:WMS-1.1.1-http-get-capabilities PYCSW_IDENTIFIER OGC-WMS Capabilities service (ver 1.1.1) PYCSW_IDENTIFIER service Dr. Sam Batzli ISO19119 2005/PDAM 1 Wisconsin Lake Clarity General: This server hosts a set of experimental OGC Web Services of remote sensing data products for use in a broad range of both desktop and mobile device clients. SSEC PAW remote sensing meteorology atmospheric science University of Wisconsin Madison weather land OGC:WMS 1.1.1 SSEC PAW remote sensing meteorology atmospheric science University of Wisconsin Madison weather land -93.03 -86.64 42.41 47.13 tight GetMap Highways GetMap LakesTSI GetMap LakeClarity GetMap LakesTSI_0305 GetMap Relief GetMap LakeNames_0305 GetMap Roads GetMap LakeNames GetMap Counties GetCapabilities HTTPGet HTTPPost http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map GetMap HTTPGet HTTPPost http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map GetFeatureInfo HTTPGet HTTPPost http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map OGC:WMS PYCSW_IDENTIFIER OGC-WMS Web Map Service http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=%2Fhome%2Fwms%2Fdata%2Fmapfiles%2Flakestsi.map&version=1.1.1&request=GetCapabilities&service=WMS OGC:WMS-1.1.1-http-get-capabilities PYCSW_IDENTIFIER OGC-WMS Capabilities service (ver 1.1.1) PYCSW_IDENTIFIER service Stephan Meissl ISO19119 2005/PDAM 1 View & download service for EU-DEM data provided by EOX Produced using Copernicus data and information funded by the European Union - EU-DEM layers. EU-DEM OGC:WMS 1.1.1 EU-DEM -29.09 -29.09 12.99 12.99 tight GetMap EU-DEM GetMap MS GetMap eudem_color GetCapabilities HTTPGet HTTPPost http://data.eox.at/eudem_ows GetMap HTTPGet HTTPPost http://data.eox.at/eudem_ows GetFeatureInfo HTTPGet HTTPPost http://data.eox.at/eudem_ows DescribeLayer HTTPGet HTTPPost http://data.eox.at/eudem_ows GetLegendGraphic HTTPGet HTTPPost http://data.eox.at/eudem_ows GetStyles HTTPGet HTTPPost http://data.eox.at/eudem_ows http://data.eox.at/eudem_ows OGC:WMS PYCSW_IDENTIFIER OGC-WMS Web Map Service http://data.eox.at/eudem_ows?version=1.1.1&request=GetCapabilities&service=WMS OGC:WMS-1.1.1-http-get-capabilities PYCSW_IDENTIFIER OGC-WMS Capabilities service (ver 1.1.1) PYCSW_IDENTIFIER service Daryl Herzmann Iowa State University https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi? ISO19119 2005/PDAM 1 IEM WMS Service IEM generated CONUS composite of NWS WSR-88D level III base reflectivity. OGC:WMS 1.3.0 -126.0 -66.0 24.0 50.0 tight GetMap nexrad_base_reflect GetMap time_idx GetMap nexrad-n0r-wmst GetCapabilities HTTPGet HTTPPost http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi GetMap HTTPGet HTTPPost http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi GetFeatureInfo HTTPGet HTTPPost http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi DescribeLayer HTTPGet HTTPPost http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi GetLegendGraphic HTTPGet HTTPPost http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi GetStyles HTTPGet HTTPPost http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi OGC:WMS PYCSW_IDENTIFIER OGC-WMS Web Map Service ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-zzz-post-GetRecords-filter-wms-layer.xml ================================================ PYCSW_IDENTIFIER NEXRAD BASE REFLECT dataset http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi?layers=time_idx&width=200&version=1.1.1&bbox=-126.0%2C24.0%2C-66.0%2C50.0&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A4326&request=GetMap&height=200 http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi urn:ogc:def:crs:EPSG:6.11:4326 24.0 -126.0 50.0 -66.0 PYCSW_IDENTIFIER NEXRAD BASE REFLECT dataset http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi?layers=nexrad-n0r-wmst&width=200&version=1.1.1&bbox=-126.0%2C24.0%2C-66.0%2C50.0&service=WMS&format=image%2Fpng&styles=&srs=EPSG%3A4326&request=GetMap&height=200 http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi urn:ogc:def:crs:EPSG:6.11:4326 24.0 -126.0 50.0 -66.0 ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Harvest-zzz-post-GetRecords-filter-wps-process.xml ================================================ PYCSW_IDENTIFIER gov.usgs.cida.gdp.wps.algorithm.filemanagement.CreateNewShapefileDataStore software http://cida.usgs.gov/gdp/utility/WebProcessingService http://cida.usgs.gov/gdp/utility/WebProcessingService?version=1.0.0&request=GetCapabilities&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.filemanagement.CreateNewShapefileDataStore&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService PYCSW_IDENTIFIER Get Grid Time Range software http://cida.usgs.gov/gdp/utility/WebProcessingService http://cida.usgs.gov/gdp/utility/WebProcessingService?version=1.0.0&request=GetCapabilities&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.filemanagement.CreateNewShapefileDataStore&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.discovery.GetGridTimeRange&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService PYCSW_IDENTIFIER gov.usgs.cida.gdp.wps.algorithm.filemanagement.ReceiveFiles software http://cida.usgs.gov/gdp/utility/WebProcessingService http://cida.usgs.gov/gdp/utility/WebProcessingService?version=1.0.0&request=GetCapabilities&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.filemanagement.CreateNewShapefileDataStore&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.discovery.GetGridTimeRange&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.filemanagement.ReceiveFiles&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService PYCSW_IDENTIFIER gov.usgs.cida.gdp.wps.algorithm.discovery.GetWcsCoverages software http://cida.usgs.gov/gdp/utility/WebProcessingService http://cida.usgs.gov/gdp/utility/WebProcessingService?version=1.0.0&request=GetCapabilities&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.filemanagement.CreateNewShapefileDataStore&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.discovery.GetGridTimeRange&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.filemanagement.ReceiveFiles&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.discovery.GetWcsCoverages&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService PYCSW_IDENTIFIER gov.usgs.cida.gdp.wps.algorithm.filemanagement.GetWatersGeom software http://cida.usgs.gov/gdp/utility/WebProcessingService http://cida.usgs.gov/gdp/utility/WebProcessingService?version=1.0.0&request=GetCapabilities&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.filemanagement.CreateNewShapefileDataStore&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.discovery.GetGridTimeRange&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.filemanagement.ReceiveFiles&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.discovery.GetWcsCoverages&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService?identifier=gov.usgs.cida.gdp.wps.algorithm.filemanagement.GetWatersGeom&version=1.0.0&request=DescribeProcess&service=WPS http://cida.usgs.gov/gdp/utility/WebProcessingService ================================================ FILE: tests/functionaltests/suites/harvesting/expected/post_Transaction-000-delete-all.xml ================================================ 0 0 131 ================================================ FILE: tests/functionaltests/suites/harvesting/get/requests.txt ================================================ Exception-Harvest-missing-resourcetype,config=tests/suites/manager/default.yml&service=CSW&version=2.0.2&request=Harvest Exception-Harvest-missing-source,config=tests/suites/manager/default.yml&service=CSW&version=2.0.2&request=Harvest&resourcetype=http://www.opengis.net/wms Exception-Harvest-invalid-resourcetype,config=tests/suites/manager/default.yml&service=CSW&version=2.0.2&request=Harvest&resourcetype=http://www.opengis.net/wms1234&source=http://demo.pycsw.org/cite/csw Exception-Harvest-waf-no-records-found,config=tests/suites/manager/default.yml&service=CSW&version=2.0.2&request=Harvest&resourcetype=urn:geoss:waf&source=http://demo.pycsw.org Exception-Harvest-waf-bad-value,config=tests/suites/manager/default.yml&service=CSW&version=2.0.2&request=Harvest&resourcetype=urn:geoss:waf&source=badvalue ================================================ FILE: tests/functionaltests/suites/harvesting/post/Clear-000-delete-all.xml ================================================ dc:identifier % ================================================ FILE: tests/functionaltests/suites/harvesting/post/Exception-Havest-csw-404.xml ================================================ https://demo.pycsw.org/gisdata/cswBAD http://www.opengis.net/cat/csw/2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/GetDomain-parameter.xml ================================================ Harvest.ResourceType ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-csw-iso.xml ================================================ http://demo.pycsw.org/services/csw http://www.opengis.net/cat/csw/2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-csw-run1.xml ================================================ http://demo.pycsw.org/cite/csw http://www.opengis.net/cat/csw/2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-csw-run2.xml ================================================ http://demo.pycsw.org/cite/csw http://www.opengis.net/cat/csw/2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-dc.xml ================================================ http://demo.pycsw.org/metadata/Clause_10.2.5.3.2_Example03_Full.xml http://www.opengis.net/cat/csw/2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-fgdc.xml ================================================ http://demo.pycsw.org/metadata/CDC008.xml http://www.opengis.net/cat/csw/csdgm application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-iso.xml ================================================ http://demo.pycsw.org/metadata/dataset2_minimalst.xml http://www.isotc211.org/schemas/2005/gmd/ application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-rdf.xml ================================================ http://demo.pycsw.org/metadata/dc-rdf.xml http://www.opengis.net/cat/csw/2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-sos100.xml ================================================ http://www.neracoos.org/cgi-bin/sos/V1.0/oostethys_sos.cgi http://www.opengis.net/sos/1.0 ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-sos200.xml ================================================ http://ngwd-bdnes.cits.nrcan.gc.ca/GinService/sos/gw http://www.opengis.net/sos/2.0 ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-waf.xml ================================================ http://demo.pycsw.org/waf urn:geoss:waf ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-wcs.xml ================================================ http://demo.mapserver.org/cgi-bin/wcs http://www.opengis.net/wcs application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-wfs110.xml ================================================ http://services.ogc.noaa.gov/geoserver/geoss_water_sba/wfs http://www.opengis.net/wfs application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-wfs200.xml ================================================ http://maps.cera.govt.nz/arcgis/services/CERA/CERA_TechClasses_WGS84/MapServer/WFSServer http://www.opengis.net/wfs/2.0 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-wms-run1.xml ================================================ http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi http://www.opengis.net/wms application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-wms-run2.xml ================================================ http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi http://www.opengis.net/wms application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-wmts.xml ================================================ http://maps.wien.gv.at/wmts/1.0.0/WMTSCapabilities.xml http://www.opengis.net/wmts/1.0 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-wps.xml ================================================ http://cida.usgs.gov/gdp/utility/WebProcessingService http://www.opengis.net/wps/1.0.0 application/xml ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-ows-dc.xml ================================================ full apiso:ServiceType OGC:SOS apiso:ServiceType OGC:WPS apiso:ServiceType OGC:WMS apiso:ServiceType OGC:WFS apiso:ServiceType OGC:CSW apiso:ServiceType OGC:WCS ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml ================================================ full apiso:Type service apiso:ServiceType OGC:SOS apiso:Abstract (groundwater( ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-dc.xml ================================================ full apiso:Type service apiso:ServiceType OGC:SOS ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-iso.xml ================================================ full apiso:Type service apiso:ServiceType OGC:SOS ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wfs-iso.xml ================================================ full apiso:Type service apiso:ServiceType OGC:WFS ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wms-dc.xml ================================================ full apiso:Type service apiso:ServiceType OGC:WMS ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wms-iso.xml ================================================ full apiso:Type service apiso:ServiceType OGC:WMS ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wms-layer.xml ================================================ full dc:type dataset csw:AnyText %nexrad% ================================================ FILE: tests/functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wps-process.xml ================================================ full dc:type software ================================================ FILE: tests/functionaltests/suites/harvesting/post/Transaction-000-delete-all.xml ================================================ dc:identifier % ================================================ FILE: tests/functionaltests/suites/idswithpaths/data/file_id_as_url.xml ================================================ https://ioos.noaa.gov/stations/BRJASL eng UTF8 dataset service Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact 2017-10-27 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 4500 0.011113580795732384 row 3661 0.008743169398907104 temporal 1 0.0 area AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) org.maracoos AVHRR.2012.7Agg Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact MARACOOS AVHRR SST UDEL Satellite SST Rutgers EARTH SCIENCE > OCEANS > OCEAN TEMPERATURE > SEA SURFACE TEMPERATURE theme MARACOOS DMAC dataCenter sea_surface_temperature longitude latitude time theme http://www.cgd.ucar.edu/cms/eaton/cf-metadata/standard_name.html Freely Distributed Unidata Common Data Model Grid largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 -100.0 -50.0 20.0 52.0 seconds 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. OPeNDAP:OPeNDAP 1 -100.0 -50.0 20.0 52.0 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z tight OPeNDAP Client Access http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg OPeNDAP:OPeNDAP OPeNDAP THREDDS OPeNDAP download mcsst float Multichannel Sea Surface Temperature (sea_surface_temperature) grid_topology int lon double Longitude (longitude) lat double Latitude (latitude) time int Time (time) MARACOOS DMAC maracoosinfo@udel.edu http://maracoos.org WWW:LINK web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg.html WWW:LINK File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://www.ncdc.noaa.gov/oa/wct/wct-jnlp-beta.php?singlefile=http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg WWW:LINK Viewer Information This URL provides an NCDC climate and weather toolkit view of an OPeNDAP resource. mapDigital This record was translated from NcML using UnidataDD2MI.xsl Version 2.3.4. (2017-10-27T16:24:57.008-04:00) ================================================ FILE: tests/functionaltests/suites/idswithpaths/data/file_id_starting_with_forward_slash.xml ================================================ /i/started/with/a/slash eng UTF8 dataset service Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact 2017-10-27 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 4500 0.011113580795732384 row 3661 0.008743169398907104 temporal 1 0.0 area AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) org.maracoos AVHRR.2012.7Agg Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact MARACOOS AVHRR SST UDEL Satellite SST Rutgers EARTH SCIENCE > OCEANS > OCEAN TEMPERATURE > SEA SURFACE TEMPERATURE theme MARACOOS DMAC dataCenter sea_surface_temperature longitude latitude time theme http://www.cgd.ucar.edu/cms/eaton/cf-metadata/standard_name.html Freely Distributed Unidata Common Data Model Grid largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 -100.0 -50.0 20.0 52.0 seconds 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. OPeNDAP:OPeNDAP 1 -100.0 -50.0 20.0 52.0 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z tight OPeNDAP Client Access http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg OPeNDAP:OPeNDAP OPeNDAP THREDDS OPeNDAP download mcsst float Multichannel Sea Surface Temperature (sea_surface_temperature) grid_topology int lon double Longitude (longitude) lat double Latitude (latitude) time int Time (time) MARACOOS DMAC maracoosinfo@udel.edu http://maracoos.org WWW:LINK web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg.html WWW:LINK File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://www.ncdc.noaa.gov/oa/wct/wct-jnlp-beta.php?singlefile=http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg WWW:LINK Viewer Information This URL provides an NCDC climate and weather toolkit view of an OPeNDAP resource. mapDigital This record was translated from NcML using UnidataDD2MI.xsl Version 2.3.4. (2017-10-27T16:24:57.008-04:00) ================================================ FILE: tests/functionaltests/suites/idswithpaths/data/file_id_with_colon.xml ================================================ urn:hi:im:a:urn:or:url eng UTF8 dataset service Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact 2017-10-27 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 4500 0.011113580795732384 row 3661 0.008743169398907104 temporal 1 0.0 area AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) org.maracoos AVHRR.2012.7Agg Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact MARACOOS AVHRR SST UDEL Satellite SST Rutgers EARTH SCIENCE > OCEANS > OCEAN TEMPERATURE > SEA SURFACE TEMPERATURE theme MARACOOS DMAC dataCenter sea_surface_temperature longitude latitude time theme http://www.cgd.ucar.edu/cms/eaton/cf-metadata/standard_name.html Freely Distributed Unidata Common Data Model Grid largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 -100.0 -50.0 20.0 52.0 seconds 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. OPeNDAP:OPeNDAP 1 -100.0 -50.0 20.0 52.0 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z tight OPeNDAP Client Access http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg OPeNDAP:OPeNDAP OPeNDAP THREDDS OPeNDAP download mcsst float Multichannel Sea Surface Temperature (sea_surface_temperature) grid_topology int lon double Longitude (longitude) lat double Latitude (latitude) time int Time (time) MARACOOS DMAC maracoosinfo@udel.edu http://maracoos.org WWW:LINK web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg.html WWW:LINK File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://www.ncdc.noaa.gov/oa/wct/wct-jnlp-beta.php?singlefile=http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg WWW:LINK Viewer Information This URL provides an NCDC climate and weather toolkit view of an OPeNDAP resource. mapDigital This record was translated from NcML using UnidataDD2MI.xsl Version 2.3.4. (2017-10-27T16:24:57.008-04:00) ================================================ FILE: tests/functionaltests/suites/idswithpaths/data/file_id_with_directory_changes.xml ================================================ ../../../I'm Trying to go back a few directories/../.. eng UTF8 dataset service Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact 2017-10-27 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 4500 0.011113580795732384 row 3661 0.008743169398907104 temporal 1 0.0 area AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) org.maracoos AVHRR.2012.7Agg Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact MARACOOS AVHRR SST UDEL Satellite SST Rutgers EARTH SCIENCE > OCEANS > OCEAN TEMPERATURE > SEA SURFACE TEMPERATURE theme MARACOOS DMAC dataCenter sea_surface_temperature longitude latitude time theme http://www.cgd.ucar.edu/cms/eaton/cf-metadata/standard_name.html Freely Distributed Unidata Common Data Model Grid largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 -100.0 -50.0 20.0 52.0 seconds 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. OPeNDAP:OPeNDAP 1 -100.0 -50.0 20.0 52.0 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z tight OPeNDAP Client Access http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg OPeNDAP:OPeNDAP OPeNDAP THREDDS OPeNDAP download mcsst float Multichannel Sea Surface Temperature (sea_surface_temperature) grid_topology int lon double Longitude (longitude) lat double Latitude (latitude) time int Time (time) MARACOOS DMAC maracoosinfo@udel.edu http://maracoos.org WWW:LINK web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg.html WWW:LINK File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://www.ncdc.noaa.gov/oa/wct/wct-jnlp-beta.php?singlefile=http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg WWW:LINK Viewer Information This URL provides an NCDC climate and weather toolkit view of an OPeNDAP resource. mapDigital This record was translated from NcML using UnidataDD2MI.xsl Version 2.3.4. (2017-10-27T16:24:57.008-04:00) ================================================ FILE: tests/functionaltests/suites/idswithpaths/data/file_id_with_driveletter_and_backslashes.xml ================================================ C:\\hi\\I'm\\a\\windows\\folder eng UTF8 dataset service Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact 2017-10-27 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 4500 0.011113580795732384 row 3661 0.008743169398907104 temporal 1 0.0 area AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) org.maracoos AVHRR.2012.7Agg Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact MARACOOS AVHRR SST UDEL Satellite SST Rutgers EARTH SCIENCE > OCEANS > OCEAN TEMPERATURE > SEA SURFACE TEMPERATURE theme MARACOOS DMAC dataCenter sea_surface_temperature longitude latitude time theme http://www.cgd.ucar.edu/cms/eaton/cf-metadata/standard_name.html Freely Distributed Unidata Common Data Model Grid largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 -100.0 -50.0 20.0 52.0 seconds 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. OPeNDAP:OPeNDAP 1 -100.0 -50.0 20.0 52.0 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z tight OPeNDAP Client Access http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg OPeNDAP:OPeNDAP OPeNDAP THREDDS OPeNDAP download mcsst float Multichannel Sea Surface Temperature (sea_surface_temperature) grid_topology int lon double Longitude (longitude) lat double Latitude (latitude) time int Time (time) MARACOOS DMAC maracoosinfo@udel.edu http://maracoos.org WWW:LINK web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg.html WWW:LINK File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://www.ncdc.noaa.gov/oa/wct/wct-jnlp-beta.php?singlefile=http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg WWW:LINK Viewer Information This URL provides an NCDC climate and weather toolkit view of an OPeNDAP resource. mapDigital This record was translated from NcML using UnidataDD2MI.xsl Version 2.3.4. (2017-10-27T16:24:57.008-04:00) ================================================ FILE: tests/functionaltests/suites/idswithpaths/data/file_id_with_foward_slashes.xml ================================================ hello/i/am/a/path eng UTF8 dataset service Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact 2017-10-27 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 4500 0.011113580795732384 row 3661 0.008743169398907104 temporal 1 0.0 area AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) org.maracoos AVHRR.2012.7Agg Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information pointOfContact MARACOOS AVHRR SST UDEL Satellite SST Rutgers EARTH SCIENCE > OCEANS > OCEAN TEMPERATURE > SEA SURFACE TEMPERATURE theme MARACOOS DMAC dataCenter sea_surface_temperature longitude latitude time theme http://www.cgd.ucar.edu/cms/eaton/cf-metadata/standard_name.html Freely Distributed Unidata Common Data Model Grid largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 -100.0 -50.0 20.0 52.0 seconds 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z AVHRR Sea Surface Temperature for MARACOOS (Mid-Atlantic Regional Association Coastal Ocean Observing System) Matt Oliver University of Delaware moliver@udel.edu http://orb.ceoe.udel.edu/ WWW:LINK web browser information originator Sea surface temperature over the Mid-Atlantic and surrounding waters from NOAA AVHRR satellites. MCSST calculation and image navigation by TeraScan software; Regridded to Mercator lon/lat projection. Processed and De-clouded at University of Delaware. All data data are preserved, and a multi class cloud mask is provided to the user. OPeNDAP:OPeNDAP 1 -100.0 -50.0 20.0 52.0 2012-10-27T19:46:59Z 2012-10-27T19:46:59Z tight OPeNDAP Client Access http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg OPeNDAP:OPeNDAP OPeNDAP THREDDS OPeNDAP download mcsst float Multichannel Sea Surface Temperature (sea_surface_temperature) grid_topology int lon double Longitude (longitude) lat double Latitude (latitude) time int Time (time) MARACOOS DMAC maracoosinfo@udel.edu http://maracoos.org WWW:LINK web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg.html WWW:LINK File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://www.ncdc.noaa.gov/oa/wct/wct-jnlp-beta.php?singlefile=http://tds.maracoos.org/thredds/dodsC/AVHRR/2012/7Agg WWW:LINK Viewer Information This URL provides an NCDC climate and weather toolkit view of an OPeNDAP resource. mapDigital This record was translated from NcML using UnidataDD2MI.xsl Version 2.3.4. (2017-10-27T16:24:57.008-04:00) ================================================ FILE: tests/functionaltests/suites/idswithpaths/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/idswithpaths/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log #federatedcatalogues: # - id: fedcat01 # type: CSW # title: Arctic SDI # url: https://catalogue.arctic-sdi.org/csw # - id: fedcat02 # type: OARec # title: pycsw OGC CITE demo and Reference Implementation # url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/idswithpaths/expected/get_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/idswithpaths/get/requests.txt ================================================ GetCapabilities,service=CSW&version=2.0.2&request=GetCapabilities ================================================ FILE: tests/functionaltests/suites/iso19115p3/data/README.txt ================================================ ISO 19115 Part 3 XML Data ========================= This directory provides data used to check conformance against pycsw's ISO 19115 Part 3 XML support. Acknowledged sources: https://portal.auscope.org.au/geonetwork: auscope-iso19139-geoprovinces.xml, auscope-3d-model.xml https://metawal.wallonie.be/geonetwork/: metawal.wallonie.be-catchments.xml, metawal.wallonie.be-srv.xml ================================================ FILE: tests/functionaltests/suites/iso19115p3/data/auscope-3d-model.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 urn:uuid Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au Anthony Hurst Executive Director, Earth Resources Policy and Programs 2022-11-03T06:16:21 2022-11-03T06:17:02 ISO 19115-3 http://portal.auscope.org/geonetwork/srv/api/records/5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 2010-01-01 https://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 Reference AuScope Level 2, 700 Swanston Street Carlton Victoria 3053 Australia info@auscope.org.au https://ror.org/04s1m4564 ROR Research Organization Registry (ROR) Entry Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au P.B. SKLADZIEN C. Jorand A. Krassay L. Hall A 3D model of the Otway and Torquay basins has been produced at 1:250 000 scale as part of GeoScience Victorias state-wide 3D geological model. To date there has been a “knowledge gap” in the transition between the basement and basin environments. This regional scale integration of the basement and basin models addresses this gap and provides a regional framework within which more detailed work can be carried out in the future. The construction and integration of the basin model has involved both the interpretation and building of new faults and stratigraphic surfaces, as well as utilising existing stratigraphic surfaces and structural interpretations from previous studies, predominantly the Otway Basin HSA SEEBASE project by FrOG Tech (Jorand et. al., 2010). 143.00 144.00 -39.40 -38.40 -400 300 Victoria Otway Basin Torquay Basin 3D Geological Models https://creativecommons.org/licenses/by/4.0/ http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model ================================================ FILE: tests/functionaltests/suites/iso19115p3/data/auscope-iso19139-geoprovinces.xml ================================================ 09a7c1d4c97ccdd7e34306deb91320ab95d51bb8 eng Peter Warren CSIRO Software Engineer +61 2 9490 8802 11 Julius Ave North Ryde CSIRO 2113 Australia http://geoserver.sourceforge.net/html/index.php 2018-02-08T11:04:47 ISO 19115:2003/19139 1.0 EPSG:4283 ProvinceFullExtent 2018-02-08T11:04:47 Peter Warren CSIRO Software Engineer +61 2 9490 8802 11 Julius Ave North Ryde CSIRO 2113 Australia http://geoserver.sourceforge.net/html/index.php features ProvinceFullExtent geoscientificInformation 106.56906097500001 171.88106000000005 -49.861429999999984 -3.6270000000000095 https://nvclwebservices.csiro.au/geoserver/wms?SERVICE=WMS& OGC:WMS-1.1.1-http-get-map gml:ProvinceFullExtent ProvinceFullExtent https://nvclwebservices.csiro.au/geoserver/wms?request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=gml%3AProvinceFullExtent image/png Default Polygon (LegendURL) ================================================ FILE: tests/functionaltests/suites/iso19115p3/data/metawal.wallonie.be-catchments.xml ================================================ 74f81503-8d39-4ec8-a49a-c76e0cd74946 urn:uuid Collection de données thématiques Direction des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines) +32 (0)81/335923 veronique.willame@spw.wallonie.be Véronique Willame 2023-08-08T07:34:11.366Z 2019-04-02T12:32:13 ISO 19115 2003/Cor 1:2006 https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946 EPSG:31370 Belge 1972 / Belgian Lambert 72 (EPSG:31370) Protection des captages - Série PROTECT_CAPT 2000-01-01 2023-07-31 2022-11-08 PROTECT_CAPT BE.SPW.INFRASIG.GINET 74f81503-8d39-4ec8-a49a-c76e0cd74946 http://geodata.wallonie.be/id/ Cette collection de données comprend les zones de surveillance arrêtées, de prévention forfaitaires et de prévention arrêtées ou à l'enquête publique autour des captages. Cet ensemble de classes d'entités est constitué de trois couches distinctes. - Les zones de surveillance arrêtées (PROTECT_CAPT__ZONE_III_ARRETEE) - les zones de prévention arrêtées (PROTECT_CAPT__ZONE_II_ARRETEE) - les zones de prévention forfaitaires (PROTECT_CAPT__ZONE_II_FORFAIT) La classe d'entités "zones de surveillance arrêtées" contient l'ensemble des zones de surveillance délimitées autour de certaines zones de prévention (approuvées par arrêté ministériel) des captages d'eau de distribution publique d'eau potable les plus importants de par les volumes exploités. Actuellement, on en compte cinq sur toute la Wallonie. Ces zones de surveillance III sont délimitées par le bassin d'alimentation et le bassin hydrogéologique et fournies à la Directions des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines) sur document papier par le producteur d'eau publique qui a réalisé l'étude. La classe d'entités "zones de prévention arrêtées" contient l'ensemble des zones de prévention (autour des captages d'eau souterraine) rapprochées (IIa) et éloignées (IIb) approuvées par arrêté ministériel, à l'enquête publique (en cours ou terminée) ou à l'instruction. Cette couche couvre toute la Wallonie. La classe d'entités "zones de prévention forfaitaires" autour des captages contient l'ensemble des zones de prévention forfaitaires (ou théoriques), autour des captages d'eau souterraine de distribution publique. Ces zones de prévention sont provisoires. Elles sont de forme circulaire et seront définies et officialisées, dans le futur, après une étude de délimitation par le producteur d'eau qui l'exploite le captage. Les diamètres des zones de prévention forfaitaires rapprochées (IIa) et éloignées (IIb) sont fonction de la nature du terrain. La méthode des distances théoriques tient compte essentiellement de la perméabilité des terrains: zone de prise d'eau (10 m minimum autour des installations), zone de prévention rapprochée IIa (35 m autour des installations de la prise d'eau), zone de prévention IIb (100 m dans les aquifères sableux, 500 m dans les aquifères graveleux et 1000 m dans les aquifères fissurés et karstiques autour de la zone de prévention rapprochée). Cette couche couvre toute la Wallonie. Suite au décalage entre la mise à jour des Zones de prévention forfaitaires autour des captages (décembre 2018) et des Zones de prévention arrêtée ou à l'enquête publique autour des captages, mises à jour en mai 2020, et lorsqu’une zone arrêtée est présente pour un captage, c’est celle-ci qui prime au détriment de la zone forfaitaire. La mise à jour des Zones de prévention forfaitaires autour des captages est prévue début juillet 2020. Helpdesk carto du SPW (SPW - Secrétariat général - SPW Digital - Département Données transversales - Gestion et valorisation de la donnée) helpdesk.carto@spw.wallonie.be Direction des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines) +32 (0)81/335923 veronique.willame@spw.wallonie.be Véronique Willame Service public de Wallonie (SPW) https://geoportail.wallonie.be WWW:LINK Géoportail de la Wallonie Géoportail de la Wallonie 10000 geoscientificInformation inlandWaters Région wallonne 2.75 6.50 49.45 50.85 https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT.png protect_capt_pic png https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT_s.png protect_capt_pic_small png Sol et sous-sol Eau Thèmes du géoportail wallon 2014-01-01 2014-06-26 geonetwork.thesaurus.external.theme.Themes_geoportail_wallon_hierarchy eau politique environnementale GEMET themes 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet-theme eau potable surveillance de l'environnement surveillance de l'eau eau de surface captage eaux souterraines zone de captage d'eau potable zone protégée de captage d'eau protection de zone de captage de l'eau captage d'eau GEMET 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet DGO3_BDREF WalOnMap Extraction_DIG DGO3_CIGALE Reporting INSPIRENO Open Data BDInfraSIGNO PanierTelechargementGeoportail Mots-clés InfraSIG 2022-10-03 2022-10-03 geonetwork.thesaurus.external.theme.infraSIG zone forfaitaire prévention rapprochée prévention éloignée prévention IIa IIb surveillance III Les conditions générales d'accès s’appliquent. Les conditions générales d'utilisation s'appliquent. Modèle de données http://environnement.wallonie.be/cartosig/Inventaire_Donnees/Modeles_SIG3/PROTECT_CAPT.pdf WWW:LINK application/pdf Modèle de données (document pdf) ESRI Shapefile (.shp) - ESRI File Geodatabase (.fgdb) 10.x Service public de Wallonie (SPW) helpdesk.carto@spw.wallonie.be Cette ressource est une collection de données. En la commandant, l'ensemble des géodonnées constitutives de cette collection vous sera automatiquement fourni. Les instructions pour obtenir une copie physique d’une donnée sont détaillées sur https://geoportail.wallonie.be/telecharger. Cellule SIG de la DGARNE (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Étude du milieu naturel et agricole - Direction de la Coordination des Données) sig.dgarne@spw.wallonie.be https://geoportail.wallonie.be/walonmap/#ADU=https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer WWW:LINK Application WalOnMap - Toute la Wallonie à la carte Application cartographique du Geoportail (WalOnMap) qui permet de découvrir les données géographiques de la Wallonie. http://geoapps.wallonie.be/Cigale/Public/#CTX=EAUX_SOUT WWW:LINK Protection des eaux souteraines (CIGALE) - Application Application de consultation des principales données cartographiques du SPW Agriculture, Ressources naturelles et Environnements https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer ESRI:REST Service de visualisation ESRI-REST Ce service ESRI-REST permet de visualiser le jeu de données "Protection des captages" https://geoservices.wallonie.be/arcgis/services/EAU/PROTECT_CAPT/MapServer/WMSServer?request=GetCapabilities&service=WMS OGC:WMS Service de visualisation WMS Ce service WMS permet de visualiser le jeu de données "Protection des captages" http://environnement.wallonie.be/de/eso/atlas/index.htm#4.1a WWW:LINK Site web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b. Zones de protection définies par arrêté ministériel Pages web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b Zones de protection définies par arrêté ministériel Pour les zones arrêtées (les zones de surveillance arrêtées et les zones de prévention arrêtées ou à l'enquête publique), les entités sont numérisées sur base des plans papier des producteurs d'eau qui réalisent l'étude de délimitation des zones de prévention. Le dossier est déposé au centre extérieur de la DESO pour réception, vérification, officialisation par arrêté ministériel et publication au Moniteur belge. Chaque zone de prévention est numérisée par digitalisation (à la Direction des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines)) sur base de plans papier sur fond IGN et sur Fond cadastral. Pour les zones forfaitaires, les entités de cette couche sont des zones de prévention circulaires, générées autour de la position exacte de chacun des captages d'eau de distribution publique d'eau potable (qui n'ont pas encore de zones de prévention approuvée par arrêté ministériel), en créant un buffer de diamètres différents en fonction de la nature de l'aquifère et de la zone rapprochée ou éloignée. Collection de données thématiques ================================================ FILE: tests/functionaltests/suites/iso19115p3/data/metawal.wallonie.be-srv.xml ================================================ 1714cd1e-6685-4dea-a6f4-b51612a15ed0 urn:uuid Service Gestion et valorisation de la donnée (SPW - Secrétariat général - SPW Digital - Département Données transversales - Gestion et valorisation de la donnée) helpdesk.carto@spw.wallonie.be 2023-12-11T13:33:59.133Z 2019-04-02T12:32:33 ISO 19119 2005/Amd.1:2008 https://metawal.wallonie.be/geonetwork/srv/api/records/1714cd1e-6685-4dea-a6f4-b51612a15ed0 EPSG:31370 Belge 1972 / Belgian Lambert 72 (EPSG:31370) EPSG:4326 WGS 84 (EPSG:4326) EPSG:3857 WGS 84 / Pseudo-Mercator (EPSG:3857) EPSG:3035 ETRS89 / LAEA Europe (EPSG:3035) EPSG:4258 ETRS89 (EPSG:4258) EPSG:3812 ETRS89 / Belgian Lambert 2008 (EPSG:3812) INSPIRE - Santé et sécurité des personnes en Wallonie (BE) - Service de visualisation WMS 2018-03-01 1714cd1e-6685-4dea-a6f4-b51612a15ed0 http://geodata.wallonie.be/id/ Ce service de visualisation WMS INSPIRE permet de consulter les couches de données du thème "Santé et sécurité des personnes" au sein du territoire wallon (Belgique). Ce service de visualisation WMS est fourni par le Service public de Wallonie (SPW) et expose les couches de données géographiques constitutives du thème "Santé et sécurité des personnes" de la Directive (Annexe 3.5) sur l'ensemble du territoire wallon. Ce service permet donc de visualiser les couches de données sélectionnées comme faisant partie du thème "Bâtiments". Ces couches de données sont présentées "telles quelles", c'est-à-dire dans leur modèle de données initial, non conforme aux spécifications de données définies par la Directive. Les couches de données seront progressivement adaptées aux modèles de donnée commun INSPIRE suivant les spécifications du thème. Le service de visualisation est conforme aux spécifications de la Directive INSPIRE en la matière. Helpdesk carto du SPW (SPW - Secrétariat général - SPW Digital - Département de la Géomatique - Direction de l'Intégration des géodonnées) helpdesk.carto@spw.wallonie.be Gestion et valorisation de la donnée (SPW - Secrétariat général - SPW Digital - Département Données transversales - Gestion et valorisation de la donnée) helpdesk.carto@spw.wallonie.be Service public de Wallonie (SPW) helpdesk.carto@spw.wallonie.be https://geoportail.wallonie.be WWW:LINK Géoportail de la Wallonie Géoportail de la Wallonie Région wallonne 2.75 6.51 49.45 50.85 https://metawal.wallonie.be/geonetwork/inspire/api/records/1714cd1e-6685-4dea-a6f4-b51612a15ed0/attachments/wms_inspire_20190430.png Industrie et services Société et activités Thèmes du géoportail wallon 2014-01-01 2014-06-26 geonetwork.thesaurus.external.theme.Themes_geoportail_wallon_hierarchy Santé et sécurité des personnes GEMET - INSPIRE themes, version 1.0 2008-01-01 2008-06-01 geonetwork.thesaurus.external.theme.httpinspireeceuropaeutheme-theme aspects sociaux, population santé humaine GEMET themes 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet-theme santé sécurité GEMET 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet Reporting INSPIRE Mots-clés InfraSIG 2022-10-03 2022-10-03 geonetwork.thesaurus.external.theme.infraSIG Human health and safety HH health inspire WMS View validationtest Service d’accès aux cartes Classification of spatial data services 2008-01-01 2008-12-03 geonetwork.thesaurus.external.theme.httpinspireeceuropaeumetadatacodelistSpatialDataServiceCategory-SpatialDataServiceCategory Régional Champ géographique 2019-01-01 2019-05-22 geonetwork.thesaurus.external.theme.httpinspireeceuropaeumetadatacodelistSpatialScope-SpatialScope No limitations to public access Conditions d'utilisation spécifiques Les conditions d'utilisation du service sont régies par les conditions d’accès et d’utilisation des services web géographiques de visualisation du Service public de Wallonie. view Service public de Wallonie (SPW) helpdesk.carto@spw.wallonie.be https://geoservices.test.wallonie.be/geoserver/inspire_hh/ows?service=WMS&version=1.3.0&request=GetCapabilities OGC:WMS INSPIRE Santé et sécurité des personnes - Service de visualisation WMS Adresse de connexion au service de visualisation WMS-Inspire des couches de données du thème "Santé et sécurité des personnes". Service Règlement (CE) n o 976/2009 de la Commission du 19 octobre 2009 portant modalités d’application de la directive 2007/2/CE du Parlement européen et du Conseil en ce qui concerne les services en réseau 2009-10-19 Voir la spécification référencée true RÈGLEMENT (UE) N o 1089/2010 DE LA COMMISSION du 23 novembre 2010 portant modalités d'application de la directive 2007/2/CE du Parlement européen et du Conseil en ce qui concerne l'interopérabilité des séries et des services de données géographiques 2010-12-08 Voir la spécification référencée true ================================================ FILE: tests/functionaltests/suites/iso19115p3/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/iso19115p3/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true profiles: - iso19115p3 logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/iso19115p3/data/records.db table: records ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/get_DescribeRecord.xml ================================================ Wrapper namespace to support Catalog Service implementations class of information to which the referencing entity applies links a given operationName (mandatory attribute of SV_OperationMetadata) with a data set identified by an 'identifier' scoped identifier of the resource in the context of the given service instance NOTE: name of the resources (i.e. dataset) as it is used by a service instance (e.g. layer name or featureTypeName). reference to the dataset on which the service operates class of information to which the referencing entity applies Operation Chain Information the name, as used by the service for this chain a narrative explanation of the services in the chain and resulting output describes the signature of one and only one method provided by the service a unique identifier for this interface distributed computing platforms on which the operation has been implemented free text description of the intent of the operation and the results of the operation the name used to invoke this interface within the context of the DCP. The name is identical for all DCPs. handle for accessing the service interface parameter information the name, as used by the service for this parameter indication if the parameter is an input to the service, an output or both a narrative explanation of the role of the parameter indication if the parameter is required indication if more than one value of the parameter may be provided class of information to which the referencing entity applies class of information to which the referencing entity applies the parameter is an input parameter to the service instance the parameter is an output parameter to the service instance the parameter is both an input and output parameter to the service instance identification of capabilities which a service provider makes available to a service user through a set of interfaces that define a behaviour - See ISO 19119 for further information a service type name, E.G. 'discovery', 'view', 'download', 'transformation', or 'invoke' provide for searching based on the version of serviceType. For example, we may only be interested in OGC Catalogue V1.1 services. If version is maintained as a separate attribute, users can easily search for all services of a type regardless of the version information about the availability of the service, including, 'fees' 'planned' 'available date and time' 'ordering instructions' 'turnaround' type of coupling between service and associated data (if exists) further description of the data coupling in the case of tightly coupled services provides a reference to the dataset on which the service operates ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/get_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record mdb:MD_Metadata DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://standards.iso.org/iso/19115/-3/mdb/2.0 http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record mdb:MD_Metadata mdb:AccessConstraints mdb:Bands mdb:Classification mdb:CloudCover mdb:ConditionApplyingToAccessAndUse mdb:Contributor mdb:Creator mdb:Degree mdb:Instrument mdb:Lineage mdb:OtherConstraints mdb:Platform mdb:Publisher mdb:Relation mdb:ResponsiblePartyRole mdb:SensorType mdb:SpecificationDate mdb:SpecificationDateType mdb:SpecificationTitle csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox mdb:Abstract mdb:AlternateTitle mdb:AnyText mdb:BoundingBox mdb:CRS mdb:CouplingType mdb:CreationDate mdb:Denominator mdb:DistanceUOM mdb:DistanceValue mdb:Edition mdb:Format mdb:GeographicDescriptionCode mdb:HasSecurityConstraints mdb:Identifier mdb:KeywordType mdb:Language mdb:Modified mdb:OperatesOn mdb:OperatesOnIdentifier mdb:OperatesOnName mdb:Operation mdb:OrganisationName mdb:ParentIdentifier mdb:PublicationDate mdb:ResourceLanguage mdb:RevisionDate mdb:ServiceType mdb:ServiceTypeVersion mdb:Subject mdb:TempExtent_begin mdb:TempExtent_end mdb:Title mdb:TopicCategory mdb:Type mdb:VertExtentMax mdb:VertExtentMin brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://standards.iso.org/iso/19115/-3/mdb/2.0 http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_DescribeRecord.xml ================================================ Wrapper namespace to support Catalog Service implementations class of information to which the referencing entity applies links a given operationName (mandatory attribute of SV_OperationMetadata) with a data set identified by an 'identifier' scoped identifier of the resource in the context of the given service instance NOTE: name of the resources (i.e. dataset) as it is used by a service instance (e.g. layer name or featureTypeName). reference to the dataset on which the service operates class of information to which the referencing entity applies Operation Chain Information the name, as used by the service for this chain a narrative explanation of the services in the chain and resulting output describes the signature of one and only one method provided by the service a unique identifier for this interface distributed computing platforms on which the operation has been implemented free text description of the intent of the operation and the results of the operation the name used to invoke this interface within the context of the DCP. The name is identical for all DCPs. handle for accessing the service interface parameter information the name, as used by the service for this parameter indication if the parameter is an input to the service, an output or both a narrative explanation of the role of the parameter indication if the parameter is required indication if more than one value of the parameter may be provided class of information to which the referencing entity applies class of information to which the referencing entity applies the parameter is an input parameter to the service instance the parameter is an output parameter to the service instance the parameter is both an input and output parameter to the service instance identification of capabilities which a service provider makes available to a service user through a set of interfaces that define a behaviour - See ISO 19119 for further information a service type name, E.G. 'discovery', 'view', 'download', 'transformation', or 'invoke' provide for searching based on the version of serviceType. For example, we may only be interested in OGC Catalogue V1.1 services. If version is maintained as a separate attribute, users can easily search for all services of a type regardless of the version information about the availability of the service, including, 'fees' 'planned' 'available date and time' 'ordering instructions' 'turnaround' type of coupling between service and associated data (if exists) further description of the data coupling in the case of tightly coupled services provides a reference to the dataset on which the service operates ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record mdb:MD_Metadata DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://standards.iso.org/iso/19115/-3/mdb/2.0 http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record mdb:MD_Metadata mdb:AccessConstraints mdb:Bands mdb:Classification mdb:CloudCover mdb:ConditionApplyingToAccessAndUse mdb:Contributor mdb:Creator mdb:Degree mdb:Instrument mdb:Lineage mdb:OtherConstraints mdb:Platform mdb:Publisher mdb:Relation mdb:ResponsiblePartyRole mdb:SensorType mdb:SpecificationDate mdb:SpecificationDateType mdb:SpecificationTitle csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox mdb:Abstract mdb:AlternateTitle mdb:AnyText mdb:BoundingBox mdb:CRS mdb:CouplingType mdb:CreationDate mdb:Denominator mdb:DistanceUOM mdb:DistanceValue mdb:Edition mdb:Format mdb:GeographicDescriptionCode mdb:HasSecurityConstraints mdb:Identifier mdb:KeywordType mdb:Language mdb:Modified mdb:OperatesOn mdb:OperatesOnIdentifier mdb:OperatesOnName mdb:Operation mdb:OrganisationName mdb:ParentIdentifier mdb:PublicationDate mdb:ResourceLanguage mdb:RevisionDate mdb:ServiceType mdb:ServiceTypeVersion mdb:Subject mdb:TempExtent_begin mdb:TempExtent_end mdb:Title mdb:TopicCategory mdb:Type mdb:VertExtentMax mdb:VertExtentMin brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://standards.iso.org/iso/19115/-3/mdb/2.0 http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetDomain-property.xml ================================================ mdb:TopicCategory geoscientificInformation ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecordById-ISO19139-full.xml ================================================ 09a7c1d4c97ccdd7e34306deb91320ab95d51bb8 dataset CSIRO Peter Warren Software Engineer +61 2 9490 8802 voice 11 Julius Ave North Ryde CSIRO 2113 Australia 2018-02-08T11:04:47 creation 2018-02-08T11:04:47 revision ISO 19115-1:2014 ProvinceFullExtent features ProvinceFullExtent geoscientificInformation 106.57 171.88 -49.86 -3.63 https://nvclwebservices.csiro.au/geoserver/wms?SERVICE=WMS& OGC:WMS-1.1.1-http-get-map gml:ProvinceFullExtent ProvinceFullExtent https://nvclwebservices.csiro.au/geoserver/wms?request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=gml%3AProvinceFullExtent image/png Default Polygon (LegendURL) ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecordById-brief.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 143.0 144.0 -39.4 -38.4 -400.0 300.0 http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecordById-full-dc.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 Victoria Otway Basin Torquay Basin 3D Geological Models WWW:LINK-1.0-http--link http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 http://geomodels.auscope.org/model/otway 2022-11-03T06:16:21 A 3D model of the Otway and Torquay basins has been produced at 1:250 000 scale as part of GeoScience Victorias state-wide 3D geological model. To date there has been a “knowledge gap” in the transition between the basement and basin environments. This regional scale integration of the basement and basin models addresses this gap and provides a regional framework within which more detailed work can be carried out in the future. The construction and integration of the basin model has involved both the interpretation and building of new faults and stratigraphic surfaces, as well as utilising existing stratigraphic surfaces and structural interpretations from previous studies, predominantly the Otway Basin HSA SEEBASE project by FrOG Tech (Jorand et. al., 2010). Earth Resources Victoria eng license -39.4 143.0 -38.4 144.0 ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecordById-full.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 urn:uuid Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au Anthony Hurst Executive Director, Earth Resources Policy and Programs 2022-11-03T06:16:21 2022-11-03T06:17:02 ISO 19115-3 http://portal.auscope.org/geonetwork/srv/api/records/5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 2010-01-01 https://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 Reference AuScope Level 2, 700 Swanston Street Carlton Victoria 3053 Australia info@auscope.org.au https://ror.org/04s1m4564 ROR Research Organization Registry (ROR) Entry Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au P.B. SKLADZIEN C. Jorand A. Krassay L. Hall A 3D model of the Otway and Torquay basins has been produced at 1:250 000 scale as part of GeoScience Victorias state-wide 3D geological model. To date there has been a “knowledge gap” in the transition between the basement and basin environments. This regional scale integration of the basement and basin models addresses this gap and provides a regional framework within which more detailed work can be carried out in the future. The construction and integration of the basin model has involved both the interpretation and building of new faults and stratigraphic surfaces, as well as utilising existing stratigraphic surfaces and structural interpretations from previous studies, predominantly the Otway Basin HSA SEEBASE project by FrOG Tech (Jorand et. al., 2010). 143.00 144.00 -39.40 -38.40 -400 300 Victoria Otway Basin Torquay Basin 3D Geological Models https://creativecommons.org/licenses/by/4.0/ http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecordById-srv-brief.xml ================================================ 1714cd1e-6685-4dea-a6f4-b51612a15ed0 service INSPIRE - Santé et sécurité des personnes en Wallonie (BE) - Service de visualisation WMS Industrie et services Société et activités Santé et sécurité des personnes aspects sociaux population santé humaine santé sécurité Reporting INSPIRE Human health and safety HH health inspire WMS View validationtest Service d’accès aux cartes Régional 2.75 6.51 49.45 50.85 2018-03-01 publication https://geoservices.test.wallonie.be/geoserver/inspire_hh/ows?service=WMS&version=1.3.0&request=GetCapabilities OGC:WMS INSPIRE Santé et sécurité des personnes - Service de visualisation WMS Adresse de connexion au service de visualisation WMS-Inspire des couches de données du thème "Santé et sécurité des personnes". https://metawal.wallonie.be/geonetwork/inspire/api/records/1714cd1e-6685-4dea-a6f4-b51612a15ed0/attachments/wms_inspire_20190430.png WWW:LINK-1.0-http--image-thumbnail preview Web image thumbnail (URL) ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-all-csw-output.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 urn:uuid Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au Anthony Hurst Executive Director, Earth Resources Policy and Programs 2022-11-03T06:16:21 2022-11-03T06:17:02 ISO 19115-3 http://portal.auscope.org/geonetwork/srv/api/records/5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 2010-01-01 https://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 Reference AuScope Level 2, 700 Swanston Street Carlton Victoria 3053 Australia info@auscope.org.au https://ror.org/04s1m4564 ROR Research Organization Registry (ROR) Entry Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au P.B. SKLADZIEN C. Jorand A. Krassay L. Hall A 3D model of the Otway and Torquay basins has been produced at 1:250 000 scale as part of GeoScience Victorias state-wide 3D geological model. To date there has been a “knowledge gap” in the transition between the basement and basin environments. This regional scale integration of the basement and basin models addresses this gap and provides a regional framework within which more detailed work can be carried out in the future. The construction and integration of the basin model has involved both the interpretation and building of new faults and stratigraphic surfaces, as well as utilising existing stratigraphic surfaces and structural interpretations from previous studies, predominantly the Otway Basin HSA SEEBASE project by FrOG Tech (Jorand et. al., 2010). 143.00 144.00 -39.40 -38.40 -400 300 Victoria Otway Basin Torquay Basin 3D Geological Models https://creativecommons.org/licenses/by/4.0/ http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model 09a7c1d4c97ccdd7e34306deb91320ab95d51bb8 dataset CSIRO Peter Warren Software Engineer +61 2 9490 8802 voice 11 Julius Ave North Ryde CSIRO 2113 Australia 2018-02-08T11:04:47 creation 2018-02-08T11:04:47 revision ISO 19115-1:2014 ProvinceFullExtent features ProvinceFullExtent geoscientificInformation 106.57 171.88 -49.86 -3.63 https://nvclwebservices.csiro.au/geoserver/wms?SERVICE=WMS& OGC:WMS-1.1.1-http-get-map gml:ProvinceFullExtent ProvinceFullExtent https://nvclwebservices.csiro.au/geoserver/wms?request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=gml%3AProvinceFullExtent image/png Default Polygon (LegendURL) 74f81503-8d39-4ec8-a49a-c76e0cd74946 urn:uuid Collection de données thématiques Direction des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines) +32 (0)81/335923 veronique.willame@spw.wallonie.be Véronique Willame 2023-08-08T07:34:11.366Z 2019-04-02T12:32:13 ISO 19115 2003/Cor 1:2006 https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946 EPSG:31370 Belge 1972 / Belgian Lambert 72 (EPSG:31370) Protection des captages - Série PROTECT_CAPT 2000-01-01 2023-07-31 2022-11-08 PROTECT_CAPT BE.SPW.INFRASIG.GINET 74f81503-8d39-4ec8-a49a-c76e0cd74946 http://geodata.wallonie.be/id/ Cette collection de données comprend les zones de surveillance arrêtées, de prévention forfaitaires et de prévention arrêtées ou à l'enquête publique autour des captages. Cet ensemble de classes d'entités est constitué de trois couches distinctes. - Les zones de surveillance arrêtées (PROTECT_CAPT__ZONE_III_ARRETEE) - les zones de prévention arrêtées (PROTECT_CAPT__ZONE_II_ARRETEE) - les zones de prévention forfaitaires (PROTECT_CAPT__ZONE_II_FORFAIT) La classe d'entités "zones de surveillance arrêtées" contient l'ensemble des zones de surveillance délimitées autour de certaines zones de prévention (approuvées par arrêté ministériel) des captages d'eau de distribution publique d'eau potable les plus importants de par les volumes exploités. Actuellement, on en compte cinq sur toute la Wallonie. Ces zones de surveillance III sont délimitées par le bassin d'alimentation et le bassin hydrogéologique et fournies à la Directions des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines) sur document papier par le producteur d'eau publique qui a réalisé l'étude. La classe d'entités "zones de prévention arrêtées" contient l'ensemble des zones de prévention (autour des captages d'eau souterraine) rapprochées (IIa) et éloignées (IIb) approuvées par arrêté ministériel, à l'enquête publique (en cours ou terminée) ou à l'instruction. Cette couche couvre toute la Wallonie. La classe d'entités "zones de prévention forfaitaires" autour des captages contient l'ensemble des zones de prévention forfaitaires (ou théoriques), autour des captages d'eau souterraine de distribution publique. Ces zones de prévention sont provisoires. Elles sont de forme circulaire et seront définies et officialisées, dans le futur, après une étude de délimitation par le producteur d'eau qui l'exploite le captage. Les diamètres des zones de prévention forfaitaires rapprochées (IIa) et éloignées (IIb) sont fonction de la nature du terrain. La méthode des distances théoriques tient compte essentiellement de la perméabilité des terrains: zone de prise d'eau (10 m minimum autour des installations), zone de prévention rapprochée IIa (35 m autour des installations de la prise d'eau), zone de prévention IIb (100 m dans les aquifères sableux, 500 m dans les aquifères graveleux et 1000 m dans les aquifères fissurés et karstiques autour de la zone de prévention rapprochée). Cette couche couvre toute la Wallonie. Suite au décalage entre la mise à jour des Zones de prévention forfaitaires autour des captages (décembre 2018) et des Zones de prévention arrêtée ou à l'enquête publique autour des captages, mises à jour en mai 2020, et lorsqu’une zone arrêtée est présente pour un captage, c’est celle-ci qui prime au détriment de la zone forfaitaire. La mise à jour des Zones de prévention forfaitaires autour des captages est prévue début juillet 2020. Helpdesk carto du SPW (SPW - Secrétariat général - SPW Digital - Département Données transversales - Gestion et valorisation de la donnée) helpdesk.carto@spw.wallonie.be Direction des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines) +32 (0)81/335923 veronique.willame@spw.wallonie.be Véronique Willame Service public de Wallonie (SPW) https://geoportail.wallonie.be WWW:LINK Géoportail de la Wallonie Géoportail de la Wallonie 10000 geoscientificInformation inlandWaters Région wallonne 2.75 6.50 49.45 50.85 https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT.png protect_capt_pic png https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT_s.png protect_capt_pic_small png Sol et sous-sol Eau Thèmes du géoportail wallon 2014-01-01 2014-06-26 geonetwork.thesaurus.external.theme.Themes_geoportail_wallon_hierarchy eau politique environnementale GEMET themes 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet-theme eau potable surveillance de l'environnement surveillance de l'eau eau de surface captage eaux souterraines zone de captage d'eau potable zone protégée de captage d'eau protection de zone de captage de l'eau captage d'eau GEMET 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet DGO3_BDREF WalOnMap Extraction_DIG DGO3_CIGALE Reporting INSPIRENO Open Data BDInfraSIGNO PanierTelechargementGeoportail Mots-clés InfraSIG 2022-10-03 2022-10-03 geonetwork.thesaurus.external.theme.infraSIG zone forfaitaire prévention rapprochée prévention éloignée prévention IIa IIb surveillance III Les conditions générales d'accès s’appliquent. Les conditions générales d'utilisation s'appliquent. Modèle de données http://environnement.wallonie.be/cartosig/Inventaire_Donnees/Modeles_SIG3/PROTECT_CAPT.pdf WWW:LINK application/pdf Modèle de données (document pdf) ESRI Shapefile (.shp) - ESRI File Geodatabase (.fgdb) 10.x Service public de Wallonie (SPW) helpdesk.carto@spw.wallonie.be Cette ressource est une collection de données. En la commandant, l'ensemble des géodonnées constitutives de cette collection vous sera automatiquement fourni. Les instructions pour obtenir une copie physique d’une donnée sont détaillées sur https://geoportail.wallonie.be/telecharger. Cellule SIG de la DGARNE (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Étude du milieu naturel et agricole - Direction de la Coordination des Données) sig.dgarne@spw.wallonie.be https://geoportail.wallonie.be/walonmap/#ADU=https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer WWW:LINK Application WalOnMap - Toute la Wallonie à la carte Application cartographique du Geoportail (WalOnMap) qui permet de découvrir les données géographiques de la Wallonie. http://geoapps.wallonie.be/Cigale/Public/#CTX=EAUX_SOUT WWW:LINK Protection des eaux souteraines (CIGALE) - Application Application de consultation des principales données cartographiques du SPW Agriculture, Ressources naturelles et Environnements https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer ESRI:REST Service de visualisation ESRI-REST Ce service ESRI-REST permet de visualiser le jeu de données "Protection des captages" https://geoservices.wallonie.be/arcgis/services/EAU/PROTECT_CAPT/MapServer/WMSServer?request=GetCapabilities&service=WMS OGC:WMS Service de visualisation WMS Ce service WMS permet de visualiser le jeu de données "Protection des captages" http://environnement.wallonie.be/de/eso/atlas/index.htm#4.1a WWW:LINK Site web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b. Zones de protection définies par arrêté ministériel Pages web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b Zones de protection définies par arrêté ministériel Pour les zones arrêtées (les zones de surveillance arrêtées et les zones de prévention arrêtées ou à l'enquête publique), les entités sont numérisées sur base des plans papier des producteurs d'eau qui réalisent l'étude de délimitation des zones de prévention. Le dossier est déposé au centre extérieur de la DESO pour réception, vérification, officialisation par arrêté ministériel et publication au Moniteur belge. Chaque zone de prévention est numérisée par digitalisation (à la Direction des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines)) sur base de plans papier sur fond IGN et sur Fond cadastral. Pour les zones forfaitaires, les entités de cette couche sont des zones de prévention circulaires, générées autour de la position exacte de chacun des captages d'eau de distribution publique d'eau potable (qui n'ont pas encore de zones de prévention approuvée par arrêté ministériel), en créant un buffer de diamètres différents en fonction de la nature de l'aquifère et de la zone rapprochée ou éloignée. Collection de données thématiques 1714cd1e-6685-4dea-a6f4-b51612a15ed0 urn:uuid Service Gestion et valorisation de la donnée (SPW - Secrétariat général - SPW Digital - Département Données transversales - Gestion et valorisation de la donnée) helpdesk.carto@spw.wallonie.be 2023-12-11T13:33:59.133Z 2019-04-02T12:32:33 ISO 19119 2005/Amd.1:2008 https://metawal.wallonie.be/geonetwork/srv/api/records/1714cd1e-6685-4dea-a6f4-b51612a15ed0 EPSG:31370 Belge 1972 / Belgian Lambert 72 (EPSG:31370) EPSG:4326 WGS 84 (EPSG:4326) EPSG:3857 WGS 84 / Pseudo-Mercator (EPSG:3857) EPSG:3035 ETRS89 / LAEA Europe (EPSG:3035) EPSG:4258 ETRS89 (EPSG:4258) EPSG:3812 ETRS89 / Belgian Lambert 2008 (EPSG:3812) INSPIRE - Santé et sécurité des personnes en Wallonie (BE) - Service de visualisation WMS 2018-03-01 1714cd1e-6685-4dea-a6f4-b51612a15ed0 http://geodata.wallonie.be/id/ Ce service de visualisation WMS INSPIRE permet de consulter les couches de données du thème "Santé et sécurité des personnes" au sein du territoire wallon (Belgique). Ce service de visualisation WMS est fourni par le Service public de Wallonie (SPW) et expose les couches de données géographiques constitutives du thème "Santé et sécurité des personnes" de la Directive (Annexe 3.5) sur l'ensemble du territoire wallon. Ce service permet donc de visualiser les couches de données sélectionnées comme faisant partie du thème "Bâtiments". Ces couches de données sont présentées "telles quelles", c'est-à-dire dans leur modèle de données initial, non conforme aux spécifications de données définies par la Directive. Les couches de données seront progressivement adaptées aux modèles de donnée commun INSPIRE suivant les spécifications du thème. Le service de visualisation est conforme aux spécifications de la Directive INSPIRE en la matière. Helpdesk carto du SPW (SPW - Secrétariat général - SPW Digital - Département de la Géomatique - Direction de l'Intégration des géodonnées) helpdesk.carto@spw.wallonie.be Gestion et valorisation de la donnée (SPW - Secrétariat général - SPW Digital - Département Données transversales - Gestion et valorisation de la donnée) helpdesk.carto@spw.wallonie.be Service public de Wallonie (SPW) helpdesk.carto@spw.wallonie.be https://geoportail.wallonie.be WWW:LINK Géoportail de la Wallonie Géoportail de la Wallonie Région wallonne 2.75 6.51 49.45 50.85 https://metawal.wallonie.be/geonetwork/inspire/api/records/1714cd1e-6685-4dea-a6f4-b51612a15ed0/attachments/wms_inspire_20190430.png Industrie et services Société et activités Thèmes du géoportail wallon 2014-01-01 2014-06-26 geonetwork.thesaurus.external.theme.Themes_geoportail_wallon_hierarchy Santé et sécurité des personnes GEMET - INSPIRE themes, version 1.0 2008-01-01 2008-06-01 geonetwork.thesaurus.external.theme.httpinspireeceuropaeutheme-theme aspects sociaux, population santé humaine GEMET themes 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet-theme santé sécurité GEMET 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet Reporting INSPIRE Mots-clés InfraSIG 2022-10-03 2022-10-03 geonetwork.thesaurus.external.theme.infraSIG Human health and safety HH health inspire WMS View validationtest Service d’accès aux cartes Classification of spatial data services 2008-01-01 2008-12-03 geonetwork.thesaurus.external.theme.httpinspireeceuropaeumetadatacodelistSpatialDataServiceCategory-SpatialDataServiceCategory Régional Champ géographique 2019-01-01 2019-05-22 geonetwork.thesaurus.external.theme.httpinspireeceuropaeumetadatacodelistSpatialScope-SpatialScope No limitations to public access Conditions d'utilisation spécifiques Les conditions d'utilisation du service sont régies par les conditions d’accès et d’utilisation des services web géographiques de visualisation du Service public de Wallonie. view Service public de Wallonie (SPW) helpdesk.carto@spw.wallonie.be https://geoservices.test.wallonie.be/geoserver/inspire_hh/ows?service=WMS&version=1.3.0&request=GetCapabilities OGC:WMS INSPIRE Santé et sécurité des personnes - Service de visualisation WMS Adresse de connexion au service de visualisation WMS-Inspire des couches de données du thème "Santé et sécurité des personnes". Service Règlement (CE) n o 976/2009 de la Commission du 19 octobre 2009 portant modalités d’application de la directive 2007/2/CE du Parlement européen et du Conseil en ce qui concerne les services en réseau 2009-10-19 Voir la spécification référencée true RÈGLEMENT (UE) N o 1089/2010 DE LA COMMISSION du 23 novembre 2010 portant modalités d'application de la directive 2007/2/CE du Parlement européen et du Conseil en ce qui concerne l'interopérabilité des séries et des services de données géographiques 2010-12-08 Voir la spécification référencée true ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-all.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 urn:uuid Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au Anthony Hurst Executive Director, Earth Resources Policy and Programs 2022-11-03T06:16:21 2022-11-03T06:17:02 ISO 19115-3 http://portal.auscope.org/geonetwork/srv/api/records/5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 2010-01-01 https://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 Reference AuScope Level 2, 700 Swanston Street Carlton Victoria 3053 Australia info@auscope.org.au https://ror.org/04s1m4564 ROR Research Organization Registry (ROR) Entry Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au P.B. SKLADZIEN C. Jorand A. Krassay L. Hall A 3D model of the Otway and Torquay basins has been produced at 1:250 000 scale as part of GeoScience Victorias state-wide 3D geological model. To date there has been a “knowledge gap” in the transition between the basement and basin environments. This regional scale integration of the basement and basin models addresses this gap and provides a regional framework within which more detailed work can be carried out in the future. The construction and integration of the basin model has involved both the interpretation and building of new faults and stratigraphic surfaces, as well as utilising existing stratigraphic surfaces and structural interpretations from previous studies, predominantly the Otway Basin HSA SEEBASE project by FrOG Tech (Jorand et. al., 2010). 143.00 144.00 -39.40 -38.40 -400 300 Victoria Otway Basin Torquay Basin 3D Geological Models https://creativecommons.org/licenses/by/4.0/ http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model 09a7c1d4c97ccdd7e34306deb91320ab95d51bb8 dataset CSIRO Peter Warren Software Engineer +61 2 9490 8802 voice 11 Julius Ave North Ryde CSIRO 2113 Australia 2018-02-08T11:04:47 creation 2018-02-08T11:04:47 revision ISO 19115-1:2014 ProvinceFullExtent features ProvinceFullExtent geoscientificInformation 106.57 171.88 -49.86 -3.63 https://nvclwebservices.csiro.au/geoserver/wms?SERVICE=WMS& OGC:WMS-1.1.1-http-get-map gml:ProvinceFullExtent ProvinceFullExtent https://nvclwebservices.csiro.au/geoserver/wms?request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=gml%3AProvinceFullExtent image/png Default Polygon (LegendURL) 74f81503-8d39-4ec8-a49a-c76e0cd74946 urn:uuid Collection de données thématiques Direction des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines) +32 (0)81/335923 veronique.willame@spw.wallonie.be Véronique Willame 2023-08-08T07:34:11.366Z 2019-04-02T12:32:13 ISO 19115 2003/Cor 1:2006 https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946 EPSG:31370 Belge 1972 / Belgian Lambert 72 (EPSG:31370) Protection des captages - Série PROTECT_CAPT 2000-01-01 2023-07-31 2022-11-08 PROTECT_CAPT BE.SPW.INFRASIG.GINET 74f81503-8d39-4ec8-a49a-c76e0cd74946 http://geodata.wallonie.be/id/ Cette collection de données comprend les zones de surveillance arrêtées, de prévention forfaitaires et de prévention arrêtées ou à l'enquête publique autour des captages. Cet ensemble de classes d'entités est constitué de trois couches distinctes. - Les zones de surveillance arrêtées (PROTECT_CAPT__ZONE_III_ARRETEE) - les zones de prévention arrêtées (PROTECT_CAPT__ZONE_II_ARRETEE) - les zones de prévention forfaitaires (PROTECT_CAPT__ZONE_II_FORFAIT) La classe d'entités "zones de surveillance arrêtées" contient l'ensemble des zones de surveillance délimitées autour de certaines zones de prévention (approuvées par arrêté ministériel) des captages d'eau de distribution publique d'eau potable les plus importants de par les volumes exploités. Actuellement, on en compte cinq sur toute la Wallonie. Ces zones de surveillance III sont délimitées par le bassin d'alimentation et le bassin hydrogéologique et fournies à la Directions des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines) sur document papier par le producteur d'eau publique qui a réalisé l'étude. La classe d'entités "zones de prévention arrêtées" contient l'ensemble des zones de prévention (autour des captages d'eau souterraine) rapprochées (IIa) et éloignées (IIb) approuvées par arrêté ministériel, à l'enquête publique (en cours ou terminée) ou à l'instruction. Cette couche couvre toute la Wallonie. La classe d'entités "zones de prévention forfaitaires" autour des captages contient l'ensemble des zones de prévention forfaitaires (ou théoriques), autour des captages d'eau souterraine de distribution publique. Ces zones de prévention sont provisoires. Elles sont de forme circulaire et seront définies et officialisées, dans le futur, après une étude de délimitation par le producteur d'eau qui l'exploite le captage. Les diamètres des zones de prévention forfaitaires rapprochées (IIa) et éloignées (IIb) sont fonction de la nature du terrain. La méthode des distances théoriques tient compte essentiellement de la perméabilité des terrains: zone de prise d'eau (10 m minimum autour des installations), zone de prévention rapprochée IIa (35 m autour des installations de la prise d'eau), zone de prévention IIb (100 m dans les aquifères sableux, 500 m dans les aquifères graveleux et 1000 m dans les aquifères fissurés et karstiques autour de la zone de prévention rapprochée). Cette couche couvre toute la Wallonie. Suite au décalage entre la mise à jour des Zones de prévention forfaitaires autour des captages (décembre 2018) et des Zones de prévention arrêtée ou à l'enquête publique autour des captages, mises à jour en mai 2020, et lorsqu’une zone arrêtée est présente pour un captage, c’est celle-ci qui prime au détriment de la zone forfaitaire. La mise à jour des Zones de prévention forfaitaires autour des captages est prévue début juillet 2020. Helpdesk carto du SPW (SPW - Secrétariat général - SPW Digital - Département Données transversales - Gestion et valorisation de la donnée) helpdesk.carto@spw.wallonie.be Direction des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines) +32 (0)81/335923 veronique.willame@spw.wallonie.be Véronique Willame Service public de Wallonie (SPW) https://geoportail.wallonie.be WWW:LINK Géoportail de la Wallonie Géoportail de la Wallonie 10000 geoscientificInformation inlandWaters Région wallonne 2.75 6.50 49.45 50.85 https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT.png protect_capt_pic png https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT_s.png protect_capt_pic_small png Sol et sous-sol Eau Thèmes du géoportail wallon 2014-01-01 2014-06-26 geonetwork.thesaurus.external.theme.Themes_geoportail_wallon_hierarchy eau politique environnementale GEMET themes 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet-theme eau potable surveillance de l'environnement surveillance de l'eau eau de surface captage eaux souterraines zone de captage d'eau potable zone protégée de captage d'eau protection de zone de captage de l'eau captage d'eau GEMET 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet DGO3_BDREF WalOnMap Extraction_DIG DGO3_CIGALE Reporting INSPIRENO Open Data BDInfraSIGNO PanierTelechargementGeoportail Mots-clés InfraSIG 2022-10-03 2022-10-03 geonetwork.thesaurus.external.theme.infraSIG zone forfaitaire prévention rapprochée prévention éloignée prévention IIa IIb surveillance III Les conditions générales d'accès s’appliquent. Les conditions générales d'utilisation s'appliquent. Modèle de données http://environnement.wallonie.be/cartosig/Inventaire_Donnees/Modeles_SIG3/PROTECT_CAPT.pdf WWW:LINK application/pdf Modèle de données (document pdf) ESRI Shapefile (.shp) - ESRI File Geodatabase (.fgdb) 10.x Service public de Wallonie (SPW) helpdesk.carto@spw.wallonie.be Cette ressource est une collection de données. En la commandant, l'ensemble des géodonnées constitutives de cette collection vous sera automatiquement fourni. Les instructions pour obtenir une copie physique d’une donnée sont détaillées sur https://geoportail.wallonie.be/telecharger. Cellule SIG de la DGARNE (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Étude du milieu naturel et agricole - Direction de la Coordination des Données) sig.dgarne@spw.wallonie.be https://geoportail.wallonie.be/walonmap/#ADU=https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer WWW:LINK Application WalOnMap - Toute la Wallonie à la carte Application cartographique du Geoportail (WalOnMap) qui permet de découvrir les données géographiques de la Wallonie. http://geoapps.wallonie.be/Cigale/Public/#CTX=EAUX_SOUT WWW:LINK Protection des eaux souteraines (CIGALE) - Application Application de consultation des principales données cartographiques du SPW Agriculture, Ressources naturelles et Environnements https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer ESRI:REST Service de visualisation ESRI-REST Ce service ESRI-REST permet de visualiser le jeu de données "Protection des captages" https://geoservices.wallonie.be/arcgis/services/EAU/PROTECT_CAPT/MapServer/WMSServer?request=GetCapabilities&service=WMS OGC:WMS Service de visualisation WMS Ce service WMS permet de visualiser le jeu de données "Protection des captages" http://environnement.wallonie.be/de/eso/atlas/index.htm#4.1a WWW:LINK Site web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b. Zones de protection définies par arrêté ministériel Pages web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b Zones de protection définies par arrêté ministériel Pour les zones arrêtées (les zones de surveillance arrêtées et les zones de prévention arrêtées ou à l'enquête publique), les entités sont numérisées sur base des plans papier des producteurs d'eau qui réalisent l'étude de délimitation des zones de prévention. Le dossier est déposé au centre extérieur de la DESO pour réception, vérification, officialisation par arrêté ministériel et publication au Moniteur belge. Chaque zone de prévention est numérisée par digitalisation (à la Direction des Eaux souterraines (SPW - Agriculture, Ressources naturelles et Environnement - Département de l'Environnement et de l'Eau - Direction des Eaux souterraines)) sur base de plans papier sur fond IGN et sur Fond cadastral. Pour les zones forfaitaires, les entités de cette couche sont des zones de prévention circulaires, générées autour de la position exacte de chacun des captages d'eau de distribution publique d'eau potable (qui n'ont pas encore de zones de prévention approuvée par arrêté ministériel), en créant un buffer de diamètres différents en fonction de la nature de l'aquifère et de la zone rapprochée ou éloignée. Collection de données thématiques 1714cd1e-6685-4dea-a6f4-b51612a15ed0 urn:uuid Service Gestion et valorisation de la donnée (SPW - Secrétariat général - SPW Digital - Département Données transversales - Gestion et valorisation de la donnée) helpdesk.carto@spw.wallonie.be 2023-12-11T13:33:59.133Z 2019-04-02T12:32:33 ISO 19119 2005/Amd.1:2008 https://metawal.wallonie.be/geonetwork/srv/api/records/1714cd1e-6685-4dea-a6f4-b51612a15ed0 EPSG:31370 Belge 1972 / Belgian Lambert 72 (EPSG:31370) EPSG:4326 WGS 84 (EPSG:4326) EPSG:3857 WGS 84 / Pseudo-Mercator (EPSG:3857) EPSG:3035 ETRS89 / LAEA Europe (EPSG:3035) EPSG:4258 ETRS89 (EPSG:4258) EPSG:3812 ETRS89 / Belgian Lambert 2008 (EPSG:3812) INSPIRE - Santé et sécurité des personnes en Wallonie (BE) - Service de visualisation WMS 2018-03-01 1714cd1e-6685-4dea-a6f4-b51612a15ed0 http://geodata.wallonie.be/id/ Ce service de visualisation WMS INSPIRE permet de consulter les couches de données du thème "Santé et sécurité des personnes" au sein du territoire wallon (Belgique). Ce service de visualisation WMS est fourni par le Service public de Wallonie (SPW) et expose les couches de données géographiques constitutives du thème "Santé et sécurité des personnes" de la Directive (Annexe 3.5) sur l'ensemble du territoire wallon. Ce service permet donc de visualiser les couches de données sélectionnées comme faisant partie du thème "Bâtiments". Ces couches de données sont présentées "telles quelles", c'est-à-dire dans leur modèle de données initial, non conforme aux spécifications de données définies par la Directive. Les couches de données seront progressivement adaptées aux modèles de donnée commun INSPIRE suivant les spécifications du thème. Le service de visualisation est conforme aux spécifications de la Directive INSPIRE en la matière. Helpdesk carto du SPW (SPW - Secrétariat général - SPW Digital - Département de la Géomatique - Direction de l'Intégration des géodonnées) helpdesk.carto@spw.wallonie.be Gestion et valorisation de la donnée (SPW - Secrétariat général - SPW Digital - Département Données transversales - Gestion et valorisation de la donnée) helpdesk.carto@spw.wallonie.be Service public de Wallonie (SPW) helpdesk.carto@spw.wallonie.be https://geoportail.wallonie.be WWW:LINK Géoportail de la Wallonie Géoportail de la Wallonie Région wallonne 2.75 6.51 49.45 50.85 https://metawal.wallonie.be/geonetwork/inspire/api/records/1714cd1e-6685-4dea-a6f4-b51612a15ed0/attachments/wms_inspire_20190430.png Industrie et services Société et activités Thèmes du géoportail wallon 2014-01-01 2014-06-26 geonetwork.thesaurus.external.theme.Themes_geoportail_wallon_hierarchy Santé et sécurité des personnes GEMET - INSPIRE themes, version 1.0 2008-01-01 2008-06-01 geonetwork.thesaurus.external.theme.httpinspireeceuropaeutheme-theme aspects sociaux, population santé humaine GEMET themes 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet-theme santé sécurité GEMET 2009-01-01 2009-09-22 geonetwork.thesaurus.external.theme.gemet Reporting INSPIRE Mots-clés InfraSIG 2022-10-03 2022-10-03 geonetwork.thesaurus.external.theme.infraSIG Human health and safety HH health inspire WMS View validationtest Service d’accès aux cartes Classification of spatial data services 2008-01-01 2008-12-03 geonetwork.thesaurus.external.theme.httpinspireeceuropaeumetadatacodelistSpatialDataServiceCategory-SpatialDataServiceCategory Régional Champ géographique 2019-01-01 2019-05-22 geonetwork.thesaurus.external.theme.httpinspireeceuropaeumetadatacodelistSpatialScope-SpatialScope No limitations to public access Conditions d'utilisation spécifiques Les conditions d'utilisation du service sont régies par les conditions d’accès et d’utilisation des services web géographiques de visualisation du Service public de Wallonie. view Service public de Wallonie (SPW) helpdesk.carto@spw.wallonie.be https://geoservices.test.wallonie.be/geoserver/inspire_hh/ows?service=WMS&version=1.3.0&request=GetCapabilities OGC:WMS INSPIRE Santé et sécurité des personnes - Service de visualisation WMS Adresse de connexion au service de visualisation WMS-Inspire des couches de données du thème "Santé et sécurité des personnes". Service Règlement (CE) n o 976/2009 de la Commission du 19 octobre 2009 portant modalités d’application de la directive 2007/2/CE du Parlement européen et du Conseil en ce qui concerne les services en réseau 2009-10-19 Voir la spécification référencée true RÈGLEMENT (UE) N o 1089/2010 DE LA COMMISSION du 23 novembre 2010 portant modalités d'application de la directive 2007/2/CE du Parlement européen et du Conseil en ce qui concerne l'interopérabilité des séries et des services de données géographiques 2010-12-08 Voir la spécification référencée true ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-cql-title.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 143.0 144.0 -39.4 -38.4 -400.0 300.0 http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-elementname.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 143.0 144.0 -39.4 -38.4 -400.0 300.0 http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model 09a7c1d4c97ccdd7e34306deb91320ab95d51bb8 dataset ProvinceFullExtent 106.57 171.88 -49.86 -3.63 2018-02-08T11:04:47 revision https://nvclwebservices.csiro.au/geoserver/wms?SERVICE=WMS& OGC:WMS-1.1.1-http-get-map gml:ProvinceFullExtent ProvinceFullExtent https://nvclwebservices.csiro.au/geoserver/wms?request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=gml%3AProvinceFullExtent image/png Default Polygon (LegendURL) 74f81503-8d39-4ec8-a49a-c76e0cd74946 series Protection des captages - Série 2.75 6.5 49.45 50.85 2000-01-01 creation 2022-11-08 publication 2023-07-31 revision https://geoportail.wallonie.be/walonmap/#ADU=https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer WWW:LINK Application WalOnMap - Toute la Wallonie à la carte Application cartographique du Geoportail (WalOnMap) qui permet de découvrir les données géographiques de la Wallonie. http://geoapps.wallonie.be/Cigale/Public/#CTX=EAUX_SOUT WWW:LINK Protection des eaux souteraines (CIGALE) - Application Application de consultation des principales données cartographiques du SPW Agriculture, Ressources naturelles et Environnements https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer ESRI:REST Service de visualisation ESRI-REST Ce service ESRI-REST permet de visualiser le jeu de données "Protection des captages" https://geoservices.wallonie.be/arcgis/services/EAU/PROTECT_CAPT/MapServer/WMSServer?request=GetCapabilities&service=WMS OGC:WMS Service de visualisation WMS Ce service WMS permet de visualiser le jeu de données "Protection des captages" http://environnement.wallonie.be/de/eso/atlas/index.htm#4.1a WWW:LINK Site web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b. Zones de protection définies par arrêté ministériel Pages web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b Zones de protection définies par arrêté ministériel https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT.png WWW:LINK-1.0-http--image-thumbnail preview Web image thumbnail (URL) https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT_s.png WWW:LINK-1.0-http--image-thumbnail preview Web image thumbnail (URL) 1714cd1e-6685-4dea-a6f4-b51612a15ed0 service INSPIRE - Santé et sécurité des personnes en Wallonie (BE) - Service de visualisation WMS Industrie et services Société et activités Santé et sécurité des personnes aspects sociaux population santé humaine santé sécurité Reporting INSPIRE Human health and safety HH health inspire WMS View validationtest Service d’accès aux cartes Régional 2.75 6.51 49.45 50.85 2018-03-01 publication https://geoservices.test.wallonie.be/geoserver/inspire_hh/ows?service=WMS&version=1.3.0&request=GetCapabilities OGC:WMS INSPIRE Santé et sécurité des personnes - Service de visualisation WMS Adresse de connexion au service de visualisation WMS-Inspire des couches de données du thème "Santé et sécurité des personnes". https://metawal.wallonie.be/geonetwork/inspire/api/records/1714cd1e-6685-4dea-a6f4-b51612a15ed0/attachments/wms_inspire_20190430.png WWW:LINK-1.0-http--image-thumbnail preview Web image thumbnail (URL) ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-filter-accessconstraints.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 143.0 144.0 -39.4 -38.4 -400.0 300.0 http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model 74f81503-8d39-4ec8-a49a-c76e0cd74946 series Protection des captages - Série 2.75 6.5 49.45 50.85 2000-01-01 creation 2022-11-08 publication 2023-07-31 revision https://geoportail.wallonie.be/walonmap/#ADU=https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer WWW:LINK Application WalOnMap - Toute la Wallonie à la carte Application cartographique du Geoportail (WalOnMap) qui permet de découvrir les données géographiques de la Wallonie. http://geoapps.wallonie.be/Cigale/Public/#CTX=EAUX_SOUT WWW:LINK Protection des eaux souteraines (CIGALE) - Application Application de consultation des principales données cartographiques du SPW Agriculture, Ressources naturelles et Environnements https://geoservices.wallonie.be/arcgis/rest/services/EAU/PROTECT_CAPT/MapServer ESRI:REST Service de visualisation ESRI-REST Ce service ESRI-REST permet de visualiser le jeu de données "Protection des captages" https://geoservices.wallonie.be/arcgis/services/EAU/PROTECT_CAPT/MapServer/WMSServer?request=GetCapabilities&service=WMS OGC:WMS Service de visualisation WMS Ce service WMS permet de visualiser le jeu de données "Protection des captages" http://environnement.wallonie.be/de/eso/atlas/index.htm#4.1a WWW:LINK Site web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b. Zones de protection définies par arrêté ministériel Pages web Etat des nappes d'eau souterraine-chapitre IV.1a. Zones de prévention programmées ou en cours d'étude et IV.1b Zones de protection définies par arrêté ministériel https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT.png WWW:LINK-1.0-http--image-thumbnail preview Web image thumbnail (URL) https://metawal.wallonie.be/geonetwork/srv/api/records/74f81503-8d39-4ec8-a49a-c76e0cd74946/attachments/PROTECT_CAPT_s.png WWW:LINK-1.0-http--image-thumbnail preview Web image thumbnail (URL) ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-filter-and-nested-spatial-or-dateline.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 urn:uuid Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au Anthony Hurst Executive Director, Earth Resources Policy and Programs 2022-11-03T06:16:21 2022-11-03T06:17:02 ISO 19115-3 http://portal.auscope.org/geonetwork/srv/api/records/5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 2010-01-01 https://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 Reference AuScope Level 2, 700 Swanston Street Carlton Victoria 3053 Australia info@auscope.org.au https://ror.org/04s1m4564 ROR Research Organization Registry (ROR) Entry Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au P.B. SKLADZIEN C. Jorand A. Krassay L. Hall A 3D model of the Otway and Torquay basins has been produced at 1:250 000 scale as part of GeoScience Victorias state-wide 3D geological model. To date there has been a “knowledge gap” in the transition between the basement and basin environments. This regional scale integration of the basement and basin models addresses this gap and provides a regional framework within which more detailed work can be carried out in the future. The construction and integration of the basin model has involved both the interpretation and building of new faults and stratigraphic surfaces, as well as utilising existing stratigraphic surfaces and structural interpretations from previous studies, predominantly the Otway Basin HSA SEEBASE project by FrOG Tech (Jorand et. al., 2010). 143.00 144.00 -39.40 -38.40 -400 300 Victoria Otway Basin Torquay Basin 3D Geological Models https://creativecommons.org/licenses/by/4.0/ http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model 09a7c1d4c97ccdd7e34306deb91320ab95d51bb8 dataset CSIRO Peter Warren Software Engineer +61 2 9490 8802 voice 11 Julius Ave North Ryde CSIRO 2113 Australia 2018-02-08T11:04:47 creation 2018-02-08T11:04:47 revision ISO 19115-1:2014 ProvinceFullExtent features ProvinceFullExtent geoscientificInformation 106.57 171.88 -49.86 -3.63 https://nvclwebservices.csiro.au/geoserver/wms?SERVICE=WMS& OGC:WMS-1.1.1-http-get-map gml:ProvinceFullExtent ProvinceFullExtent https://nvclwebservices.csiro.au/geoserver/wms?request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=gml%3AProvinceFullExtent image/png Default Polygon (LegendURL) ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-filter-anytext.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 143.0 144.0 -39.4 -38.4 -400.0 300.0 http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-filter-bbox-csw-output.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 -39.4 143.0 -38.4 144.0 09a7c1d4c97ccdd7e34306deb91320ab95d51bb8 ProvinceFullExtent dataset -49.86 106.57 -3.63 171.88 ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-filter-bbox.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 143.0 144.0 -39.4 -38.4 -400.0 300.0 http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model 09a7c1d4c97ccdd7e34306deb91320ab95d51bb8 dataset ProvinceFullExtent 106.57 171.88 -49.86 -3.63 2018-02-08T11:04:47 revision https://nvclwebservices.csiro.au/geoserver/wms?SERVICE=WMS& OGC:WMS-1.1.1-http-get-map gml:ProvinceFullExtent ProvinceFullExtent https://nvclwebservices.csiro.au/geoserver/wms?request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=gml%3AProvinceFullExtent image/png Default Polygon (LegendURL) ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_GetRecords-filter-date.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 143.0 144.0 -39.4 -38.4 -400.0 300.0 http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:37363 WWW:LINK-1.0-http--link View Reports http://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 WWW:LINK-1.0-http--link Download Metadata and 3D model data http://geomodels.auscope.org/model/otway WWW:LINK-1.0-http--link 3D Geological Model ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_Transaction-delete.xml ================================================ Transaction operations are not supported ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_Transaction-insert.xml ================================================ Transaction operations are not supported ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_Transaction-update-full.xml ================================================ Transaction operations are not supported ================================================ FILE: tests/functionaltests/suites/iso19115p3/expected/post_Transaction-update-recordproperty.xml ================================================ Transaction operations are not supported ================================================ FILE: tests/functionaltests/suites/iso19115p3/get/requests.txt ================================================ GetCapabilities,service=CSW&version=2.0.2&request=GetCapabilities DescribeRecord,service=CSW&REQUEST=DescribeRecord&version=2.0.2&typeName=mdb:MD_Metadata ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/DescribeRecord.xml ================================================ mdb:MD_Metadata ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetDomain-property.xml ================================================ mdb:TopicCategory ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecordById-ISO19139-full.xml ================================================ 09a7c1d4c97ccdd7e34306deb91320ab95d51bb8 full ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecordById-brief.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 brief ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecordById-full-dc.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 full ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecordById-full.xml ================================================ 5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 full ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecordById-srv-brief.xml ================================================ 1714cd1e-6685-4dea-a6f4-b51612a15ed0 brief ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-all-csw-output.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-all.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-cql-title.xml ================================================ brief mdb:Title like '%tway%' ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-elementname.xml ================================================ mdb:Title ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-filter-accessconstraints.xml ================================================ brief mdb:AccessConstraints license ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-filter-and-nested-spatial-or-dateline.xml ================================================ full csw:AnyText *ustrali* ows:BoundingBox -38 142 -40 145 ows:BoundingBox -3 100 -50 172 dc:title ASC ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-filter-anytext.xml ================================================ brief mdb:AnyText 3D % ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-filter-bbox-csw-output.xml ================================================ brief mdb:BoundingBox -60 100 -5 175 ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-filter-bbox.xml ================================================ brief mdb:BoundingBox -60 100 -5 175 ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/GetRecords-filter-date.xml ================================================ brief mdb:Modified %2022% ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/Transaction-delete.xml ================================================ mdb:Identifier 12345 ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/Transaction-insert.xml ================================================ 12345 urn:uuid Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au Anthony Hurst Executive Director, Earth Resources Policy and Programs 2022-11-03T06:16:21 2022-11-03T06:17:02 ISO 19115-3 http://portal.auscope.org/geonetwork/srv/api/records/5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 2010-01-01 https://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 Reference A 3D model of the Otway and Torquay basins has been produced at 1:250 000 scale as part of GeoScience Victorias state-wide 3D geological model. To date there has been a “knowledge gap” in the transition between the basement and basin environments. This regional scale integration of the basement and basin models addresses this gap and provides a regional framework within which more detailed work can be carried out in the future. The construction and integration of the basin model has involved both the interpretation and building of new faults and stratigraphic surfaces, as well as utilising existing stratigraphic surfaces and structural interpretations from previous studies, predominantly the Otway Basin HSA SEEBASE project by FrOG Tech (Jorand et. al., 2010). 143.00 144.00 -39.40 -38.40 -400 300 Victoria Otway Basin Torquay Basin 3D Geological Models https://creativecommons.org/licenses/by/4.0/ ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/Transaction-update-full.xml ================================================ 12345 urn:uuid Earth Resources Victoria 1300 366 356 GPO Box 2392 Melbourne Victoria 3001 Australia customer.service@ecodev.vic.gov.au Anthony Hurst Executive Director, Earth Resources Policy and Programs 2022-11-03T06:16:21 2022-11-03T06:17:02 ISO 19115-3 http://portal.auscope.org/geonetwork/srv/api/records/5ebc3cb7-a3b5-4760-a8ff-851d5d5beb32 3D geological model of the Otway and Torquay Basin 2011 2010-01-01 https://geology.data.vic.gov.au/searchAssistant/document.php?q=parent_id:107513 Reference A 3D model of the Otway and Torquay basins has been produced at 1:250 000 scale as part of GeoScience Victorias state-wide 3D geological model. To date there has been a “knowledge gap” in the transition between the basement and basin environments. This regional scale integration of the basement and basin models addresses this gap and provides a regional framework within which more detailed work can be carried out in the future. The construction and integration of the basin model has involved both the interpretation and building of new faults and stratigraphic surfaces, as well as utilising existing stratigraphic surfaces and structural interpretations from previous studies, predominantly the Otway Basin HSA SEEBASE project by FrOG Tech (Jorand et. al., 2010). 143.00 144.00 -39.40 -38.40 -400 300 Victoria Otway Basin Torquay Basin 3D Geological Models https://creativecommons.org/licenses/by/4.0/ ================================================ FILE: tests/functionaltests/suites/iso19115p3/post/Transaction-update-recordproperty.xml ================================================ mdb:Title NEW_TITLE mdb:Identifier 12345 ================================================ FILE: tests/functionaltests/suites/manager/data/.gitignore ================================================ # This file exists to force git to include this directory in the code # repository. # # git does not include empty directories in code repositories. # # Functional tests are automatically generated by py.test. The way that the # tests are set up, the presence of a ``data/`` directory inside a test suite # has the following meaning: # # * if a ``data/`` directory does not exist, the tests of the suite use data # from the CITE suite; # # * if an empty ``data/`` directory exists, then a new empty database is # created and used; # # * if the ``data/`` directory exists and has files inside, a new database is # created and the files are loaded into the database as records. # # As such, the current suite needs an empty ``data/`` directory because its # functional tests depend on the existence of an empty database. # ignore all files in this directory (in case some file is put here by mistake, # we do not want it to be sent to the git repository and mess up the functional # tests) * # however, be sure to not ignore this file, as we need at least one file inside # this directory, so that git will aknowledge its existence !.gitignore ================================================ FILE: tests/functionaltests/suites/manager/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/manager/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true profiles: - apiso logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: true allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/manager/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Clear-000-delete-all.xml ================================================ 0 0 0 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_GetCapabilities.xml ================================================ pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record gmd:MD_Metadata DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames Harvest.ResourceType Transaction.TransactionSchemas CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record gmd:MD_Metadata apiso:AccessConstraints apiso:Bands apiso:Classification apiso:CloudCover apiso:ConditionApplyingToAccessAndUse apiso:Contributor apiso:Creator apiso:Degree apiso:IlluminationElevationAngle apiso:Instrument apiso:Lineage apiso:OtherConstraints apiso:Platform apiso:Publisher apiso:Relation apiso:ResponsiblePartyRole apiso:SensorType apiso:SpecificationDate apiso:SpecificationDateType apiso:SpecificationTitle csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox apiso:Abstract apiso:AlternateTitle apiso:AnyText apiso:BoundingBox apiso:CRS apiso:CouplingType apiso:CreationDate apiso:Denominator apiso:DistanceUOM apiso:DistanceValue apiso:Edition apiso:Format apiso:GeographicDescriptionCode apiso:HasSecurityConstraints apiso:Identifier apiso:KeywordType apiso:Language apiso:Modified apiso:OperatesOn apiso:OperatesOnIdentifier apiso:OperatesOnName apiso:Operation apiso:OrganisationName apiso:ParentIdentifier apiso:PublicationDate apiso:ResourceLanguage apiso:RevisionDate apiso:ServiceType apiso:ServiceTypeVersion apiso:Subject apiso:TempExtent_begin apiso:TempExtent_end apiso:Title apiso:TopicCategory apiso:Type brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom http://www.isotc211.org/2005/gmi http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 urn:geoss:waf http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.isotc211.org/2005/gmi http://www.isotc211.org/schemas/2005/gmd/ http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/manager/expected/post_GetDomain-parameter.xml ================================================ Harvest.ResourceType http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.isotc211.org/2005/gmd http://www.isotc211.org/2005/gmi http://www.isotc211.org/schemas/2005/gmd/ http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/3.0 http://www.opengis.net/cat/csw/csdgm http://www.opengis.net/sos/1.0 http://www.opengis.net/sos/2.0 http://www.opengis.net/wcs http://www.opengis.net/wfs http://www.opengis.net/wfs/2.0 http://www.opengis.net/wms http://www.opengis.net/wmts/1.0 http://www.opengis.net/wps/1.0.0 http://www.w3.org/2005/Atom urn:geoss:waf ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-000-delete-all.xml ================================================ 0 0 0 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-dc-01-insert.xml ================================================ 1 0 0 xyz pycsw Catalogue ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-dc-02-update-full.xml ================================================ 0 1 0 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-fgdc-01-insert.xml ================================================ 1 0 0 foorecord NCEP ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-fgdc-02-update-recprop.xml ================================================ 0 1 0 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-fgdc-03-delete-all.xml ================================================ 0 0 2 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-iso-00-delete-all.xml ================================================ 0 0 0 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-iso-01-insert.xml ================================================ 1 0 0 12345 pycsw record ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-iso-02-update-full.xml ================================================ 0 1 0 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-iso-03-update-recprop.xml ================================================ 0 1 0 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-iso-04-update-recprop-no-matches.xml ================================================ 0 0 0 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-iso-05-delete.xml ================================================ 0 0 1 ================================================ FILE: tests/functionaltests/suites/manager/expected/post_Transaction-xxx-delete-all.xml ================================================ 0 0 0 ================================================ FILE: tests/functionaltests/suites/manager/post/Clear-000-delete-all.xml ================================================ dc:identifier % ================================================ FILE: tests/functionaltests/suites/manager/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/manager/post/GetDomain-parameter.xml ================================================ Harvest.ResourceType ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-000-delete-all.xml ================================================ dc:identifier % ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-dc-01-insert.xml ================================================ xyz pycsw Catalogue 2012-06-05 Sample metadata dataset imagery baseMaps earthCover BIL Vanda Lima en -90 -180 90 180 ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-dc-02-update-full.xml ================================================ xyz THIS HAS BEEN UPDATED 2012-06-05 Sample metadata dataset imagery baseMaps earthCover BIL Vanda Lima en -90 -180 90 180 ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-fgdc-01-insert.xml ================================================ foorecord NOAA/ESRL Physical Sciences Division 20001201 NCEP Boulder, CO NOAA/ESRL Physical Sciences Division ftp://ftp.cdc.noaa.gov/Datasets/ncep/ http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep/ http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.html NCEP's twice-daily global analysis at 2.5&#176; resolution on pressure levels which is a product of their operational forecast system. Scientific research. Additional Fields: -----------------: StartDate: 19790101 StopDate: 20001201 Storage_Medium: online PSD Search Fields: Entry_ID: ncep.fgdc 19790101 20001201 Publication_Date: 20001201 Complete Irregular -180 180 90.00 -90.00 GCMD DIF 5.33 NCEP Air temperature Geopotential height Precipitable Water Content Precipitable water Content Relative humidity Sea level pressure Station pressure Surface potential temperature Surface Pressure Tropopause Pressure Tropopause temperature u-wind v-wind none Global none none none 19790101, 20001201 None None. Acknowledgement of PSD would appreciated in products derived from these data. PSD Data Management mailing address
NOAA/ESRL Physical Sciences Division
U.S. Dept. of Commerce
NOAA, R/PSD
325 Broadway
Boulder CO 80305 USA
(303) 497-6640 (303) 497-6020 esrl.psd.data@noaa.gov
None Unclassified None Data resides in netCDF files at PSD
Data QC'd at source. We have checked our stored values. None None None None 20001201 None None None None 9999 9999 None None None None 9999 PSD Data Management mailing address
NOAA/ESRL Physical Sciences Division
U.S. Dept. of Commerce
NOAA, Code R/PSD
325 Broadway
Boulder CO 80305 USA
(303) 497-7200 (303) 497-6020 esrl.psd.data@noaa.gov
No warranty expressed or implied.
20001201 PSD Data Management mailing address
NOAA/ESRL Physical Sciences Division
U.S. Dept. of Commerce
NOAA, Code R/PSD
325 Broadway
Boulder CO 80305 USA
(303) 497-7200 (303) 497-6020 esrl.psd.data@noaa.gov
FGDC Content Standards for Digital Geospatial Metadata FGDC-STD-001-1998 None Unclassified None
================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-fgdc-02-update-recprop.xml ================================================ idinfo/citation/citeinfo/title NEW_TITLE dct:abstract NCEP% ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-fgdc-03-delete-all.xml ================================================ dc:identifier % ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-iso-00-delete-all.xml ================================================ apiso:Identifier % ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-iso-01-insert.xml ================================================ 12345 pycsw 2011-05-17 pycsw record 2011-05-17 Sample metadata record eng -180 180 -90 90 ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-iso-02-update-full.xml ================================================ 12345 pycsw 2011-05-17 pycsw record UPDATED 2011-05-17 Sample metadata record eng -180 180 -90 90 ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-iso-03-update-recprop.xml ================================================ apiso:Title NEW_TITLE apiso:Identifier 12345 ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-iso-04-update-recprop-no-matches.xml ================================================ apiso:Title NEW_TITLE apiso:Identifier non-existent ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-iso-05-delete.xml ================================================ apiso:Identifier 12345 ================================================ FILE: tests/functionaltests/suites/manager/post/Transaction-xxx-delete-all.xml ================================================ dc:identifier % ================================================ FILE: tests/functionaltests/suites/oaipmh/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true profiles: - apiso logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_GetRecord_bad_metadata_prefix.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh Invalid outputschema parameter csw-recordd ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_GetRecord_datacite.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Image urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. image/svg+xml ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_GetRecord_dc.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_GetRecord_iso.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image ISO19115 2003/Cor.1:2006 Lorem ipsum Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. Tourism--Greece ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_GetRecord_oai_dc.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_Identify.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh pycsw Geospatial Catalogue http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh 2.0 tomkralidis@gmail.com PYCSW_TIMESTAMP no YYYY-MM-DDThh:mm:ssZ ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListIdentifiers_bad_metadata_prefix.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh Invalid outputSchema parameter value: foo ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListIdentifiers_datacite.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 11 ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListIdentifiers_dc.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 11 ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListIdentifiers_iso.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 11 ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListIdentifiers_missing_metadata_prefix.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh Missing metadataPrefix parameter ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListIdentifiers_oai_dc.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 11 ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListMetadataFormats.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh csw-record http://schemas.opengis.net/csw/2.0.2/record.xsd http://www.opengis.net/cat/csw/2.0.2 datacite http://schema.datacite.org/meta/kernel-4.3/metadata.xsd http://datacite.org/schema/kernel-4 dif http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/dif.xsd http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ fgdc-std http://www.fgdc.gov/metadata/fgdc-std-001-1998.xsd http://www.opengis.net/cat/csw/csdgm gm03 http://www.geocat.ch/internet/geocat/en/home/documentation/gm03.parsys.50316.downloadList.86742.DownloadFile.tmp/gm0321.zip http://www.interlis.ch/INTERLIS2.3 iso19139 http://www.isotc211.org/2005/gmd/gmd.xsd http://www.isotc211.org/2005/gmd oai_dc http://www.openarchives.org/OAI/2.0/oai_dc.xsd http://www.openarchives.org/OAI/2.0/oai_dc/ ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListRecords_datacite.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f 2006-05-12 Image urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. image/svg+xml urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd 2006-05-12 Service urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd </titles> <subjects/> <creators> <creator> <creatorName/> </creator> </creators> <descriptions> <description xml:lang="eng">Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</description> </descriptions> <rightsList/> <geoLocations> <geoLocation> <geoLocationBox> <westBoundLongitude>13.75</westBoundLongitude> <southBoundLatitude>60.04</southBoundLatitude> <eastBoundLongitude>17.92</eastBoundLongitude> <northBoundLatitude>68.41</northBoundLatitude> </geoLocationBox> </geoLocation> </geoLocations> </resource> </oai:metadata> </oai:record> <oai:record> <oai:header> <oai:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</oai:identifier> <oai:datestamp>2006-05-12</oai:datestamp> <oai:setSpec/> </oai:header> <oai:metadata> <resource xsi:schemaLocation="http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4.3/metadata.xsd"> <resourceType resourceTypeGeneral="Text">Text</resourceType> <identifier identifierType="URN">urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</identifier> <titles> <title xml:lang="eng">Maecenas enim Marine sediments Pellentesque tempus magna non sapien fringilla blandit. application/xhtml+xml urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 2006-05-12 Service urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 Ut facilisis justo ut lacus Vegetation urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec 2006-05-12 Text urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec 2006-05-12 Aliquam fermentum purus quis arcu Hydrography--Dictionaries Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. application/pdf 2006 urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e 2006-03-26 Image urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e Vestibulum massa purus image/jp2 urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 2006-03-26 Dataset urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 </titles> <subjects> <subject xml:lang="eng">Physiography-Landforms</subject> </subjects> <creators> <creator> <creatorName/> </creator> </creators> <descriptions> <description xml:lang="eng">Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque.</description> </descriptions> <rightsList/> </resource> </oai:metadata> </oai:record> <oai:record> <oai:header> <oai:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</oai:identifier> <oai:datestamp>2006-03-26</oai:datestamp> <oai:setSpec/> </oai:header> <oai:metadata> <resource xsi:schemaLocation="http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4.3/metadata.xsd"> <resourceType resourceTypeGeneral="Dataset">Dataset</resourceType> <identifier identifierType="URN">urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</identifier> <dates> <date dateType="Updated">2006-03-26</date> </dates> <titles> <title xml:lang="eng">Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. -4.1 47.59 0.89 51.22 2006 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc 2005-10-24 Dataset urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc 2005-10-24 Ñunç elementum Hydrography-Oceanographic -6.17 44.79 -2.23 51.13 2005 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Image urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet image/jpeg 11 ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListRecords_dc.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.042 13.754 68.410 17.920 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e http://purl.org/dc/dcmitype/Image image/jp2 Vestibulum massa purus urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms FI-ES Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 2005-10-24 44.792 -6.171 51.126 -2.228 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI 11 ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListRecords_dc_bad_metadata_prefix.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh Invalid outputSchema parameter value: csw-recording ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListRecords_iso19139.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image ISO19115 2003/Cor.1:2006 Lorem ipsum Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. Tourism--Greece urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service ISO19115 2003/Cor.1:2006 Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 13.75 17.92 60.04 68.41 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 http://purl.org/dc/dcmitype/Text ISO19115 2003/Cor.1:2006 Maecenas enim Pellentesque tempus magna non sapien fringilla blandit. Marine sediments urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service ISO19115 2003/Cor.1:2006 Ut facilisis justo ut lacus Vegetation urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec http://purl.org/dc/dcmitype/Text ISO19115 2003/Cor.1:2006 Aliquam fermentum purus quis arcu Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. Hydrography--Dictionaries urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e http://purl.org/dc/dcmitype/Image ISO19115 2003/Cor.1:2006 Vestibulum massa purus urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 dataset ISO19115 2003/Cor.1:2006 Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. Physiography-Landforms urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 dataset ISO19115 2003/Cor.1:2006 Mauris sed neque Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. Vegetation-Cropland -4.1 0.89 47.59 51.22 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc dataset ISO19115 2003/Cor.1:2006 Ñunç elementum Hydrography-Oceanographic -6.17 -2.23 44.79 51.13 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image ISO19115 2003/Cor.1:2006 Lorem ipsum dolor sit amet 11 ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListRecords_oai_dc.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.042 13.754 68.410 17.920 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e http://purl.org/dc/dcmitype/Image image/jp2 Vestibulum massa purus urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms FI-ES Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 2005-10-24 44.792 -6.171 51.126 -2.228 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI 11 ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_ListSets.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh datasets Datasets interactiveResources Interactive Resources ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_bad_verb.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh Unknown verb 'foo' ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_empty.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh Missing 'verb' parameter ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_empty_with_amp.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh Missing 'verb' parameter ================================================ FILE: tests/functionaltests/suites/oaipmh/expected/get_illegal_verb.xml ================================================ PYCSW_TIMESTAMP http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/oaipmh/default.yml&mode=oaipmh Unknown verb 'foo' ================================================ FILE: tests/functionaltests/suites/oaipmh/get/requests.txt ================================================ empty,mode=oaipmh empty_with_amp,mode=oaipmh& bad_verb,mode=oaipmh&verb=foo illegal_verb,mode=oaipmh&verb=foo&foo=bar Identify,mode=oaipmh&verb=Identify ListSets,mode=oaipmh&verb=ListSets ListMetadataFormats,mode=oaipmh&verb=ListMetadataFormats GetRecord_dc,mode=oaipmh&verb=GetRecord&identifier=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f&metadataPrefix=csw-record GetRecord_bad_metadata_prefix,mode=oaipmh&verb=GetRecord&identifier=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f&metadataPrefix=csw-recordd GetRecord_oai_dc,mode=oaipmh&verb=GetRecord&identifier=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f&metadataPrefix=oai_dc GetRecord_datacite,mode=oaipmh&verb=GetRecord&identifier=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f&metadataPrefix=datacite GetRecord_iso,mode=oaipmh&verb=GetRecord&identifier=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f&metadataPrefix=iso19139 ListIdentifiers_missing_metadata_prefix,mode=oaipmh&verb=ListIdentifiers ListIdentifiers_dc,mode=oaipmh&verb=ListIdentifiers&metadataPrefix=csw-record ListIdentifiers_iso,mode=oaipmh&verb=ListIdentifiers&metadataPrefix=iso19139 ListIdentifiers_datacite,mode=oaipmh&verb=ListIdentifiers&metadataPrefix=datacite ListIdentifiers_oai_dc,mode=oaipmh&verb=ListIdentifiers&metadataPrefix=oai_dc ListIdentifiers_bad_metadata_prefix,mode=oaipmh&verb=ListIdentifiers&metadataPrefix=foo ListRecords_dc,mode=oaipmh&verb=ListRecords&metadataPrefix=csw-record ListRecords_dc_bad_metadata_prefix,mode=oaipmh&verb=ListRecords&metadataPrefix=csw-recording ListRecords_oai_dc,mode=oaipmh&verb=ListRecords&metadataPrefix=oai_dc ListRecords_datacite,mode=oaipmh&verb=ListRecords&metadataPrefix=datacite ListRecords_iso19139,mode=oaipmh&verb=ListRecords&metadataPrefix=iso19139 ================================================ FILE: tests/functionaltests/suites/oarec/conftest.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # Tom Kralidis # # Copyright (c) 2023 Ricardo Garcia Silva # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import pytest @pytest.fixture() def config(): yield { 'server': { 'url': 'http://localhost/pycsw/oarec', 'mimetype': 'application/xml;', 'charset': 'UTF-8', 'encoding': 'UTF-8', 'language': 'en-US', 'maxrecords': '10', 'gzip_compresslevel': '9', 'profiles': [ 'apiso' ] }, 'logging': { 'level': 'ERROR' }, 'manager': { 'transactions': True, 'allowed_ips': [ '127.0.0.1' ] }, 'metadata': { 'identification': { 'title': 'pycsw Geospatial Catalogue', 'description': 'pycsw is an OARec and OGC CSW server implementation written in Python', # noqa 'keywords': [ 'catalogue', 'discovery', 'metadata' ], 'keywords_type': 'theme', 'fees': 'None', 'accessconstraints': 'None' }, 'provider': { 'name': 'Organization Name', 'url': 'https://pycsw.org/' }, 'contact': { 'name': 'Lastname, Firstname', 'position': 'Position Title', 'address': 'Mailing Address', 'city': 'City', 'stateorprovince': 'Administrative Area', 'postalcode': 'Zip or Postal Code', 'country': 'Country', 'phone': '+xx-xxx-xxx-xxxx', 'fax': '+xx-xxx-xxx-xxxx', 'email': 'you@example.org', 'url': 'Contact URL', 'hours': 'Hours of Service', 'instructions': 'During hours of service. Off on weekends.', 'role': 'pointOfContact' }, 'inspire': { 'enabled': True, 'languages_supported': [ 'eng', 'gre' ], 'default_language': 'eng', 'date': 'YYYY-MM-DD', 'gemet_keywords': [ 'Utility and governmental services' ], 'conformity_service': 'notEvaluated', 'contact_name': 'Organization Name', 'contact_email': 'you@example.org', 'temp_extent': { 'begin': 'YYYY-MM-DD', 'end': 'YYYY-MM-DD' } } }, 'repository': { 'database': 'sqlite:///tests/functionaltests/suites/cite/data/cite.db', # noqa 'table': 'records' } } @pytest.fixture() def config_virtual_collections(config): database = config['repository']['database'] config['repository']['database'] = database.replace('cite.db', 'cite-virtual-collections.db') # noqa return config @pytest.fixture() def sample_record(): yield { "id": "record-123", "conformsTo": [ "http://www.opengis.net/spec/ogcapi-records-1/1.0/req/record-core" ], "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [-141, 42], [-141, 84], [-52, 84], [-52, 42], [-141, 42] ]] }, "properties": { "identifier": "3f342f64-9348-11df-ba6a-0014c2c00eab", "title": "title in English", "description": "abstract in English", "themes": [ { "concepts": [ "kw1 in English", "kw2 in English", "kw3 in English" ] }, { "concepts": [ "FOO", "BAR" ], "scheme": "http://example.org/vocab" }, { "concepts": [ "kw1", "kw2" ] } ], "providers": [ { "name": "Environment Canada", "individual": "Tom Kralidis", "positionName": "Senior Systems Scientist", "contactInfo": { "phone": { "office": "+01-123-456-7890" }, "email": { "office": "+01-123-456-7890" }, "address": { "office": { "deliveryPoint": "4905 Dufferin Street", "city": "Toronto", "administrativeArea": "Ontario", "postalCode": "M3H 5T4", "country": "Canada" }, "onlineResource": { "href": "https://www.ec.gc.ca/" } }, "hoursOfService": "0700h - 1500h EST", "contactInstructions": "email", "url": { "rel": "canonical", "type": "text/html", "href": "https://www.ec.gc.ca/" } }, "roles": [ {"name": "pointOfContact"} ] }, { "name": "Environment Canada", "individual": "Tom Kralidis", "positionName": "Senior Systems Scientist", "contactInfo": { "phone": {"office": "+01-123-456-7890"}, "email": {"office": "+01-123-456-7890"}, "address": { "office": { "deliveryPoint": "4905 Dufferin Street", "city": "Toronto", "administrativeArea": "Ontario", "postalCode": "M3H 5T4", "country": "Canada" }, "onlineResource": {"href": "https://www.ec.gc.ca/"} }, "hoursOfService": "0700h - 1500h EST", "contactInstructions": "email", "url": { "rel": "canonical", "type": "text/html", "href": "https://www.ec.gc.ca/" } }, "roles": [ {"name": "distributor"} ] } ], "language": { "code": "en" }, "type": "dataset", "created": "2011-11-11", "updated": "2000-09-01", "rights": "Copyright (c) 2010 Her Majesty the Queen in Right of Canada" # noqa }, "links": [ { "rel": "canonical", "href": "https://example.org/data", "type": "WWW:LINK", "title": "my waf" }, { "rel": "service", "href": "https://example.org/wms", "type": "OGC:WMS", "title": "roads" } ], "time": { "interval": [ "1950-07-31", None ], "resolution": "P1Y" } } ================================================ FILE: tests/functionaltests/suites/oarec/test_oarec_functional.py ================================================ # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # Ricardo Garcia Silva # # Copyright (c) 2025 Tom Kralidis # Copyright (c) 2022 Angelos Tzotsos # Copyright (c) 2023 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from copy import deepcopy import json from xml.etree import ElementTree as etree import pytest from pycsw.ogc.api.records import API pytestmark = pytest.mark.functional def test_landing_page(config): api = API(config) headers, status, content = api.landing_page({}, {'f': 'json'}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert status == 200 assert len(content['links']) == 15 for link in content['links']: assert link['href'].startswith(api.config['server']['url']) headers, status, content = api.landing_page({}, {'f': 'html'}) assert status == 200 assert headers['Content-Type'] == 'text/html' def test_openapi(config): api = API(config) headers, status, content = api.openapi({}, {'f': 'json'}) assert status == 200 json.loads(content) assert headers['Content-Type'] == 'application/vnd.oai.openapi+json;version=3.0' # noqa headers, status, content = api.openapi({}, {'f': 'html'}) assert status == 200 assert headers['Content-Type'] == 'text/html' def test_conformance(config): api = API(config) headers, status, content = api.conformance({}, {}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert len(content['conformsTo']) == 14 def test_collections(config): api = API(config) headers, status, content = api.collections({}, {}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert len(content['links']) == 2 assert len(content['collections']) == 1 content = json.loads(api.collections({}, {})[2])['collections'][0] assert len(content['links']) == 4 assert content['id'] == 'metadata:main' assert content['title'] == 'pycsw Geospatial Catalogue' assert content['description'] == 'pycsw is an OARec and OGC CSW server implementation written in Python' # noqa assert content['itemType'] == 'record' def test_queryables(config): api = API(config) headers, status, content = api.queryables({}, {}) content = json.loads(content) assert headers['Content-Type'] == 'application/schema+json' assert content['type'] == 'object' assert content['title'] == 'pycsw Geospatial Catalogue' assert content['$id'] == 'http://localhost/pycsw/oarec/collections/metadata:main/queryables' # noqa assert content['$schema'] == 'http://json-schema.org/draft/2019-09/schema' assert len(content['properties']) == 19 assert 'geometry' in content['properties'] assert content['properties']['geometry']['$ref'] == 'https://geojson.org/schema/Polygon.json' # noqa headers, status, content = api.queryables({}, {}, collection='foo') assert status == 400 def test_items(config): api = API(config) headers, status, content = api.items({}, None, {}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert content['type'] == 'FeatureCollection' assert len(content['links']) == 5 assert 'timeStamp' in content assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert len(content['features']) == 10 assert len(content['features']) == content['numberReturned'] params = {'q': 'Lorem'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 5 assert content['numberReturned'] == 5 assert len(content['features']) == content['numberReturned'] params = {'q': 'Lorem dolor'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 1 assert content['numberReturned'] == 1 assert len(content['features']) == content['numberReturned'] params = {'bbox': '-50,0,50,80'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 3 assert content['numberReturned'] == 3 assert len(content['features']) == content['numberReturned'] params = {'bbox': '-50,0,50,80', 'q': 'Lorem'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 1 assert content['numberReturned'] == 1 assert len(content['features']) == content['numberReturned'] params = {'q': 'Lorem ipsum'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 2 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] params = {'q': 'Lorem,ipsum'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 6 assert content['numberReturned'] == 6 assert len(content['features']) == content['numberReturned'] params = {'q': 'Lorem ipsum purus'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 0 assert content['numberReturned'] == 0 assert len(content['features']) == content['numberReturned'] params = {'q': 'Lorem ipsum,purus'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 4 assert content['numberReturned'] == 4 assert len(content['features']) == content['numberReturned'] ids = [ 'urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f', 'urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd' ] params = {'ids': ','.join(ids)} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 2 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] params = {'filter': "title LIKE '%%Lorem%%'"} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 2 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] params = {'filter': "title LIKE '%%Lorem%%'", 'q': 'iPsUm'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 2 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] params = {'limit': 0} content = json.loads(api.items({}, None, params)[2]) assert content['code'] == 'InvalidParameterValue' assert content['description'] == 'Limit must be a positive integer' params = {'limit': 4} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 4 assert len(content['features']) == content['numberReturned'] params = {'limit': 4, 'offset': 10} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] params = {'sortby': 'title'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert content['features'][5]['properties']['title'] == 'Lorem ipsum' params = {'sortby': '-title'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert content['features'][5]['properties']['title'] == 'Lorem ipsum dolor sit amet' # noqa params = {'SoRtBy': '-title'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert content['features'][5]['properties']['title'] == 'Lorem ipsum dolor sit amet' # noqa params = {'sortby': '-title,description'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert content['features'][0]['properties']['title'] == 'Ñunç elementum' params = {'sortby': 'title,description'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert content['features'][5]['properties']['title'] == 'Lorem ipsum' params = {'sortby': 'title,-description'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert content['features'][6]['properties']['title'] == 'Lorem ipsum dolor sit amet' # noqa cql_json = {'op': '=', 'args': [{'property': 'title'}, 'Lorem ipsum']} content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 1 assert content['numberReturned'] == 1 assert len(content['features']) == content['numberReturned'] cql_json = {'op': '=', 'args': [{'property': 'title'}, 'Lorem ipsum']} content = json.loads(api.items({}, cql_json, {'limit': 1})[2]) assert content['numberMatched'] == 1 assert content['numberReturned'] == 1 assert len(content['features']) == content['numberReturned'] cql_json = {'op': 'like', 'args': [{'property': 'title'}, 'lorem%']} content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 2 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] headers, status, content = api.items({}, None, {}, collection='foo') assert status == 400 def test_item(config): api = API(config) item = 'urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f' headers, status, content = api.item({}, {}, 'metadata:main', item) content = json.loads(content) assert headers['Content-Type'] == 'application/geo+json' assert content['id'] == item assert content['type'] == 'Feature' assert content['properties']['title'] == 'Lorem ipsum' assert content['properties']['keywords'] == ['Tourism--Greece'] item = 'urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f' params = {'f': 'xml'} content = api.item({}, params, 'metadata:main', item)[2] e = etree.fromstring(content) element = e.find('{http://purl.org/dc/elements/1.1/}identifier').text assert element == item element = e.find('{http://purl.org/dc/elements/1.1/}type').text assert element == 'http://purl.org/dc/dcmitype/Image' element = e.find('{http://purl.org/dc/elements/1.1/}title').text assert element == 'Lorem ipsum' element = e.find('{http://purl.org/dc/elements/1.1/}subject').text assert element == 'Tourism--Greece' headers, status, content = api.item({}, {}, 'foo', item) assert status == 400 def test_json_transaction(config, sample_record): api = API(config) request_headers = { 'Content-Type': 'application/json' } # insert record headers, status, content = api.manage_collection_item( request_headers, 'create', data=sample_record) assert status == 201 # test that record is in repository content = json.loads(api.item({}, {}, 'metadata:main', 'record-123')[2]) assert content['id'] == 'record-123' assert content['properties']['title'] == 'title in English' # test XML representation params = {'f': 'xml'} content = api.item({}, params, 'metadata:main', 'record-123')[2] e = etree.fromstring(content) element = e.find('{http://www.w3.org/2005/Atom}id').text assert element == 'record-123' element = e.find('{http://www.w3.org/2005/Atom}title').text assert element == 'title in English' # update record sample_record['properties']['title'] = 'new title' headers, status, content = api.manage_collection_item( request_headers, 'update', item='record-123', data=sample_record) assert status == 204 # test that record is in repository content = json.loads(api.item({}, {}, 'metadata:main', 'record-123')[2]) assert content['id'] == 'record-123' assert content['properties']['title'] == 'new title' # test XML representation params = {'f': 'xml'} content = api.item({}, params, 'metadata:main', 'record-123')[2] e = etree.fromstring(content) element = e.find('{http://www.w3.org/2005/Atom}id').text assert element == 'record-123' element = e.find('{http://www.w3.org/2005/Atom}title').text assert element == 'new title' # delete record headers, status, content = api.manage_collection_item( request_headers, 'delete', item='record-123') assert status == 200 # test that record is not in repository headers, status, content = api.item({}, {}, 'metadata:main', 'record-123') assert status == 404 config2 = deepcopy(config) config2['manager']['transactions'] = False api = API(config2) request_headers = { 'Content-Type': 'application/json' } # fail on insert record attempt headers, status, content = api.manage_collection_item( request_headers, 'create', data=sample_record) assert status == 405 config2['manager']['transactions'] = 'false' api = API(config2) request_headers = { 'Content-Type': 'application/json' } # fail on insert record attempt headers, status, content = api.manage_collection_item( request_headers, 'create', data=sample_record) assert status == 405 def test_xml_transaction(config): api = API(config) sample_xml = b""" record-456 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 """.strip() request_headers = { 'Content-Type': 'application/xml' } # insert record headers, status, content = api.manage_collection_item( request_headers, 'create', data=sample_xml) assert status == 201 # test that record is in repository content = json.loads(api.item({}, {}, 'metadata:main', 'record-456')[2]) assert content['id'] == 'record-456' assert content['properties']['title'] == 'Ut facilisis justo ut lacus' # test XML representation params = {'f': 'xml'} content = api.item({}, params, 'metadata:main', 'record-456')[2] e = etree.fromstring(content) element = e.find('{http://purl.org/dc/elements/1.1/}identifier').text assert element == 'record-456' element = e.find('{http://purl.org/dc/elements/1.1/}title').text assert element == 'Ut facilisis justo ut lacus' # update record test_data_xml = sample_xml.replace( b'Ut facilisis justo ut lacus', b'new title') headers, status, content = api.manage_collection_item( request_headers, 'update', item='record-456', data=test_data_xml) assert status == 204 # test that record is in repository content = json.loads(api.item({}, {}, 'metadata:main', 'record-456')[2]) assert content['id'] == 'record-456' assert content['properties']['title'] == 'new title' # test XML representation params = {'f': 'xml'} content = api.item({}, params, 'metadata:main', 'record-456')[2] e = etree.fromstring(content) element = e.find('{http://purl.org/dc/elements/1.1/}identifier').text assert element == 'record-456' element = e.find('{http://purl.org/dc/elements/1.1/}title').text assert element == 'new title' # delete record headers, status, content = api.manage_collection_item( request_headers, 'delete', item='record-456') assert status == 200 # test that record is not in repository headers, status, content = api.item({}, {}, 'metadata:main', 'record-456') assert status == 404 ================================================ FILE: tests/functionaltests/suites/oarec/test_oarec_virtual_collections_functional.py ================================================ # ================================================================= # # Authors: Tom Kralidis # Ricardo Garcia Silva # # Copyright (c) 2025 Tom Kralidis # Copyright (c) 2023 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= from copy import deepcopy import json from xml.etree import ElementTree as etree import pytest from pycsw.ogc.api.records import API pytestmark = pytest.mark.functional def test_landing_page(config_virtual_collections): api = API(config_virtual_collections) headers, status, content = api.landing_page({}, {'f': 'json'}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert status == 200 assert len(content['links']) == 15 for link in content['links']: assert link['href'].startswith(api.config['server']['url']) headers, status, content = api.landing_page({}, {'f': 'html'}) assert status == 200 assert headers['Content-Type'] == 'text/html' def test_openapi(config_virtual_collections): api = API(config_virtual_collections) headers, status, content = api.openapi({}, {'f': 'json'}) assert status == 200 json.loads(content) assert headers['Content-Type'] == 'application/vnd.oai.openapi+json;version=3.0' # noqa headers, status, content = api.openapi({}, {'f': 'html'}) assert status == 200 assert headers['Content-Type'] == 'text/html' def test_conformance(config_virtual_collections): api = API(config_virtual_collections) content = json.loads(api.conformance({}, {})[2]) assert len(content['conformsTo']) == 14 def test_collections(config_virtual_collections): api = API(config_virtual_collections) content = json.loads(api.collections({}, {})[2]) assert len(content['links']) == 2 assert len(content['collections']) == 2 content = json.loads(api.collections({}, {})[2])['collections'][0] assert len(content['links']) == 4 assert content['id'] == 'metadata:main' assert content['title'] == 'pycsw Geospatial Catalogue' assert content['description'] == 'pycsw is an OARec and OGC CSW server implementation written in Python' # noqa assert content['itemType'] == 'record' cvc = deepcopy(config_virtual_collections) cvc['server']['maxrecords'] = 0 api = API(cvc) content = json.loads(api.collections({}, {})[2]) assert len(content['links']) == 2 assert len(content['collections']) == 1 cvc = deepcopy(config_virtual_collections) cvc['server']['maxrecords'] = 1 api = API(cvc) content = json.loads(api.collections({}, {})[2]) assert len(content['links']) == 2 assert len(content['collections']) == 2 def test_queryables(config_virtual_collections): api = API(config_virtual_collections) content = json.loads(api.queryables({}, {})[2]) assert content['type'] == 'object' assert content['title'] == 'pycsw Geospatial Catalogue' assert content['$id'] == 'http://localhost/pycsw/oarec/collections/metadata:main/queryables' # noqa assert content['$schema'] == 'http://json-schema.org/draft/2019-09/schema' assert len(content['properties']) == 19 assert 'geometry' in content['properties'] assert content['properties']['geometry']['$ref'] == 'https://geojson.org/schema/Polygon.json' # noqa headers, status, content = api.queryables({}, {}, 'foo') assert status == 400 def test_items(config_virtual_collections): api = API(config_virtual_collections) content = json.loads(api.items({}, None, {})[2]) assert content['type'] == 'FeatureCollection' assert len(content['links']) == 5 assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert len(content['features']) == 10 assert len(content['features']) == content['numberReturned'] params = {'q': 'Lorem'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 5 assert content['numberReturned'] == 5 assert len(content['features']) == content['numberReturned'] params = {'q': 'Lorem dolor'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 1 assert content['numberReturned'] == 1 assert len(content['features']) == content['numberReturned'] params = {'bbox': '-50,0,50,80'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 3 assert content['numberReturned'] == 3 assert len(content['features']) == content['numberReturned'] params = {'bbox': '-50,0,50,80', 'q': 'Lorem'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 1 assert content['numberReturned'] == 1 assert len(content['features']) == content['numberReturned'] params = {'filter': "title LIKE '%%Lorem%%'"} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 2 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] params = {'filter': "title LIKE '%%Lorem%%'", 'q': 'iPsUm'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 2 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] params = {'limit': 0} content = json.loads(api.items({}, None, params)[2]) assert content['code'] == 'InvalidParameterValue' assert content['description'] == 'Limit must be a positive integer' params = {'limit': 4} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 4 assert len(content['features']) == content['numberReturned'] params = {'limit': 4, 'offset': 10} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] params = {'sortby': 'title'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert content['features'][5]['properties']['title'] == 'Lorem ipsum' params = {'sortby': '-title'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 10 assert content['features'][5]['properties']['title'] == 'Lorem ipsum dolor sit amet' # noqa cql_json = {'op': '=', 'args': [{'property': 'title'}, 'Lorem ipsum']} content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 1 assert content['numberReturned'] == 1 assert len(content['features']) == content['numberReturned'] cql_json = {'op': '=', 'args': [{'property': 'title'}, 'Lorem ipsum']} content = json.loads(api.items({}, cql_json, {'limit': 1})[2]) assert content['numberMatched'] == 1 assert content['numberReturned'] == 1 assert len(content['features']) == content['numberReturned'] cql_json = {'op': 'like', 'args': [{'property': 'title'}, 'lorem%']} content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 2 assert content['numberReturned'] == 2 assert len(content['features']) == content['numberReturned'] headers, status, content = api.items({}, {}, {}, 'foo') assert status == 400 def test_item(config_virtual_collections): api = API(config_virtual_collections) item = 'urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f' content = json.loads(api.item({}, {}, 'metadata:main', item)[2]) assert content['id'] == item assert content['type'] == 'Feature' assert content['properties']['title'] == 'Lorem ipsum' assert content['properties']['keywords'] == ['Tourism--Greece'] item = 'urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f' params = {'f': 'xml'} content = api.item({}, params, 'metadata:main', item)[2] e = etree.fromstring(content) element = e.find('{http://purl.org/dc/elements/1.1/}identifier').text assert element == item element = e.find('{http://purl.org/dc/elements/1.1/}type').text assert element == 'http://purl.org/dc/dcmitype/Image' element = e.find('{http://purl.org/dc/elements/1.1/}title').text assert element == 'Lorem ipsum' element = e.find('{http://purl.org/dc/elements/1.1/}subject').text assert element == 'Tourism--Greece' headers, status, content = api.item({}, {}, 'foo', item) assert status == 400 ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/3e9a8c05.xml ================================================ 3e9a8c05 eng service NTUA tzotsos@gmail.com pointOfContact 2011-04-18 ISO19115 2003/Cor.1:2006 test Title 2011-04-19 creation http://aiolos.survey.ntua.gr ogc test Abstract NTUA tzotsos@gmail.com owner Geographic viewer (humanGeographicViewer) administration GEMET Themes, version 2.3 2011-04-18 publication Conditions unknown no limitation 19.37 29.61 34.80 41.75 2011-04-18 2011-04-20 view http://aiolos.survey.ntua.gr/geoserver/wms service Conformity_001 INSPIRE Corrigendum to INSPIRE Metadata Regulation published in the Official Journal of the European Union, L 328, page 83 2009-12-15 publication See the referenced specification true ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/README.txt ================================================ OpenSearch EO Data ================== This directory provides data used to check conformance against pycsw OpenSearch EO support. - pacioos-NS06agg.xml: http://oos.soest.hawaii.edu/pacioos/metadata/NS06agg.html - all other *.xml files are from the Greek National Mapping Agency (metadata submitted to the INSPIRE geoportal) ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_aerfo_RAS_1991_GR800P001800000012.xml ================================================ 366f6257-19eb-4f20-ba78-0698ac4aae77 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 366f6257-19eb-4f20-ba78-0698ac4aae77 T_aerfo_RAS_1991_GR800P001800000012.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_aerfo_RAS_1991_GR800P001800000013.xml ================================================ 75a7eb5e-336e-453d-ab06-209b1070d396 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 75a7eb5e-336e-453d-ab06-209b1070d396 T_aerfo_RAS_1991_GR800P001800000013.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_aerfo_RAS_1991_GR800P001800000014.xml ================================================ a7308c0a-b748-48e2-bab7-0a608a51d416 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation a7308c0a-b748-48e2-bab7-0a608a51d416 T_aerfo_RAS_1991_GR800P001800000014.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_aerfo_RAS_1991_GR800P001800000015.xml ================================================ 0173e0d7-6ea9-4407-b846-f29d6bfa9903 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 0173e0d7-6ea9-4407-b846-f29d6bfa9903 T_aerfo_RAS_1991_GR800P001800000015.tif Aerial Photos YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0024.0038.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_ortho_RAS_1998_284404.xml ================================================ de53e931-778a-4792-94ad-9fe507aca483 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication de53e931-778a-4792-94ad-9fe507aca483 T_ortho_RAS_1998_284404.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.47878421.52731739.7600139.790341 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_ortho_RAS_1998_288395.xml ================================================ 4a5109d7-9ce5-4197-a423-b5fa8c426dee eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication 4a5109d7-9ce5-4197-a423-b5fa8c426dee T_ortho_RAS_1998_288395.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.52833321.57683439.67999939.710309 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_ortho_RAS_1998_288398.xml ================================================ 5f37e0f8-4fb1-4637-b959-b415058bdb68 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication 5f37e0f8-4fb1-4637-b959-b415058bdb68 T_ortho_RAS_1998_288398.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.52736921.57588839.70700439.737315 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_ortho_RAS_1998_288401.xml ================================================ f99cc358-f379-4e79-ab1e-cb2f7709f594 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication f99cc358-f379-4e79-ab1e-cb2f7709f594 T_ortho_RAS_1998_288401.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.52640421.57494139.73400939.764321 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_ortho_RAS_1998_288404.xml ================================================ ae200a05-2800-40b8-b85d-8f8d007b9e30 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 Ortho 2000-01-01publication ae200a05-2800-40b8-b85d-8f8d007b9e30 T_ortho_RAS_1998_288404.tif Ortho YPAATypaat@ypaat.growner OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng geoscientificInformation 21.52543721.57399239.76101539.791327 1997-01-011999-01-01 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_pmoed_DTM_1996_276395.xml ================================================ a2744b0c-becd-426a-95a8-46e9850ccc6d eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation a2744b0c-becd-426a-95a8-46e9850ccc6d T_pmoed_DTM_1996_276395.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_pmoed_DTM_1996_276398.xml ================================================ 0dc824a6-b555-46c1-bd7b-bc66cb91a70f eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation 0dc824a6-b555-46c1-bd7b-bc66cb91a70f T_pmoed_DTM_1996_276398.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_pmoed_DTM_1996_276401.xml ================================================ 42c8e55a-2bf6-476d-a7c9-be3bcd697f13 eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation 42c8e55a-2bf6-476d-a7c9-be3bcd697f13 T_pmoed_DTM_1996_276401.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_pmoed_DTM_1996_276404.xml ================================================ c3bf29d4-d60a-4959-a415-2c03fb0d4aef eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation c3bf29d4-d60a-4959-a415-2c03fb0d4aef T_pmoed_DTM_1996_276404.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/T_pmoed_DTM_1996_280395.xml ================================================ b8cc2388-5d0a-43d8-9473-0e86dd0396da eng dataset YPAATypaat@ypaat.grpointOfContact 2009-10-07 ISO19115 2003/Cor.1:2006 DTM 2009-10-07creation b8cc2388-5d0a-43d8-9473-0e86dd0396da T_pmoed_DTM_1996_280395.tif DTM YPAATypaat@ypaat.growner ElevationGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations 5000 eng elevation 19.0030.0034.0042.00 2009-10-072009-10-07 http://www.ypaat.gr dataset test ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/iso_19115-2_Sentinel-2-scene.xml ================================================ S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE eng utf8 TBD dataset WWW:LINK information pointOfContact 2020-09-02T11:39:10.000000Z ISO 19115:2003 - Geographic information - Metadata ISO 19115:2003 European Petroleum Survey Group (EPSG) Geodetic Parameter Registry 2008-11-12 publication European Petroleum Survey Group http://www.epsg-registry.org originator urn:ogc:def:crs:EPSG:4326 6.18.3 S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE 2020-09-02T11:39:10.000000Z creation 2020-09-02T11:39:10.000000Z publication S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE onGoing continual Orthoimagery Land cover Geographical names theme data set series theme processing theme eo:productType:S2MSI2A eo:orbitNumber:50 eo:orbitDirection:DESCENDING eo:snowCover:0.0 theme otherRestrictions grid utf8 imageryBaseMapsEarthCover 1 22.241087944581203 22.316296604618408 36.95084163397443 37.21692395594552 2020-09-02T09:05:59.024Z 2020-09-02T09:05:59.024Z image image 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 456 411 nm 0.082857 Level-2A WWW:LINK information distributor s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/ enclosure product product alternate s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_B02_10m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_B03_10m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_B04_10m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_B08_10m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_TCI_10m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_AOT_10m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R10m/T34SFG_20200902T090559_WVP_10m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B02_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B03_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B04_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B05_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B06_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B07_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B8A_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B11_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_B12_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_TCI_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_AOT_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_WVP_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R20m/T34SFG_20200902T090559_SCL_20m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B01_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B02_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B03_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B04_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B05_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B06_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B07_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B8A_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B09_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B11_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_B12_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_TCI_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_AOT_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_WVP_60m.jp2 image/jp2 granule granule enclosure s3://eodata/Sentinel-2/MSI/L2A/2020/09/02/S2B_MSIL2A_20200902T090559_N0214_R050_T34SFG_20200902T113910.SAFE/GRANULE/L2A_T34SFG_A018237_20200902T091111/IMG_DATA/R60m/T34SFG_20200902T090559_SCL_60m.jp2 image/jp2 granule granule enclosure continual This metadata record was generated by pygeometa-0.13.1 (https://github.com/geopython/pygeometa) Sentinel-2B Sentinel-2B INS-NOBS S2MSI2A ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/pacioos-NS06agg.xml ================================================ NS06agg eng UTF8 dataset service Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information pointOfContact 2014-04-16 ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data ISO 19115-2:2009(E) 3 column 1 0.0 row 1 0.0 temporal 482760 252.0 area PacIOOS Nearshore Sensor 06: Pohnpei, Micronesia 2011-04-12 creation 2011-04-19 issued 2014-03-18 revision org.pacioos NS06agg Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information originator Jim Potemra distributor Data produced by Dr. Margaret McManus (mamc@hawaii.edu). Point of contact: Gordon Walker (gwalker@hawaii.edu). The nearshore sensors are part of the Pacific Islands Ocean Observing System (PacIOOS) and are designed to measure a variety of ocean parameters at fixed point locations. NS06 is located at the dock in Pohnpei lagoon and is mounted to the bottom in about 1 meter of water. The instrument is a Sea-Bird Electronics model 16+ V2 coupled with a WET Labs ECO-FLNTUS combination sensor. PacIOOS provides timely, reliable, and accurate ocean information to support a safe, clean, productive ocean and resilient coastal zone in the U.S. Pacific Islands region. The Pacific Islands Ocean Observing System (PacIOOS) is funded through the National Oceanic and Atmospheric Administration (NOAA) as a Regional Association within the U.S. Integrated Ocean Observing System (IOOS). PacIOOS is coordinated by the University of Hawaii School of Ocean and Earth Science and Technology (SOEST). Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information pointOfContact http://pacioos.org/metadata/browse/NS06agg.png Sample image. Oceans > Ocean Chemistry > Chlorophyll Oceans > Ocean Optics > Turbidity Oceans > Ocean Temperature > Water Temperature Oceans > Salinity/Density > Conductivity Oceans > Salinity/Density > Salinity Oceans > Water Quality theme GCMD Science Keywords Ocean &gt; Pacific Ocean &gt; Western Pacific Ocean &gt; Micronesia &gt; Federated States of Micronesia Ocean &gt; Pacific Ocean &gt; United States of America &gt; Territories Federated States of Micronesia &gt; Pohnpei &gt; Pohnpei Lagoon place GCMD Location Keywords Pacific Islands Ocean Observing System (PacIOOS) project GCMD Project Keywords Pacific Islands Ocean Observing System (PacIOOS) dataCenter GCMD Data Center Keywords sea_water_temperature sea_water_electrical_conductivity sea_water_turbidity mass_concentration_of_chlorophyll_in_sea_water sea_water_salinity depth latitude longitude time theme CF-1.4 The data may be used and redistributed for free but is not intended for legal use, since it may contain inaccuracies. Neither the data Contributor, University of Hawaii, PacIOOS, NOAA, State of Hawaii nor the United States Government, nor any of their employees or contractors, makes any warranty, express or implied, including warranties of merchantability and fitness for a particular purpose, or assumes any legal liability for the accuracy, completeness, or usefulness, of this information. Pacific Islands Ocean Observing System (PacIOOS) largerWorkCitation project Unidata Common Data Model Point largerWorkCitation project eng climatologyMeteorologyAtmosphere 1 158.22402954101562 158.22402954101562 6.955227375030518 6.955227375030518 seconds 2010-05-07T00:00:00Z 2014-03-17T23:56:00Z -1.0 -1.0 PacIOOS Nearshore Sensor 06: Pohnpei, Micronesia 2011-04-12 creation 2011-04-19 issued 2014-03-18 revision Margaret McManus University of Hawaii mamc@hawaii.edu http://www.soest.hawaii.edu/oceanography/faculty/mcmanus.html http web browser information originator Jim Potemra distributor The nearshore sensors are part of the Pacific Islands Ocean Observing System (PacIOOS) and are designed to measure a variety of ocean parameters at fixed point locations. NS06 is located at the dock in Pohnpei lagoon and is mounted to the bottom in about 1 meter of water. The instrument is a Sea-Bird Electronics model 16+ V2 coupled with a WET Labs ECO-FLNTUS combination sensor. THREDDS OPeNDAP 1 158.22402954101562 158.22402954101562 6.955227375030518 6.955227375030518 2010-05-07T00:00:00Z 2014-03-17T23:56:00Z -1.0 -1.0 tight OPeNDAP Client Access http://oos.soest.hawaii.edu/thredds/dodsC/pacioos/nss/ns06agg OPeNDAP THREDDS OPeNDAP download temp float Temperature (sea_water_temperature) cond float Conductivity (sea_water_electrical_conductivity) turb float Turbidity (sea_water_turbidity) flor float Chlorophyll (mass_concentration_of_chlorophyll_in_sea_water) salt float Salinity (sea_water_salinity) z float depth below mean sea level (depth) lat float Latitude (latitude) lon float Longitude (longitude) time float Time (time) Pacific Islands Ocean Observing System (PacIOOS) jimp@hawaii.edu http://pacioos.org http web browser URL for the data publisher This URL provides contact information for the publisher of this dataset information publisher OPeNDAP http://oos.soest.hawaii.edu/thredds/idd/nss_pacioos.html?dataset=NS06agg THREDDS Catalog This URL provides a catalog page for this dataset within THREDDS Data Server (TDS). download http://oos.soest.hawaii.edu/thredds/dodsC/pacioos/nss/ns06agg.html File Information This URL provides a standard OPeNDAP html interface for selecting data from this dataset. Change the extension to .info for a description of the dataset. download http://pacioos.org/voyager/index.html?b=6.874279%2C158.077126%2C7.050468%2C158.369808&tz=pont&o=qual:2::p0NS06p1 PacIOOS Voyager (Google Maps API) This URL provides a viewer for this dataset. download http://oos.soest.hawaii.edu/dchart/index.html?dsetid=54cd0688ada08d86748b9c5762509f DChart This URL provides a viewer for this dataset. download http://oos.soest.hawaii.edu/erddap/tabledap/nss06_agg.graph?time%2Ctemperature&.draw=lines ERDDAP This URL provides a viewer for this dataset. download http://pacioos.org/focus/waterquality/wq_fsm.php PacIOOS Water Quality Platforms: FSM This URL provides a viewer for this dataset. download dataset UH/SOEST (M. McManus), PacIOOS asset (05/2010) This record was translated from NcML using UnidataDD2MI.xsl Version 2.3 ================================================ FILE: tests/functionaltests/suites/opensearcheo/data/test.xml ================================================ 437ae0a2-06e2-4015-b296-a66e7f407bf2 eng dataset YPAATypaat@ypaat.grpointOfContact NTUAtzotsos@gmail.compointOfContact 2009-10-09 ISO19115 2003/Cor.1:2006 Aerial Photos 2009-10-09creation 437ae0a2-06e2-4015-b296-a66e7f407bf2 T_aerfo_RAS_1991_GR800P001800000011.tif Aerial Photos YPAATypaat@ypaat.growner NTUAtzotsos@hotmail.comuser OrthoimageryGEMET - INSPIRE themes, version 1.02008-06-01publication no conditions apply otherRestrictionsno limitations eng geoscientificInformation 20.0038.0024.0040.00 2009-10-092009-10-09 http://www.ypaat.gr dataset Conformity_001INSPIREINSPIRE2008-05-15publicationSee the referenced specificationtrue test ================================================ FILE: tests/functionaltests/suites/opensearcheo/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true profiles: - apiso logging: level: DEBUG # logfile: /tmp/pycsw.log #federatedcatalogues: # - id: fedcat01 # type: CSW # title: Arctic SDI # url: https://catalogue.arctic-sdi.org/csw # - id: fedcat02 # type: OARec # title: pycsw OGC CITE demo and Reference Implementation # url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-description-document.xml ================================================ pycsw Geospatial pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery https://pycsw.org/img/favicon.ico Kralidis, Tom tomkralidis@gmail.com pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-cloudcover-gt.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-cloudcover-lt-gt.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-cloudcover-lt.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-cloudcover.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-instrument.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-orbitdirection.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-orbitnumber.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-platform.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-processinglevel.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-producttype.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-sensortype.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-snowcover.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-spectralrange.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-start-stop-extent.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/expected/get_opensearch-query-time-extent.xml ================================================ http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.yml pycsw Geospatial Catalogue pycsw ================================================ FILE: tests/functionaltests/suites/opensearcheo/get/requests.txt ================================================ opensearch-description-document,mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities opensearch-query-time-extent,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&time=2009/2015 opensearch-query-start-stop-extent,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&start=2009&stop=2015 opensearch-query-cloudcover,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:cloudCover=0.082857 opensearch-query-cloudcover-lt,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:cloudCover=20[ opensearch-query-cloudcover-gt,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:cloudCover=]20 opensearch-query-cloudcover-lt-gt,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:cloudCover=]0,1[ opensearch-query-instrument,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:instrument=INS-NOBS opensearch-query-orbitdirection,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:orbitDirection=DESCENDING opensearch-query-orbitnumber,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:orbitNumber=50 opensearch-query-processinglevel,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:processingLevel=Level-2A opensearch-query-platform,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:platform=Sentinel-2B opensearch-query-producttype,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:productType=S2MSI2A opensearch-query-sensortype,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:sensorType=S2MSI2A opensearch-query-snowcover,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:snowCover=0.0 opensearch-query-spectralrange,mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&eo:spectralRange=B1 ================================================ FILE: tests/functionaltests/suites/pubsub/conftest.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # Tom Kralidis # # Copyright (c) 2023 Ricardo Garcia Silva # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import pytest @pytest.fixture() def config(): yield { 'server': { 'url': 'http://localhost/pycsw/oarec', 'mimetype': 'application/xml;', 'charset': 'UTF-8', 'encoding': 'UTF-8', 'language': 'en-US', 'maxrecords': '10', 'gzip_compresslevel': '9', 'profiles': [ 'apiso' ] }, 'logging': { 'level': 'ERROR' }, 'manager': { 'transactions': True, 'allowed_ips': [ '127.0.0.1' ] }, 'pubsub': { 'broker': { 'type': 'mqtt', 'url': 'mqtt://localhost:1883' } }, 'metadata': { 'identification': { 'title': 'pycsw Geospatial Catalogue', 'description': 'pycsw is an OARec and OGC CSW server implementation written in Python', # noqa 'keywords': [ 'catalogue', 'discovery', 'metadata' ], 'keywords_type': 'theme', 'fees': 'None', 'accessconstraints': 'None' }, 'provider': { 'name': 'Organization Name', 'url': 'https://pycsw.org/' }, 'contact': { 'name': 'Lastname, Firstname', 'position': 'Position Title', 'address': 'Mailing Address', 'city': 'City', 'stateorprovince': 'Administrative Area', 'postalcode': 'Zip or Postal Code', 'country': 'Country', 'phone': '+xx-xxx-xxx-xxxx', 'fax': '+xx-xxx-xxx-xxxx', 'email': 'you@example.org', 'url': 'Contact URL', 'hours': 'Hours of Service', 'instructions': 'During hours of service. Off on weekends.', 'role': 'pointOfContact' }, 'inspire': { 'enabled': True, 'languages_supported': [ 'eng', 'gre' ], 'default_language': 'eng', 'date': 'YYYY-MM-DD', 'gemet_keywords': [ 'Utility and governmental services' ], 'conformity_service': 'notEvaluated', 'contact_name': 'Organization Name', 'contact_email': 'you@example.org', 'temp_extent': { 'begin': 'YYYY-MM-DD', 'end': 'YYYY-MM-DD' } } }, 'repository': { 'database': 'sqlite:///tests/functionaltests/suites/cite/data/cite.db', # noqa 'table': 'records' } } @pytest.fixture() def config_virtual_collections(config): database = config['repository']['database'] config['repository']['database'] = database.replace('cite.db', 'cite-virtual-collections.db') # noqa return config @pytest.fixture() def sample_record(): yield { "id": "record-123", "conformsTo": [ "http://www.opengis.net/spec/ogcapi-records-1/1.0/req/record-core" ], "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[ [-141, 42], [-141, 84], [-52, 84], [-52, 42], [-141, 42] ]] }, "properties": { "identifier": "3f342f64-9348-11df-ba6a-0014c2c00eab", "title": "title in English", "description": "abstract in English", "themes": [ { "concepts": [ "kw1 in English", "kw2 in English", "kw3 in English" ] }, { "concepts": [ "FOO", "BAR" ], "scheme": "http://example.org/vocab" }, { "concepts": [ "kw1", "kw2" ] } ], "providers": [ { "name": "Environment Canada", "individual": "Tom Kralidis", "positionName": "Senior Systems Scientist", "contactInfo": { "phone": { "office": "+01-123-456-7890" }, "email": { "office": "+01-123-456-7890" }, "address": { "office": { "deliveryPoint": "4905 Dufferin Street", "city": "Toronto", "administrativeArea": "Ontario", "postalCode": "M3H 5T4", "country": "Canada" }, "onlineResource": { "href": "https://www.ec.gc.ca/" } }, "hoursOfService": "0700h - 1500h EST", "contactInstructions": "email", "url": { "rel": "canonical", "type": "text/html", "href": "https://www.ec.gc.ca/" } }, "roles": [ {"name": "pointOfContact"} ] }, { "name": "Environment Canada", "individual": "Tom Kralidis", "positionName": "Senior Systems Scientist", "contactInfo": { "phone": {"office": "+01-123-456-7890"}, "email": {"office": "+01-123-456-7890"}, "address": { "office": { "deliveryPoint": "4905 Dufferin Street", "city": "Toronto", "administrativeArea": "Ontario", "postalCode": "M3H 5T4", "country": "Canada" }, "onlineResource": {"href": "https://www.ec.gc.ca/"} }, "hoursOfService": "0700h - 1500h EST", "contactInstructions": "email", "url": { "rel": "canonical", "type": "text/html", "href": "https://www.ec.gc.ca/" } }, "roles": [ {"name": "distributor"} ] } ], "language": { "code": "en" }, "type": "dataset", "created": "2011-11-11", "updated": "2000-09-01", "rights": "Copyright (c) 2010 Her Majesty the Queen in Right of Canada" # noqa }, "links": [ { "rel": "canonical", "href": "https://example.org/data", "type": "WWW:LINK", "title": "my waf" }, { "rel": "service", "href": "https://example.org/wms", "type": "OGC:WMS", "title": "roads" } ], "time": { "interval": [ "1950-07-31", None ], "resolution": "P1Y" } } ================================================ FILE: tests/functionaltests/suites/pubsub/test_pubsub_functional.py ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2025 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import json import pytest from pycsw.ogc.api.records import API pytestmark = pytest.mark.functional def test_landing_page(config): api = API(config) headers, status, content = api.landing_page({}, {'f': 'json'}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert status == 200 assert len(content['links']) == 16 links = ( api.config['server']['url'], api.config['pubsub']['broker']['url'] ) for link in content['links']: assert link['href'].startswith(links) headers, status, content = api.landing_page({}, {'f': 'html'}) assert status == 200 assert headers['Content-Type'] == 'text/html' def test_conformance(config): api = API(config) headers, status, content = api.conformance({}, {}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert len(content['conformsTo']) == 16 ================================================ FILE: tests/functionaltests/suites/repofilter/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records filter: "type = 'http://purl.org/dc/dcmitype/Dataset'" ================================================ FILE: tests/functionaltests/suites/repofilter/expected/post_GetRecordById-masked.xml ================================================ ================================================ FILE: tests/functionaltests/suites/repofilter/expected/post_GetRecords-all.xml ================================================ urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms FI-ES Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 2005-10-24 44.792 -6.171 51.126 -2.228 ================================================ FILE: tests/functionaltests/suites/repofilter/post/GetRecordById-masked.xml ================================================ urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec summary ================================================ FILE: tests/functionaltests/suites/repofilter/post/GetRecords-all.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/sru/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/sru/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/sru/expected/get_explain.xml ================================================ 1.1 XML http://explain.z3950.org/dtd/2.1/ PYCSW_HOST PYCSW_PORT pycsw pycsw Geospatial Catalogue pycsw is an OARec and OGC CSW server implementation written in Python abstract abstract contributor contributor creator creator date date format format identifier identifier language language modified modified publisher publisher relation relation rights rights source source subject subject title title type type title222 Simple Dublin Core 0 ================================================ FILE: tests/functionaltests/suites/sru/expected/get_search.xml ================================================ 1.1 5 ================================================ FILE: tests/functionaltests/suites/sru/expected/get_search_cql.xml ================================================ 1.1 2 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image -2 info:srw/schema/1/dc-v1.1 xml urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 Lorem ipsum dolor sit amet http://purl.org/dc/dcmitype/Image -1 info:srw/schema/1/dc-v1.1 xml ================================================ FILE: tests/functionaltests/suites/sru/expected/get_search_maxrecords.xml ================================================ 1.1 5 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image 1 info:srw/schema/1/dc-v1.1 xml urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset 2 info:srw/schema/1/dc-v1.1 xml ================================================ FILE: tests/functionaltests/suites/sru/expected/get_search_startrecord_maxrecords.xml ================================================ 1.1 5 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image 1 info:srw/schema/1/dc-v1.1 xml urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset 2 info:srw/schema/1/dc-v1.1 xml ================================================ FILE: tests/functionaltests/suites/sru/get/requests.txt ================================================ explain,mode=sru search,mode=sru&version=1.1&operation=searchRetrieve&query=lor search_maxrecords,mode=sru&operation=searchRetrieve&query=lor&maximumRecords=2 search_startrecord_maxrecords,mode=sru&operation=searchRetrieve&query=lor&maximumRecords=2&startRecord=1 search_cql,mode=sru&operation=searchRetrieve&query=dc:title%20like%20'%lor%'&maximumRecords=5 ================================================ FILE: tests/functionaltests/suites/stablesort/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true logging: level: DEBUG federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records stable_sort: true ================================================ FILE: tests/functionaltests/suites/stablesort/expected/get_GetRecords-page1.xml ================================================ urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db http://purl.org/dc/dcmitype/Text Fuscé vitae ligulä 2003-05-09 Land titles text/rtf Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.042 13.754 68.410 17.920 ================================================ FILE: tests/functionaltests/suites/stablesort/expected/get_GetRecords-page2.xml ================================================ urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a http://purl.org/dc/dcmitype/Service Physiography Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam. urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e http://purl.org/dc/dcmitype/Image image/jp2 Vestibulum massa purus urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc ================================================ FILE: tests/functionaltests/suites/stablesort/expected/get_GetRecords-page3.xml ================================================ urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 http://purl.org/dc/dcmitype/Image Lorem ipsum dolor sit amet image/jpeg IT-FI urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 http://purl.org/dc/dcmitype/Dataset Physiography-Landforms FI-ES Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 http://purl.org/dc/dcmitype/Dataset Mauris sed neque Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 2006-03-26 47.595 -4.097 51.217 0.889 urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc http://purl.org/dc/dcmitype/Dataset Ñunç elementum Hydrography-Oceanographic 2005-10-24 44.792 -6.171 51.126 -2.228 ================================================ FILE: tests/functionaltests/suites/stablesort/get/requests.txt ================================================ GetRecords-page1,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:type:D&maxRecords=4&startPosition=1 GetRecords-page2,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:type:D&maxRecords=4&startPosition=5 GetRecords-page3,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:type:D&maxRecords=4&startPosition=9 ================================================ FILE: tests/functionaltests/suites/stac_api/conftest.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # Tom Kralidis # # Copyright (c) 2023 Ricardo Garcia Silva # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import pytest @pytest.fixture() def config(): yield { 'server': { 'url': 'http://localhost/pycsw/oarec', 'mimetype': 'application/xml;', 'charset': 'UTF-8', 'encoding': 'UTF-8', 'language': 'en-US', 'maxrecords': '10', 'gzip_compresslevel': '9', 'profiles': [ 'apiso' ] }, 'logging': { 'level': 'ERROR', }, 'manager': { 'transactions': True, 'allowed_ips': '127.0.0.1' }, 'metadata': { 'identification': { 'title': 'pycsw Geospatial Catalogue', 'description': 'pycsw is an OARec and OGC CSW server implementation written in Python', 'keywords': [ 'catalogue', 'discovery', 'metadata' ], 'keywords_type': 'theme', 'fees': 'None', 'accessconstraints': 'None' }, 'provider': { 'name': 'Organization Name', 'url': 'https://pycsw.org/', }, 'contact': { 'name': 'Lastname, Firstname', 'position': 'Position Title', 'address': 'Mailing Address', 'city': 'City', 'stateorprovince': 'Administrative Area', 'postalcode': 'Zip or Postal Code', 'country': 'Country', 'phone': '+xx-xxx-xxx-xxxx', 'fax': '+xx-xxx-xxx-xxxx', 'email': 'you@example.org', 'url': 'Contact URL', 'hours': 'Hours of Service', 'instructions': 'During hours of service. Off on weekends.', 'role': 'pointOfContact', }, 'inspire': { 'enabled': True, 'languages_supported': [ 'eng', 'gre' ], 'default_language': 'eng', 'date': 'YYYY-MM-DD', 'gemet_keywords': 'Utility and governmental services', 'conformity_service': 'notEvaluated', 'contact_name': 'Organization Name', 'contact_email': 'you@example.org', 'temp_extent': { 'begin': 'YYYY-MM-DD/YYYY-MM-DD', 'end': 'YYYY-MM-DD/YYYY-MM-DD' } } }, 'repository': { 'database': 'sqlite:///tests/functionaltests/suites/stac_api/data/records.db', 'table': 'records', } } @pytest.fixture() def sample_collection(): yield { 'assets': { '6072a0ee-0fff-4755-9cc7-660711de9b35': { 'href': 'https://api.up42.com/v2/assets/6072a0ee-0fff-4755-9cc7-660711de9b35', 'title': 'Original Delivery', 'roles': [ 'data', 'original' ], 'type': 'application/zip' } }, 'links': [ { 'rel': 'self', 'href': 'https://api.up42.dev/catalog/hosts/oneatlas/stac/search' } ], 'stac_extensions': [ 'https://api.up42.com/stac-extensions/up42-order/v1.0.0/schema.json' ], 'title': 'ORT_SPOT7_20190922_094920500_000', 'description': 'High-resolution 1.5m SPOT images acquired daily on a global basis. The datasets are available starting from 2012.', 'keywords': [ 'berlin', 'optical' ], 'license': 'proprietary', 'providers': [ { 'name': 'Airbus', 'roles': [ 'producer' ], 'url': 'https://www.airbus.com' } ], 'extent': { 'spatial': { 'bbox': [ [ -86.07022916666666, 11.900145833333333, -86.05072916666667, 11.942270833333334 ] ] }, 'temporal': { 'interval': [ [ '2017-01-01T00:00:00Z', '2021-12-31T00:00:00Z' ] ] } }, 'stac_version': '1.0.0', 'type': 'Collection', 'id': '123e4567-e89b-12d3-a456-426614174000' } @pytest.fixture() def sample_item(): yield { 'id': '20201211_223832_CS2', 'stac_version': '1.0.0', 'type': 'Feature', 'geometry': None, 'properties': { 'datetime': '2020-12-11T22:38:32.125000Z' }, 'collection': 'simple-collection', 'links': [{ 'rel': 'collection', 'href': './collection.json', 'type': 'application/json', 'title': 'Simple Example Collection' }, { 'rel': 'root', 'href': './collection.json', 'type': 'application/json', 'title': 'Simple Example Collection' }, { 'rel': 'parent', 'href': './collection.json', 'type': 'application/json', 'title': 'Simple Example Collection' }], 'assets': { 'visual': { 'href': 'https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.tif', 'type': 'image/tiff; application=geotiff; profile=cloud-optimized', 'title': '3-Band Visual', 'roles': [ 'visual' ] }, 'thumbnail': { 'href': 'https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.jpg', 'title': 'Thumbnail', 'type': 'image/jpeg', 'roles': [ 'thumbnail' ] } } } @pytest.fixture() def sample_item_collection(): yield { 'type': 'FeatureCollection', 'features': [{ 'id': '20201211_223832_CS2', 'stac_version': '1.0.0', 'type': 'Feature', 'geometry': None, 'properties': { 'datetime': '2020-12-11T22:38:32.125000Z' }, 'collection': 'simple-collection', 'links': [{ 'rel': 'collection', 'href': './collection.json', 'type': 'application/json', 'title': 'Simple Example Collection' }, { 'rel': 'root', 'href': './collection.json', 'type': 'application/json', 'title': 'Simple Example Collection' }, { 'rel': 'parent', 'href': './collection.json', 'type': 'application/json', 'title': 'Simple Example Collection' }], 'assets': { 'visual': { 'href': 'https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.tif', 'type': 'image/tiff; application=geotiff; profile=cloud-optimized', 'title': '3-Band Visual', 'roles': [ 'visual' ] }, 'thumbnail': { 'href': 'https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.jpg', 'title': 'Thumbnail', 'type': 'image/jpeg', 'roles': [ 'thumbnail' ] } } }, { 'id': '20201212_223832_CS2', 'stac_version': '1.0.0', 'type': 'Feature', 'geometry': None, 'properties': { 'datetime': '2020-12-12T22:38:32.125000Z' }, 'collection': 'simple-collection', 'links': [{ 'rel': 'collection', 'href': './collection.json', 'type': 'application/json', 'title': 'Simple Example Collection' }, { 'rel': 'root', 'href': './collection.json', 'type': 'application/json', 'title': 'Simple Example Collection' }, { 'rel': 'parent', 'href': './collection.json', 'type': 'application/json', 'title': 'Simple Example Collection' }], 'assets': { 'visual': { 'href': 'https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.tif', 'type': 'image/tiff; application=geotiff; profile=cloud-optimized', 'title': '3-Band Visual', 'roles': [ 'visual' ] }, 'thumbnail': { 'href': 'https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.jpg', 'title': 'Thumbnail', 'type': 'image/jpeg', 'roles': [ 'thumbnail' ] } } }] } ================================================ FILE: tests/functionaltests/suites/stac_api/data/20201211_223832_CS21.json ================================================ { "stac_version": "1.0.0", "stac_extensions": [ "https://stac-extensions.github.io/view/v1.0.0/schema.json" ], "type": "Feature", "id": "20201211_223832_CS21", "bbox": [ 172.91173669923782, 1.3438851951615003, 172.95469614953714, 1.3690476620161975 ], "geometry": { "type": "Polygon", "coordinates": [ [ [ 172.91173669923782, 1.3438851951615003 ], [ 172.95469614953714, 1.3438851951615003 ], [ 172.95469614953714, 1.3690476620161975 ], [ 172.91173669923782, 1.3690476620161975 ], [ 172.91173669923782, 1.3438851951615003 ] ] ] }, "properties": { "datetime": "2020-12-11T22:38:32.125Z", "created": "2020-12-12T01:48:13.725Z", "updated": "2020-12-12T01:48:13.725Z", "platform": "cool_sat2", "instruments": [ "cool_sensor_v1" ], "gsd": 0.66, "view:sun_elevation": 54.9, "view:off_nadir": 3.8, "view:sun_azimuth": 135.7 }, "links": [], "assets": { "analytic": { "href": "https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2_analytic.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "title": "4-Band Analytic", "roles": [ "data" ] }, "thumbnail": { "href": "https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.jpg", "title": "Thumbnail", "type": "image/png", "roles": [ "thumbnail" ] }, "visual": { "href": "https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "title": "3-Band Visual", "roles": [ "visual" ] } } } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2A_MSIL2A_20241128T092331_R093_T34SEJ_20241128T122153.json ================================================ { "id": "S2A_MSIL2A_20241128T092331_R093_T34SEJ_20241128T122153", "bbox": [ 20.9997665, 38.754036, 22.2812803, 39.7502679 ], "type": "Feature", "links": [ { "rel": "collection", "type": "application/json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/collections/sentinel-2-l2a" }, { "rel": "parent", "type": "application/json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/collections/sentinel-2-l2a" }, { "rel": "root", "type": "application/json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/" }, { "rel": "self", "type": "application/geo+json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/collections/sentinel-2-l2a/items/S2A_MSIL2A_20241128T092331_R093_T34SEJ_20241128T122153" }, { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "preview", "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/map?collection=sentinel-2-l2a&item=S2A_MSIL2A_20241128T092331_R093_T34SEJ_20241128T122153", "title": "Map of item", "type": "text/html" } ], "assets": { "AOT": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R10m/T34SEJ_20241128T092331_AOT_10m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 499980, 0, -10, 4400040 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Aerosol optical thickness (AOT)" }, "B01": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R60m/T34SEJ_20241128T092331_B01_60m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 1830, 1830 ], "proj:transform": [ 60, 0, 499980, 0, -60, 4400040 ], "gsd": 60, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ] }, "B02": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R10m/T34SEJ_20241128T092331_B02_10m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 499980, 0, -10, 4400040 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ] }, "B03": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R10m/T34SEJ_20241128T092331_B03_10m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 499980, 0, -10, 4400040 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ] }, "B04": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R10m/T34SEJ_20241128T092331_B04_10m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 499980, 0, -10, 4400040 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ] }, "B05": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R20m/T34SEJ_20241128T092331_B05_20m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 499980, 0, -20, 4400040 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ] }, "B06": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R20m/T34SEJ_20241128T092331_B06_20m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 499980, 0, -20, 4400040 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ] }, "B07": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R20m/T34SEJ_20241128T092331_B07_20m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 499980, 0, -20, 4400040 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ] }, "B08": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R10m/T34SEJ_20241128T092331_B08_10m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 499980, 0, -10, 4400040 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ] }, "B09": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R60m/T34SEJ_20241128T092331_B09_60m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 1830, 1830 ], "proj:transform": [ 60, 0, 499980, 0, -60, 4400040 ], "gsd": 60, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ] }, "B11": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R20m/T34SEJ_20241128T092331_B11_20m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 499980, 0, -20, 4400040 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ] }, "B12": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R20m/T34SEJ_20241128T092331_B12_20m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 499980, 0, -20, 4400040 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ] }, "B8A": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R20m/T34SEJ_20241128T092331_B8A_20m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 499980, 0, -20, 4400040 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ] }, "SCL": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R20m/T34SEJ_20241128T092331_SCL_20m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 499980, 0, -20, 4400040 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Scene classfication map (SCL)" }, "WVP": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R10m/T34SEJ_20241128T092331_WVP_10m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 499980, 0, -10, 4400040 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Water vapour (WVP)" }, "visual": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/IMG_DATA/R10m/T34SEJ_20241128T092331_TCI_10m.tif", "proj:bbox": [ 499980, 4290240, 609780, 4400040 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 499980, 0, -10, 4400040 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ] }, "safe-manifest": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ], "title": "SAFE manifest" }, "granule-metadata": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/GRANULE/L2A_T34SEJ_A049282_20241128T092331/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ], "title": "Granule metadata" }, "inspire-metadata": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ], "title": "INSPIRE metadata" }, "product-metadata": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ], "title": "Product metadata" }, "datastrip-metadata": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/EJ/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE/DATASTRIP/DS_2APS_20241128T122153_S20241128T092331/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ], "title": "Datastrip metadata" }, "tilejson": { "title": "TileJSON with default rendering", "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/tilejson.json?collection=sentinel-2-l2a&item=S2A_MSIL2A_20241128T092331_R093_T34SEJ_20241128T122153&assets=visual&asset_bidx=visual%7C1%2C2%2C3&nodata=0&format=png", "type": "application/json", "roles": [ "tiles" ] }, "rendered_preview": { "title": "Rendered preview", "rel": "preview", "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=sentinel-2-l2a&item=S2A_MSIL2A_20241128T092331_R093_T34SEJ_20241128T122153&assets=visual&asset_bidx=visual%7C1%2C2%2C3&nodata=0&format=png", "roles": [ "overview" ], "type": "image/png" } }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 20.9997665, 39.7502679 ], [ 22.2812803, 39.7431962 ], [ 22.2634032, 38.754036 ], [ 20.9997698, 38.7608645 ], [ 20.9997665, 39.7502679 ] ] ] }, "collection": "sentinel-2-l2a", "properties": { "license": "other", "datetime": "2024-11-28T09:23:31.024000Z", "platform": "Sentinel-2A", "proj:epsg": 32634, "instruments": [ "msi" ], "s2:mgrs_tile": "34SEJ", "constellation": "Sentinel 2", "s2:granule_id": "S2A_OPER_MSI_L2A_TL_2APS_20241128T122153_A049282_T34SEJ_N05.11", "eo:cloud_cover": 5.818298, "s2:datatake_id": "GS2A_20241128T092331_049282_N05.11", "s2:product_uri": "S2A_MSIL2A_20241128T092331_N0511_R093_T34SEJ_20241128T122153.SAFE", "s2:datastrip_id": "S2A_OPER_MSI_L2A_DS_2APS_20241128T122153_S20241128T092331_N05.11", "s2:product_type": "S2MSI2A", "sat:orbit_state": "descending", "s2:datatake_type": "INS-NOBS", "s2:generation_time": "2024-11-28T12:21:53.000000Z", "sat:relative_orbit": 93, "s2:water_percentage": 1.403924, "s2:mean_solar_zenith": 61.8754834452706, "s2:mean_solar_azimuth": 166.296580755901, "s2:processing_baseline": "05.11", "s2:snow_ice_percentage": 0, "s2:vegetation_percentage": 37.782255, "s2:thin_cirrus_percentage": 1.530549, "s2:cloud_shadow_percentage": 0.415171, "s2:nodata_pixel_percentage": 3e-06, "s2:unclassified_percentage": 1.499892, "s2:not_vegetated_percentage": 38.761142, "s2:degraded_msi_data_percentage": 0.0001, "s2:high_proba_clouds_percentage": 1.766358, "s2:reflectance_conversion_factor": 1.02646478392633, "s2:medium_proba_clouds_percentage": 2.521392, "s2:saturated_defective_pixel_percentage": 0 }, "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.0.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.0.0/schema.json" ], "stac_version": "1.0.0" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2A_MSIL2A_20241128T092331_R093_T34SFH_20241128T122153.json ================================================ { "id": "S2A_MSIL2A_20241128T092331_R093_T34SFH_20241128T122153", "bbox": [ 22.1367176, 37.8353021, 23.4167322, 38.8433146 ], "type": "Feature", "links": [ { "rel": "collection", "type": "application/json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/collections/sentinel-2-l2a" }, { "rel": "parent", "type": "application/json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/collections/sentinel-2-l2a" }, { "rel": "root", "type": "application/json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/" }, { "rel": "self", "type": "application/geo+json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/collections/sentinel-2-l2a/items/S2A_MSIL2A_20241128T092331_R093_T34SFH_20241128T122153" }, { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "preview", "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/map?collection=sentinel-2-l2a&item=S2A_MSIL2A_20241128T092331_R093_T34SFH_20241128T122153", "title": "Map of item", "type": "text/html" } ], "assets": { "AOT": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R10m/T34SFH_20241128T092331_AOT_10m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 600000, 0, -10, 4300020 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Aerosol optical thickness (AOT)" }, "B01": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R60m/T34SFH_20241128T092331_B01_60m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 1830, 1830 ], "proj:transform": [ 60, 0, 600000, 0, -60, 4300020 ], "gsd": 60, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ] }, "B02": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R10m/T34SFH_20241128T092331_B02_10m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 600000, 0, -10, 4300020 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ] }, "B03": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R10m/T34SFH_20241128T092331_B03_10m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 600000, 0, -10, 4300020 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ] }, "B04": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R10m/T34SFH_20241128T092331_B04_10m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 600000, 0, -10, 4300020 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ] }, "B05": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R20m/T34SFH_20241128T092331_B05_20m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 600000, 0, -20, 4300020 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ] }, "B06": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R20m/T34SFH_20241128T092331_B06_20m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 600000, 0, -20, 4300020 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ] }, "B07": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R20m/T34SFH_20241128T092331_B07_20m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 600000, 0, -20, 4300020 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ] }, "B08": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R10m/T34SFH_20241128T092331_B08_10m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 600000, 0, -10, 4300020 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ] }, "B09": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R60m/T34SFH_20241128T092331_B09_60m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 1830, 1830 ], "proj:transform": [ 60, 0, 600000, 0, -60, 4300020 ], "gsd": 60, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ] }, "B11": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R20m/T34SFH_20241128T092331_B11_20m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 600000, 0, -20, 4300020 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ] }, "B12": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R20m/T34SFH_20241128T092331_B12_20m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 600000, 0, -20, 4300020 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ] }, "B8A": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R20m/T34SFH_20241128T092331_B8A_20m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 600000, 0, -20, 4300020 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ] }, "SCL": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R20m/T34SFH_20241128T092331_SCL_20m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 5490, 5490 ], "proj:transform": [ 20, 0, 600000, 0, -20, 4300020 ], "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Scene classfication map (SCL)" }, "WVP": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R10m/T34SFH_20241128T092331_WVP_10m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 600000, 0, -10, 4300020 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Water vapour (WVP)" }, "visual": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/IMG_DATA/R10m/T34SFH_20241128T092331_TCI_10m.tif", "proj:bbox": [ 600000, 4190220, 709800, 4300020 ], "proj:shape": [ 10980, 10980 ], "proj:transform": [ 10, 0, 600000, 0, -10, 4300020 ], "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ] }, "safe-manifest": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ], "title": "SAFE manifest" }, "granule-metadata": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/GRANULE/L2A_T34SFH_A049282_20241128T092331/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ], "title": "Granule metadata" }, "inspire-metadata": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ], "title": "INSPIRE metadata" }, "product-metadata": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ], "title": "Product metadata" }, "datastrip-metadata": { "href": "https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/34/S/FH/2024/11/28/S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE/DATASTRIP/DS_2APS_20241128T122153_S20241128T092331/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ], "title": "Datastrip metadata" }, "tilejson": { "title": "TileJSON with default rendering", "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/tilejson.json?collection=sentinel-2-l2a&item=S2A_MSIL2A_20241128T092331_R093_T34SFH_20241128T122153&assets=visual&asset_bidx=visual%7C1%2C2%2C3&nodata=0&format=png", "type": "application/json", "roles": [ "tiles" ] }, "rendered_preview": { "title": "Rendered preview", "rel": "preview", "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=sentinel-2-l2a&item=S2A_MSIL2A_20241128T092331_R093_T34SFH_20241128T122153&assets=visual&asset_bidx=visual%7C1%2C2%2C3&nodata=0&format=png", "roles": [ "overview" ], "type": "image/png" } }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 22.1522905, 38.8433146 ], [ 23.4167322, 38.8239923 ], [ 23.3841, 37.8353021 ], [ 22.1367176, 37.853955 ], [ 22.1522905, 38.8433146 ] ] ] }, "collection": "sentinel-2-l2a", "properties": { "datetime": "2024-11-28T09:23:31.024000Z", "platform": "Sentinel-2A", "proj:epsg": 32634, "instruments": [ "msi" ], "s2:mgrs_tile": "34SFH", "constellation": "Sentinel 2", "s2:granule_id": "S2A_OPER_MSI_L2A_TL_2APS_20241128T122153_A049282_T34SFH_N05.11", "eo:cloud_cover": 15.038629, "s2:datatake_id": "GS2A_20241128T092331_049282_N05.11", "s2:product_uri": "S2A_MSIL2A_20241128T092331_N0511_R093_T34SFH_20241128T122153.SAFE", "s2:datastrip_id": "S2A_OPER_MSI_L2A_DS_2APS_20241128T122153_S20241128T092331_N05.11", "s2:product_type": "S2MSI2A", "sat:orbit_state": "descending", "s2:datatake_type": "INS-NOBS", "s2:generation_time": "2024-11-28T12:21:53.000000Z", "sat:relative_orbit": 93, "s2:water_percentage": 24.954174, "s2:mean_solar_zenith": 60.7763129418115, "s2:mean_solar_azimuth": 167.418127981186, "s2:processing_baseline": "05.11", "s2:snow_ice_percentage": 0, "s2:vegetation_percentage": 15.50326, "s2:thin_cirrus_percentage": 3.911178, "s2:cloud_shadow_percentage": 1.459325, "s2:nodata_pixel_percentage": 0, "s2:unclassified_percentage": 5.811699, "s2:not_vegetated_percentage": 32.038176, "s2:degraded_msi_data_percentage": 0.0228, "s2:high_proba_clouds_percentage": 4.16998, "s2:reflectance_conversion_factor": 1.02646478392633, "s2:medium_proba_clouds_percentage": 6.957472, "s2:saturated_defective_pixel_percentage": 0 }, "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.0.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.0.0/schema.json" ], "stac_version": "1.0.0" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 40.8408, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE", "s2:generation_time": "2019-09-10T12:09:10.000000Z", "s2:processing_baseline": "02.08", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.08", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_MTI__20190910T120910_S20190910T095200_N02.08", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_MTI__20190910T120910_A013118_T33TWN_N02.08", "s2:mgrs_tile": "33TWN", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:mean_solar_zenith": 44.0991584183932, "s2:mean_solar_azimuth": 159.531813362975, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.444861597282598, 46.86290010560831 ], [ 15.31183071907207, 46.88149751987032 ], [ 15.338289611196274, 46.95521678246418 ], [ 15.390966472422209, 47.10161813498074 ], [ 15.444791927935675, 47.247653834030366 ], [ 15.497949881270555, 47.393882520175886 ], [ 15.549772019723136, 47.54053618762919 ], [ 15.605219911107202, 47.68629327930668 ], [ 15.657081905205992, 47.83307797270472 ], [ 15.663067914137011, 47.84946349842912 ], [ 16.467277376768234, 47.844325046514086 ], [ 16.440149824410025, 46.85663988190739 ], [ 15.444861597282598, 46.86290010560831 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/DATASTRIP/DS_MTI__20190910T120910_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE/S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.31183071907207, 46.85663988190739, 16.467277376768234, 47.84946349842912 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 85.054, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE", "s2:generation_time": "2019-09-10T12:09:10.000000Z", "s2:processing_baseline": "02.08", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.08", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_MTI__20190910T120910_S20190910T095200_N02.08", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_MTI__20190910T120910_A013118_T33TXN_N02.08", "s2:mgrs_tile": "33TXN", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:mean_solar_zenith": 43.7864951023904, "s2:mean_solar_azimuth": 161.360399994209, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.33660021997006, 47.84592105208886 ], [ 17.80284668292451, 47.81947440295927 ], [ 17.751084998620154, 46.83262831925138 ], [ 16.31188688551243, 46.85818197246455 ], [ 16.33660021997006, 47.84592105208886 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/DATASTRIP/DS_MTI__20190910T120910_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910.SAFE/S2B_MSIL1C_20190910T095029_N0208_R079_T33TXN_20190910T120910-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.31188688551243, 46.83262831925138, 17.80284668292451, 47.84592105208886 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 13.7376, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE", "s2:generation_time": "2019-09-10T12:09:10.000000Z", "s2:processing_baseline": "02.08", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.08", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_MTI__20190910T120910_S20190910T095200_N02.08", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_MTI__20190910T120910_A013118_T33UWP_N02.08", "s2:mgrs_tile": "33UWP", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:mean_solar_zenith": 44.9536568849222, "s2:mean_solar_azimuth": 159.782654740994, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.631662816257208, 47.76113447645779 ], [ 15.657081905205992, 47.83307797270472 ], [ 15.710570169434488, 47.97949160816187 ], [ 15.764039003164896, 48.126009379104055 ], [ 15.81778554333848, 48.272570340647 ], [ 15.872493644825884, 48.41894350808384 ], [ 15.92758789432043, 48.56524552456526 ], [ 15.982974989379908, 48.71149865233935 ], [ 15.996305449661863, 48.74655676308699 ], [ 16.4932694755772, 48.7433372246506 ], [ 16.464786866939885, 47.75581864580811 ], [ 15.631662816257208, 47.76113447645779 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/DATASTRIP/DS_MTI__20190910T120910_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910.SAFE/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWP_20190910T120910-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.631662816257208, 47.75581864580811, 16.4932694755772, 48.74655676308699 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 39.4785, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE", "s2:generation_time": "2019-09-10T12:09:10.000000Z", "s2:processing_baseline": "02.08", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.08", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_MTI__20190910T120910_S20190910T095200_N02.08", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_MTI__20190910T120910_A013118_T33UWQ_N02.08", "s2:mgrs_tile": "33UWQ", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:mean_solar_zenith": 45.8094070076583, "s2:mean_solar_azimuth": 160.022349418, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.96301731225171, 48.658799143546375 ], [ 15.982974989379908, 48.71149865233935 ], [ 16.038555992497677, 48.85767252192476 ], [ 16.094047130559076, 49.003782869561206 ], [ 16.14979761650124, 49.149814637638734 ], [ 16.205748946304094, 49.29585740293125 ], [ 16.262186431449578, 49.44186226432437 ], [ 16.318477128826668, 49.58796090169242 ], [ 16.340298237046024, 49.643920862317806 ], [ 16.520595653725128, 49.64273706516441 ], [ 16.49066964052278, 48.65538534877128 ], [ 15.96301731225171, 48.658799143546375 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/DATASTRIP/DS_MTI__20190910T120910_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE/S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.96301731225171, 48.65538534877128, 16.520595653725128, 49.643920862317806 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 42.5064, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE", "s2:generation_time": "2019-09-10T12:09:10.000000Z", "s2:processing_baseline": "02.08", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.08", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_MTI__20190910T120910_S20190910T095200_N02.08", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_MTI__20190910T120910_A013118_T33UXP_N02.08", "s2:mgrs_tile": "33UXP", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:mean_solar_zenith": 44.6441560946082, "s2:mean_solar_azimuth": 161.618278923701, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.360279246283664, 48.74498411169783 ], [ 17.852438708473066, 48.71769475117851 ], [ 17.798094715302927, 47.73104447774509 ], [ 16.3343313489668, 47.75740973734738 ], [ 16.360279246283664, 48.74498411169783 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/DATASTRIP/DS_MTI__20190910T120910_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910.SAFE/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXP_20190910T120910-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.3343313489668, 47.73104447774509, 17.852438708473066, 48.74498411169783 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 30.1177, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE", "s2:generation_time": "2019-09-10T12:09:10.000000Z", "s2:processing_baseline": "02.08", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.08", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_MTI__20190910T120910_S20190910T095200_N02.08", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_MTI__20190910T120910_A013118_T33UXQ_N02.08", "s2:mgrs_tile": "33UXQ", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:mean_solar_zenith": 45.5029104836805, "s2:mean_solar_azimuth": 161.866690183624, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.3851737331767, 49.64443670244057 ], [ 17.904572762902152, 49.61627372192671 ], [ 17.847478451946774, 48.62982157570405 ], [ 16.357910769851937, 48.657027178567795 ], [ 16.3851737331767, 49.64443670244057 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/DATASTRIP/DS_MTI__20190910T120910_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C/2019/09/10/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE/S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.357910769851937, 48.62982157570405, 17.904572762902152, 49.64443670244057 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 64.2267135920248, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE", "s2:generation_time": "2023-04-29T15:13:37.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_S2RP_20230429T151337_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_S2RP_20230429T151337_A013118_T33TWN_N05.00", "s2:mgrs_tile": "33TWN", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0078, "s2:mean_solar_zenith": 44.0990034305175, "s2:mean_solar_azimuth": 159.532696066021, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.445301346124024, 46.86289733964962 ], [ 15.311863606240896, 46.88155190097966 ], [ 15.338319066528848, 46.955271231045074 ], [ 15.390995983857032, 47.101672701706896 ], [ 15.444822021173453, 47.247708340802895 ], [ 15.497976349912156, 47.39393813805563 ], [ 15.549799967027868, 47.540591585633614 ], [ 15.605214478403314, 47.68635775881352 ], [ 15.657120560294516, 47.833130750240834 ], [ 15.663088212288423, 47.8494633687352 ], [ 16.467277376768234, 47.844325046514086 ], [ 16.440149824410025, 46.85663988190739 ], [ 15.445301346124024, 46.86289733964962 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/DATASTRIP/DS_S2RP_20230429T151337_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/GRANULE/L1C_T33TWN_A013118_20190910T095200/IMG_DATA/T33TWN_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337.SAFE/S2B_MSIL1C_20190910T095029_N0500_R079_T33TWN_20230429T151337-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.311863606240896, 46.85663988190739, 16.467277376768234, 47.8494633687352 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 98.647794798292, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE", "s2:generation_time": "2023-04-29T15:13:37.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_S2RP_20230429T151337_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_S2RP_20230429T151337_A013118_T33TXN_N05.00", "s2:mgrs_tile": "33TXN", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0104, "s2:mean_solar_zenith": 43.7863531473642, "s2:mean_solar_azimuth": 161.36129143083, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.33660021997006, 47.84592105208886 ], [ 17.80284668292451, 47.81947440295927 ], [ 17.751084998620154, 46.83262831925138 ], [ 16.31188688551243, 46.85818197246455 ], [ 16.33660021997006, 47.84592105208886 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/DATASTRIP/DS_S2RP_20230429T151337_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/GRANULE/L1C_T33TXN_A013118_20190910T095200/IMG_DATA/T33TXN_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337.SAFE/S2B_MSIL1C_20190910T095029_N0500_R079_T33TXN_20230429T151337-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.31188688551243, 46.83262831925138, 17.80284668292451, 47.84592105208886 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 28.8718910052556, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE", "s2:generation_time": "2023-04-29T15:13:37.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_S2RP_20230429T151337_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_S2RP_20230429T151337_A013118_T33UWP_N05.00", "s2:mgrs_tile": "33UWP", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0001, "s2:mean_solar_zenith": 44.9535062944708, "s2:mean_solar_azimuth": 159.783525917098, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.6316591777781, 47.76113449967347 ], [ 15.657120560294516, 47.833130750240834 ], [ 15.710616804532526, 47.97954239571095 ], [ 15.764066021857507, 48.12606560428376 ], [ 15.817813091177218, 48.2726265904545 ], [ 15.872519109449508, 48.41900045837953 ], [ 15.927608933566882, 48.56530379366712 ], [ 15.982996310908666, 48.711556982150206 ], [ 15.996306617907225, 48.74655675551862 ], [ 16.4932694755772, 48.7433372246506 ], [ 16.464786866939885, 47.75581864580811 ], [ 15.6316591777781, 47.76113449967347 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/DATASTRIP/DS_S2RP_20230429T151337_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/GRANULE/L1C_T33UWP_A013118_20190910T095200/IMG_DATA/T33UWP_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337.SAFE/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWP_20230429T151337-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.6316591777781, 47.75581864580811, 16.4932694755772, 48.74655675551862 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 59.3207671111008, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE", "s2:generation_time": "2023-04-29T15:13:37.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_S2RP_20230429T151337_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_S2RP_20230429T151337_A013118_T33UWQ_N05.00", "s2:mgrs_tile": "33UWQ", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0001, "s2:mean_solar_zenith": 45.8092607157278, "s2:mean_solar_azimuth": 160.023209526894, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.96301645244071, 48.658799149109164 ], [ 15.982996310908666, 48.711556982150206 ], [ 16.038585054609282, 48.857728924808406 ], [ 16.094078869579587, 49.003838699992016 ], [ 16.149831938493833, 49.1498699202275 ], [ 16.205776390297686, 49.29591464931502 ], [ 16.2622273238065, 49.44191609181968 ], [ 16.318508423928247, 49.5880174129141 ], [ 16.3403037294286, 49.64392082625591 ], [ 16.520595653725128, 49.64273706516441 ], [ 16.49066964052278, 48.65538534877128 ], [ 15.96301645244071, 48.658799149109164 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/DATASTRIP/DS_S2RP_20230429T151337_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/GRANULE/L1C_T33UWQ_A013118_20190910T095200/IMG_DATA/T33UWQ_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE/S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.96301645244071, 48.65538534877128, 16.520595653725128, 49.64392082625591 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 51.9659291110514, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE", "s2:generation_time": "2023-04-29T15:13:37.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_S2RP_20230429T151337_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_S2RP_20230429T151337_A013118_T33UXP_N05.00", "s2:mgrs_tile": "33UXP", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0108, "s2:mean_solar_zenith": 44.6440183841524, "s2:mean_solar_azimuth": 161.619158319578, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.360279246283664, 48.74498411169783 ], [ 17.852438708473066, 48.71769475117851 ], [ 17.798094715302927, 47.73104447774509 ], [ 16.3343313489668, 47.75740973734738 ], [ 16.360279246283664, 48.74498411169783 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/DATASTRIP/DS_S2RP_20230429T151337_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/GRANULE/L1C_T33UXP_A013118_20190910T095200/IMG_DATA/T33UXP_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337.SAFE/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXP_20230429T151337-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.3343313489668, 47.73104447774509, 17.852438708473066, 48.74498411169783 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 47.52082773448, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE", "s2:generation_time": "2023-04-29T15:13:37.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI1C", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L1C_DS_S2RP_20230429T151337_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L1C_TL_S2RP_20230429T151337_A013118_T33UXQ_N05.00", "s2:mgrs_tile": "33UXQ", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0108, "s2:mean_solar_zenith": 45.5027769297487, "s2:mean_solar_azimuth": 161.867557996355, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.3851737331767, 49.64443670244057 ], [ 17.904572762902152, 49.61627372192671 ], [ 17.847478451946774, 48.62982157570405 ], [ 16.357910769851937, 48.657027178567795 ], [ 16.3851737331767, 49.64443670244057 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/MTD_MSIL1C.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/DATASTRIP/DS_S2RP_20230429T151337_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B01.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B02.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B03.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B04.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B05.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B06.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B07.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B08.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B8A.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B09.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B10": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B10.jp2", "type": "image/jp2", "title": "Band 10 - SWIR - Cirrus - 60m", "eo:bands": [ { "name": "B10", "description": "Band 10 - SWIR - Cirrus", "center_wavelength": 1.3735, "full_width_half_max": 0.075 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B11.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_B12.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "visual": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/GRANULE/L1C_T33UXQ_A013118_20190910T095200/IMG_DATA/T33UXQ_20190910T095029_TCI.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L1C_N0500/2019/09/10/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337.SAFE/S2B_MSIL1C_20190910T095029_N0500_R079_T33UXQ_20230429T151337-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.357910769851937, 48.62982157570405, 17.904572762902152, 49.64443670244057 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI1C" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 44.521128, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE", "s2:generation_time": "2019-09-10T12:45:13.000000Z", "s2:processing_baseline": "02.13", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.13", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_MTI__20190910T124513_S20190910T095200_N02.13", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_MTI__20190910T124513_A013118_T33TWN_N02.13", "s2:mgrs_tile": "33TWN", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:nodata_pixel_percentage": 33.393028, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 0.675055, "s2:cloud_shadow_percentage": 3.996761, "s2:vegetation_percentage": 42.600289, "s2:not_vegetated_percentage": 3.682366, "s2:water_percentage": 0.033344, "s2:unclassified_percentage": 4.453947, "s2:medium_proba_clouds_percentage": 7.334322, "s2:high_proba_clouds_percentage": 20.980535, "s2:thin_cirrus_percentage": 16.20627, "s2:snow_ice_percentage": 0.03711, "s2:mean_solar_zenith": 44.0991584183932, "s2:mean_solar_azimuth": 159.531813362975, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.444861597282598, 46.86290010560831 ], [ 15.31183071907207, 46.88149751987032 ], [ 15.338289611196274, 46.95521678246418 ], [ 15.390966472422209, 47.10161813498074 ], [ 15.444791927935675, 47.247653834030366 ], [ 15.497949881270555, 47.393882520175886 ], [ 15.549772019723136, 47.54053618762919 ], [ 15.605219911107202, 47.68629327930668 ], [ 15.657081905205992, 47.83307797270472 ], [ 15.663067914137011, 47.84946349842912 ], [ 16.467277376768234, 47.844325046514086 ], [ 16.440149824410025, 46.85663988190739 ], [ 15.444861597282598, 46.86290010560831 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/DATASTRIP/DS_MTI__20190910T124513_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "preview": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/QI_DATA/T33TWN_20190910T095029_PVI.jp2", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "thumbnail" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513.SAFE/S2B_MSIL2A_20190910T095029_N0213_R079_T33TWN_20190910T124513-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.31183071907207, 46.85663988190739, 16.467277376768234, 47.84946349842912 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 78.167575, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE", "s2:generation_time": "2019-09-10T12:45:13.000000Z", "s2:processing_baseline": "02.13", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.13", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_MTI__20190910T124513_S20190910T095200_N02.13", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_MTI__20190910T124513_A013118_T33TXN_N02.13", "s2:mgrs_tile": "33TXN", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:nodata_pixel_percentage": 0.0, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 0.360523, "s2:cloud_shadow_percentage": 0.336392, "s2:vegetation_percentage": 16.008423, "s2:not_vegetated_percentage": 4.138201, "s2:water_percentage": 0.230855, "s2:unclassified_percentage": 0.758023, "s2:medium_proba_clouds_percentage": 13.026018, "s2:high_proba_clouds_percentage": 4.158072, "s2:thin_cirrus_percentage": 60.983485, "s2:snow_ice_percentage": 0.0, "s2:mean_solar_zenith": 43.7864951023904, "s2:mean_solar_azimuth": 161.360399994209, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.33660021997006, 47.84592105208886 ], [ 17.80284668292451, 47.81947440295927 ], [ 17.751084998620154, 46.83262831925138 ], [ 16.31188688551243, 46.85818197246455 ], [ 16.33660021997006, 47.84592105208886 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/DATASTRIP/DS_MTI__20190910T124513_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "preview": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/QI_DATA/T33TXN_20190910T095029_PVI.jp2", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "thumbnail" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513.SAFE/S2B_MSIL2A_20190910T095029_N0213_R079_T33TXN_20190910T124513-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.31188688551243, 46.83262831925138, 17.80284668292451, 47.84592105208886 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 18.279976, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE", "s2:generation_time": "2019-09-10T12:45:13.000000Z", "s2:processing_baseline": "02.13", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.13", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_MTI__20190910T124513_S20190910T095200_N02.13", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_MTI__20190910T124513_A013118_T33UWP_N02.13", "s2:mgrs_tile": "33UWP", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:nodata_pixel_percentage": 54.92236, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 1.352937, "s2:cloud_shadow_percentage": 2.364761, "s2:vegetation_percentage": 57.963973, "s2:not_vegetated_percentage": 15.533578, "s2:water_percentage": 0.356046, "s2:unclassified_percentage": 4.148561, "s2:medium_proba_clouds_percentage": 4.697439, "s2:high_proba_clouds_percentage": 6.792469, "s2:thin_cirrus_percentage": 6.790069, "s2:snow_ice_percentage": 0.000169, "s2:mean_solar_zenith": 44.9536568849222, "s2:mean_solar_azimuth": 159.782654740994, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.631662816257208, 47.76113447645779 ], [ 15.657081905205992, 47.83307797270472 ], [ 15.710570169434488, 47.97949160816187 ], [ 15.764039003164896, 48.126009379104055 ], [ 15.81778554333848, 48.272570340647 ], [ 15.872493644825884, 48.41894350808384 ], [ 15.92758789432043, 48.56524552456526 ], [ 15.982974989379908, 48.71149865233935 ], [ 15.996305449661863, 48.74655676308699 ], [ 16.4932694755772, 48.7433372246506 ], [ 16.464786866939885, 47.75581864580811 ], [ 15.631662816257208, 47.76113447645779 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/DATASTRIP/DS_MTI__20190910T124513_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "preview": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/QI_DATA/T33UWP_20190910T095029_PVI.jp2", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "thumbnail" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513.SAFE/S2B_MSIL2A_20190910T095029_N0213_R079_T33UWP_20190910T124513-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.631662816257208, 47.75581864580811, 16.4932694755772, 48.74655676308699 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 51.639935, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE", "s2:generation_time": "2019-09-10T12:45:13.000000Z", "s2:processing_baseline": "02.13", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.13", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_MTI__20190910T124513_S20190910T095200_N02.13", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_MTI__20190910T124513_A013118_T33UXP_N02.13", "s2:mgrs_tile": "33UXP", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:nodata_pixel_percentage": 3e-06, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 2.167203, "s2:cloud_shadow_percentage": 2.602274, "s2:vegetation_percentage": 24.387474, "s2:not_vegetated_percentage": 12.379172, "s2:water_percentage": 0.309763, "s2:unclassified_percentage": 6.513844, "s2:medium_proba_clouds_percentage": 19.067624, "s2:high_proba_clouds_percentage": 16.676113, "s2:thin_cirrus_percentage": 15.896198, "s2:snow_ice_percentage": 0.000332, "s2:mean_solar_zenith": 44.6441560946082, "s2:mean_solar_azimuth": 161.618278923701, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.360279246283664, 48.74498411169783 ], [ 17.852438708473066, 48.71769475117851 ], [ 17.798094715302927, 47.73104447774509 ], [ 16.3343313489668, 47.75740973734738 ], [ 16.360279246283664, 48.74498411169783 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/DATASTRIP/DS_MTI__20190910T124513_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "preview": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/QI_DATA/T33UXP_20190910T095029_PVI.jp2", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "thumbnail" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.3343313489668, 47.73104447774509, 17.852438708473066, 48.74498411169783 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 38.0614, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE", "s2:generation_time": "2019-09-10T12:45:13.000000Z", "s2:processing_baseline": "02.13", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N02.13", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_MTI__20190910T124513_S20190910T095200_N02.13", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_MTI__20190910T124513_A013118_T33UXQ_N02.13", "s2:mgrs_tile": "33UXQ", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0, "s2:nodata_pixel_percentage": 0.0, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 1.411389, "s2:cloud_shadow_percentage": 3.577536, "s2:vegetation_percentage": 34.950623, "s2:not_vegetated_percentage": 14.769036, "s2:water_percentage": 0.22127, "s2:unclassified_percentage": 6.992349, "s2:medium_proba_clouds_percentage": 8.995432, "s2:high_proba_clouds_percentage": 19.044973, "s2:thin_cirrus_percentage": 10.020995, "s2:snow_ice_percentage": 0.016397, "s2:mean_solar_zenith": 45.5029104836805, "s2:mean_solar_azimuth": 161.866690183624, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.3851737331767, 49.64443670244057 ], [ 17.904572762902152, 49.61627372192671 ], [ 17.847478451946774, 48.62982157570405 ], [ 16.357910769851937, 48.657027178567795 ], [ 16.3851737331767, 49.64443670244057 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/DATASTRIP/DS_MTI__20190910T124513_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "preview": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/QI_DATA/T33UXQ_20190910T095029_PVI.jp2", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "thumbnail" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A/2019/09/10/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE/S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.357910769851937, 48.62982157570405, 17.904572762902152, 49.64443670244057 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 53.0536, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE", "s2:generation_time": "2023-04-30T08:37:12.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_S2RP_20230430T083712_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_S2RP_20230430T083712_A013118_T33TWN_N05.00", "s2:mgrs_tile": "33TWN", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0078, "s2:nodata_pixel_percentage": 33.846307, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 0.107138, "s2:cloud_shadow_percentage": 7.367544, "s2:vegetation_percentage": 34.961432, "s2:not_vegetated_percentage": 3.429612, "s2:water_percentage": 0.036587, "s2:unclassified_percentage": 1.04402, "s2:medium_proba_clouds_percentage": 13.516408, "s2:high_proba_clouds_percentage": 21.180651, "s2:thin_cirrus_percentage": 18.356542, "s2:snow_ice_percentage": 7e-05, "s2:mean_solar_zenith": 44.0990034305175, "s2:mean_solar_azimuth": 159.532696066021, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.445301346124024, 46.86289733964962 ], [ 15.311863606240896, 46.88155190097966 ], [ 15.338319066528848, 46.955271231045074 ], [ 15.390995983857032, 47.101672701706896 ], [ 15.444822021173453, 47.247708340802895 ], [ 15.497976349912156, 47.39393813805563 ], [ 15.549799967027868, 47.540591585633614 ], [ 15.605214478403314, 47.68635775881352 ], [ 15.657120560294516, 47.833130750240834 ], [ 15.663088212288423, 47.8494633687352 ], [ 16.467277376768234, 47.844325046514086 ], [ 16.440149824410025, 46.85663988190739 ], [ 15.445301346124024, 46.86289733964962 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/DATASTRIP/DS_S2RP_20230430T083712_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R10m/T33TWN_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B01_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B01_20m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 20m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R20m/T33TWN_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/GRANULE/L2A_T33TWN_A013118_20190910T095200/IMG_DATA/R60m/T33TWN_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5190240.0, 609780.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE/S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.311863606240896, 46.85663988190739, 16.467277376768234, 47.8494633687352 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 78.362733, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE", "s2:generation_time": "2023-04-30T08:37:12.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_S2RP_20230430T083712_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_S2RP_20230430T083712_A013118_T33TXN_N05.00", "s2:mgrs_tile": "33TXN", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0104, "s2:nodata_pixel_percentage": 0.0, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 0.008676, "s2:cloud_shadow_percentage": 1.213184, "s2:vegetation_percentage": 15.38761, "s2:not_vegetated_percentage": 4.514524, "s2:water_percentage": 0.263413, "s2:unclassified_percentage": 0.24986, "s2:medium_proba_clouds_percentage": 14.276174, "s2:high_proba_clouds_percentage": 4.266522, "s2:thin_cirrus_percentage": 59.820038, "s2:snow_ice_percentage": 0.0, "s2:mean_solar_zenith": 43.7863531473642, "s2:mean_solar_azimuth": 161.36129143083, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.33660021997006, 47.84592105208886 ], [ 17.80284668292451, 47.81947440295927 ], [ 17.751084998620154, 46.83262831925138 ], [ 16.31188688551243, 46.85818197246455 ], [ 16.33660021997006, 47.84592105208886 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/DATASTRIP/DS_S2RP_20230430T083712_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R10m/T33TXN_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5300040.0 ], "roles": [ "data" ] }, "B01_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B01_20m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 20m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R20m/T33TXN_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5300040.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/GRANULE/L2A_T33TXN_A013118_20190910T095200/IMG_DATA/R60m/T33TXN_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5190240.0, 709800.0, 5300040.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5300040.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE/S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.31188688551243, 46.83262831925138, 17.80284668292451, 47.84592105208886 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 34.630349, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE", "s2:generation_time": "2023-04-30T08:37:12.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_S2RP_20230430T083712_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_S2RP_20230430T083712_A013118_T33UWP_N05.00", "s2:mgrs_tile": "33UWP", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0001, "s2:nodata_pixel_percentage": 55.381244, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 0.106483, "s2:cloud_shadow_percentage": 6.056742, "s2:vegetation_percentage": 46.635726, "s2:not_vegetated_percentage": 11.429635, "s2:water_percentage": 0.200846, "s2:unclassified_percentage": 0.940219, "s2:medium_proba_clouds_percentage": 9.542563, "s2:high_proba_clouds_percentage": 7.036104, "s2:thin_cirrus_percentage": 18.051681, "s2:snow_ice_percentage": 0.0, "s2:mean_solar_zenith": 44.9535062944708, "s2:mean_solar_azimuth": 159.783525917098, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.6316591777781, 47.76113449967347 ], [ 15.657120560294516, 47.833130750240834 ], [ 15.710616804532526, 47.97954239571095 ], [ 15.764066021857507, 48.12606560428376 ], [ 15.817813091177218, 48.2726265904545 ], [ 15.872519109449508, 48.41900045837953 ], [ 15.927608933566882, 48.56530379366712 ], [ 15.982996310908666, 48.711556982150206 ], [ 15.996306617907225, 48.74655675551862 ], [ 16.4932694755772, 48.7433372246506 ], [ 16.464786866939885, 47.75581864580811 ], [ 15.6316591777781, 47.76113449967347 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/DATASTRIP/DS_S2RP_20230430T083712_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R10m/T33UWP_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B01_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B01_20m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 20m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R20m/T33UWP_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/GRANULE/L2A_T33UWP_A013118_20190910T095200/IMG_DATA/R60m/T33UWP_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5290200.0, 609780.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712.SAFE/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWP_20230430T083712-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.6316591777781, 47.75581864580811, 16.4932694755772, 48.74655675551862 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 46.90851, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE", "s2:generation_time": "2023-04-30T08:37:12.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_S2RP_20230430T083712_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_S2RP_20230430T083712_A013118_T33UWQ_N05.00", "s2:mgrs_tile": "33UWQ", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0001, "s2:nodata_pixel_percentage": 76.892251, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 0.001077, "s2:cloud_shadow_percentage": 5.51787, "s2:vegetation_percentage": 31.712502, "s2:not_vegetated_percentage": 15.536624, "s2:water_percentage": 0.066722, "s2:unclassified_percentage": 0.256695, "s2:medium_proba_clouds_percentage": 9.585929, "s2:high_proba_clouds_percentage": 3.552645, "s2:thin_cirrus_percentage": 33.769935, "s2:snow_ice_percentage": 0.0, "s2:mean_solar_zenith": 45.8092607157278, "s2:mean_solar_azimuth": 160.023209526894, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.96301645244071, 48.658799149109164 ], [ 15.982996310908666, 48.711556982150206 ], [ 16.038585054609282, 48.857728924808406 ], [ 16.094078869579587, 49.003838699992016 ], [ 16.149831938493833, 49.1498699202275 ], [ 16.205776390297686, 49.29591464931502 ], [ 16.2622273238065, 49.44191609181968 ], [ 16.318508423928247, 49.5880174129141 ], [ 16.3403037294286, 49.64392082625591 ], [ 16.520595653725128, 49.64273706516441 ], [ 16.49066964052278, 48.65538534877128 ], [ 15.96301645244071, 48.658799149109164 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/DATASTRIP/DS_S2RP_20230430T083712_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R10m/T33UWQ_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R10m/T33UWQ_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R10m/T33UWQ_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R10m/T33UWQ_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R10m/T33UWQ_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R10m/T33UWQ_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R10m/T33UWQ_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 499980.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B01_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B01_20m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 20m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R20m/T33UWQ_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 499980.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/GRANULE/L2A_T33UWQ_A013118_20190910T095200/IMG_DATA/R60m/T33UWQ_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 499980.0, 5390220.0, 609780.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 499980.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712.SAFE/S2B_MSIL2A_20190910T095029_N0500_R079_T33UWQ_20230430T083712-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 15.96301645244071, 48.65538534877128, 16.520595653725128, 49.64392082625591 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 62.801784, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE", "s2:generation_time": "2023-04-30T08:37:12.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_S2RP_20230430T083712_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_S2RP_20230430T083712_A013118_T33UXP_N05.00", "s2:mgrs_tile": "33UXP", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0108, "s2:nodata_pixel_percentage": 0.0, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 0.023583, "s2:cloud_shadow_percentage": 7.28609, "s2:vegetation_percentage": 18.046941, "s2:not_vegetated_percentage": 9.782058, "s2:water_percentage": 0.216944, "s2:unclassified_percentage": 1.842598, "s2:medium_proba_clouds_percentage": 25.349292, "s2:high_proba_clouds_percentage": 17.161708, "s2:thin_cirrus_percentage": 20.290786, "s2:snow_ice_percentage": 0.0, "s2:mean_solar_zenith": 44.6440183841524, "s2:mean_solar_azimuth": 161.619158319578, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.360279246283664, 48.74498411169783 ], [ 17.852438708473066, 48.71769475117851 ], [ 17.798094715302927, 47.73104447774509 ], [ 16.3343313489668, 47.75740973734738 ], [ 16.360279246283664, 48.74498411169783 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/DATASTRIP/DS_S2RP_20230430T083712_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R10m/T33UXP_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5400000.0 ], "roles": [ "data" ] }, "B01_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B01_20m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 20m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R20m/T33UXP_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5400000.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/GRANULE/L2A_T33UXP_A013118_20190910T095200/IMG_DATA/R60m/T33UXP_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5290200.0, 709800.0, 5400000.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5400000.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.3343313489668, 47.73104447774509, 17.852438708473066, 48.74498411169783 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE.json ================================================ { "type": "Feature", "stac_version": "1.0.0", "id": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE", "properties": { "providers": [ { "name": "ESA", "roles": [ "producer", "processor", "licensor" ], "url": "https://earth.esa.int/web/guest/home" } ], "platform": "Sentinel-2B", "constellation": "Sentinel 2", "instruments": [ "msi" ], "eo:cloud_cover": 50.333804, "sat:orbit_state": "descending", "sat:relative_orbit": 79, "proj:epsg": 32633, "s2:product_uri": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE", "s2:generation_time": "2023-04-30T08:37:12.000000Z", "s2:processing_baseline": "05.00", "s2:product_type": "S2MSI2A", "s2:datatake_id": "GS2B_20190910T095029_013118_N05.00", "s2:datatake_type": "INS-NOBS", "s2:datastrip_id": "S2B_OPER_MSI_L2A_DS_S2RP_20230430T083712_S20190910T095200_N05.00", "s2:granule_id": "S2B_OPER_MSI_L2A_TL_S2RP_20230430T083712_A013118_T33UXQ_N05.00", "s2:mgrs_tile": "33UXQ", "s2:reflectance_conversion_factor": 0.984745756818796, "s2:degraded_msi_data_percentage": 0.0108, "s2:nodata_pixel_percentage": 0.0, "s2:saturated_defective_pixel_percentage": 0.0, "s2:dark_features_percentage": 0.000246, "s2:cloud_shadow_percentage": 7.545094, "s2:vegetation_percentage": 27.752319, "s2:not_vegetated_percentage": 12.371027, "s2:water_percentage": 0.184502, "s2:unclassified_percentage": 1.81301, "s2:medium_proba_clouds_percentage": 15.143655, "s2:high_proba_clouds_percentage": 19.431418, "s2:thin_cirrus_percentage": 15.758727, "s2:snow_ice_percentage": 0.0, "s2:mean_solar_zenith": 45.5027769297487, "s2:mean_solar_azimuth": 161.867557996355, "datetime": "2019-09-10T09:50:29.024000Z", "title": "S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.3851737331767, 49.64443670244057 ], [ 17.904572762902152, 49.61627372192671 ], [ 17.847478451946774, 48.62982157570405 ], [ 16.357910769851937, 48.657027178567795 ], [ 16.3851737331767, 49.64443670244057 ] ] ] }, "links": [ { "rel": "license", "href": "https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice" }, { "rel": "alternate", "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/", "type": "application/octet-stream", "name": "product", "description": "product" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wms", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwms&service=WMS&version=1.3.0&request=GetCapabilities&cql=identifier%3D%22S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE%22", "type": "OGC:WMS", "name": "OGC WMS", "description": "WMS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE" }, { "rel": "http://www.opengis.net/def/serviceType/ogc/wcs", "href": "https://data-access-v1x.develop.eoepca.org/ows?rel=http%3A%2F%2Fwww.opengis.net%2Fdef%2FserviceType%2Fogc%2Fwcs&service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoid=S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE", "type": "OGC:WCS", "name": "OGC WCS", "description": "WCS URL for S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE" } ], "assets": { "safe-manifest": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/manifest.safe", "type": "application/xml", "roles": [ "metadata" ] }, "product-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/MTD_MSIL2A.xml", "type": "application/xml", "roles": [ "metadata" ] }, "granule-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/MTD_TL.xml", "type": "application/xml", "roles": [ "metadata" ] }, "inspire-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/INSPIRE.xml", "type": "application/xml", "roles": [ "metadata" ] }, "datastrip-metadata": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/DATASTRIP/DS_S2RP_20230430T083712_S20190910T095200/MTD_DS.xml", "type": "application/xml", "roles": [ "metadata" ] }, "B02": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_B02_10m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B03": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_B03_10m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B04": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_B04_10m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B08": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_B08_10m.jp2", "type": "image/jp2", "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ], "gsd": 10, "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "visual-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_TCI_10m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "AOT-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_AOT_10m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "WVP-10m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R10m/T33UXQ_20190910T095029_WVP_10m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 10980, 10980 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 10.0, 0.0, 600000.0, 0.0, -10.0, 5500020.0 ], "roles": [ "data" ] }, "B01_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B01_20m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 20m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B02_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B02_20m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 20m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B03_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B03_20m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 20m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B04_20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B04_20m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 20m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B05": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B05_20m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B06": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B06_20m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B07": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B07_20m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B8A": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B8A_20m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B11": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B11_20m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B12": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_B12_20m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "gsd": 20, "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "visual-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_TCI_20m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "AOT-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_AOT_20m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "WVP-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_WVP_20m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "SCL-20m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R20m/T33UXQ_20190910T095029_SCL_20m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 5490, 5490 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 20.0, 0.0, 600000.0, 0.0, -20.0, 5500020.0 ], "roles": [ "data" ] }, "B01": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B01_60m.jp2", "type": "image/jp2", "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B02_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B02_60m.jp2", "type": "image/jp2", "title": "Band 2 - Blue - 60m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B03_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B03_60m.jp2", "type": "image/jp2", "title": "Band 3 - Green - 60m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B04_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B04_60m.jp2", "type": "image/jp2", "title": "Band 4 - Red - 60m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B05_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B05_60m.jp2", "type": "image/jp2", "title": "Band 5 - Vegetation red edge 1 - 60m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B06_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B06_60m.jp2", "type": "image/jp2", "title": "Band 6 - Vegetation red edge 2 - 60m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B07_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B07_60m.jp2", "type": "image/jp2", "title": "Band 7 - Vegetation red edge 3 - 60m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B8A_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B8A_60m.jp2", "type": "image/jp2", "title": "Band 8A - Vegetation red edge 4 - 60m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B09": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B09_60m.jp2", "type": "image/jp2", "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ], "gsd": 60, "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B11_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B11_60m.jp2", "type": "image/jp2", "title": "Band 11 - SWIR (1.6) - 60m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "B12_60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_B12_60m.jp2", "type": "image/jp2", "title": "Band 12 - SWIR (2.2) - 60m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "visual-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_TCI_60m.jp2", "type": "image/jp2", "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ], "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "AOT-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_AOT_60m.jp2", "type": "image/jp2", "title": "Aerosol optical thickness (AOT)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "WVP-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_WVP_60m.jp2", "type": "image/jp2", "title": "Water vapour (WVP)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "SCL-60m": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/GRANULE/L2A_T33UXQ_A013118_20190910T095200/IMG_DATA/R60m/T33UXQ_20190910T095029_SCL_60m.jp2", "type": "image/jp2", "title": "Scene classfication map (SCL)", "proj:shape": [ 1830, 1830 ], "proj:bbox": [ 600000.0, 5390220.0, 709800.0, 5500020.0 ], "proj:transform": [ 60.0, 0.0, 600000.0, 0.0, -60.0, 5500020.0 ], "roles": [ "data" ] }, "thumbnail": { "href": "s3://EODATA/Sentinel-2/MSI/L2A_N0500/2019/09/10/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE/S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712-ql.jpg", "type": "image/jpeg", "roles": [ "thumbnail" ] } }, "bbox": [ 16.357910769851937, 48.62982157570405, 17.904572762902152, 49.64443670244057 ], "stac_extensions": [ "https://stac-extensions.github.io/eo/v1.1.0/schema.json", "https://stac-extensions.github.io/sat/v1.0.0/schema.json", "https://stac-extensions.github.io/projection/v1.1.0/schema.json" ], "collection": "S2MSI2A" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2MSI1C.xml ================================================ S2MSI1C eng utf8 dataset 2021-02-16 ISO 19115:2003 - Geographic information - Metadata ISO 19115:2003 https://sentinel.esa.int/web/sentinel/user-guides/sentinel-2-msi European Petroleum Survey Group (EPSG) Geodetic Parameter Registry 2008-11-12 publication European Petroleum Survey Group http://www.epsg-registry.org originator urn:ogc:def:crs:EPSG:4326 6.18.3 Sentinel-2 MSI Level 1C 2015-06-21 creation 2015-06-21 publication Sentinel-2 MultiSpectral Instrument Level 1C onGoing Firstname Lastname European Space Agency Position name TBD TBD TBD TBD TBD TBD TBD TBD https://www.esa.int WWW:LINK information TBD TBD pointOfContact continual sentinel-2 level-1c None grid eng utf8 imageryBaseMapsEarthCover 1 -180 180 -56 82 2015-06-21 https://sentinel.esa.int/web/sentinel/user-guides/sentinel-2-msi Firstname Lastname European Space Agency Position name TBD TBD TBD TBD TBD TBD TBD TBD https://www.esa.int WWW:LINK information TBD TBD distributor http://example.org/ OGC:WMS TBD TBD download continual This metadata record was generated by pygeometa-0.15.3 (https://github.com/geopython/pygeometa) ================================================ FILE: tests/functionaltests/suites/stac_api/data/S2MSI2A.xml ================================================ S2MSI2A eng utf8 dataset 2021-02-16 ISO 19115:2003 - Geographic information - Metadata ISO 19115:2003 https://sentinel.esa.int/web/sentinel/user-guides/sentinel-2-msi European Petroleum Survey Group (EPSG) Geodetic Parameter Registry 2008-11-12 publication European Petroleum Survey Group http://www.epsg-registry.org originator urn:ogc:def:crs:EPSG:4326 6.18.3 Sentinel-2 MSI Level 2A 2015-06-21 creation 2015-06-21 publication Sentinel-2 MultiSpectral Instrument Level 2A onGoing Firstname Lastname European Space Agency Position name TBD TBD TBD TBD TBD TBD TBD TBD https://www.esa.int WWW:LINK information TBD TBD pointOfContact continual sentinel-2 level-2a None grid eng utf8 imageryBaseMapsEarthCover 1 -180 180 -56 82 2015-06-21 https://sentinel.esa.int/web/sentinel/user-guides/sentinel-2-msi Firstname Lastname European Space Agency Position name TBD TBD TBD TBD TBD TBD TBD TBD https://www.esa.int WWW:LINK information TBD TBD distributor http://example.org/ OGC:WMS TBD TBD download continual This metadata record was generated by pygeometa-0.15.3 (https://github.com/geopython/pygeometa) ================================================ FILE: tests/functionaltests/suites/stac_api/data/sentinel-2-l2a.json ================================================ { "id": "sentinel-2-l2a", "type": "Collection", "links": [ { "rel": "items", "type": "application/geo+json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/collections/sentinel-2-l2a/items" }, { "rel": "parent", "type": "application/json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/" }, { "rel": "root", "type": "application/json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/" }, { "rel": "self", "type": "application/json", "href": "https://catalogue.dev-1.hsc.eofarm.com/stac/collections/sentinel-2-l2a" }, { "rel": "license", "href": "https://scihub.copernicus.eu/twiki/pub/SciHubWebPortal/TermsConditions/Sentinel_Data_Terms_and_Conditions.pdf", "title": "Copernicus Sentinel data terms" }, { "rel": "describedby", "href": "https://planetarycomputer.microsoft.com/dataset/sentinel-2-l2a", "title": "Human readable dataset overview and reference", "type": "text/html" } ], "title": "Sentinel-2 Level-2A", "assets": { "thumbnail": { "href": "https://ai4edatasetspublicassets.blob.core.windows.net/assets/pc_thumbnails/sentinel-2.png", "type": "image/png", "roles": [ "thumbnail" ], "title": "Sentinel 2 L2A" }, "geoparquet-items": { "href": "abfs://items/sentinel-2-l2a.parquet", "type": "application/x-parquet", "roles": [ "stac-items" ], "title": "GeoParquet STAC items", "description": "Snapshot of the collection's STAC items exported to GeoParquet format.", "msft:partition_info": { "is_partitioned": true, "partition_frequency": "W-MON" }, "table:storage_options": { "account_name": "pcstacitems" } } }, "extent": { "spatial": { "bbox": [ [ -180, -90, 180, 90 ] ] }, "temporal": { "interval": [ [ "2015-06-27T10:25:31Z", null ] ] } }, "license": "proprietary", "keywords": [ "Sentinel", "Copernicus", "ESA", "Satellite", "Global", "Imagery", "Reflectance" ], "providers": [ { "url": "https://sentinel.esa.int/web/sentinel/missions/sentinel-2", "name": "ESA", "roles": [ "producer", "licensor" ] }, { "url": "https://www.esri.com/", "name": "Esri", "roles": [ "processor" ] }, { "url": "https://planetarycomputer.microsoft.com", "name": "Microsoft", "roles": [ "host", "processor" ] } ], "summaries": { "gsd": [ 10, 20, 60 ], "eo:bands": [ { "name": "AOT", "description": "aerosol optical thickness" }, { "gsd": 60, "name": "B01", "common_name": "coastal", "description": "coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 }, { "gsd": 10, "name": "B02", "common_name": "blue", "description": "visible blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 }, { "gsd": 10, "name": "B03", "common_name": "green", "description": "visible green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "gsd": 10, "name": "B04", "common_name": "red", "description": "visible red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "gsd": 20, "name": "B05", "common_name": "rededge", "description": "vegetation classification red edge", "center_wavelength": 0.704, "full_width_half_max": 0.019 }, { "gsd": 20, "name": "B06", "common_name": "rededge", "description": "vegetation classification red edge", "center_wavelength": 0.74, "full_width_half_max": 0.018 }, { "gsd": 20, "name": "B07", "common_name": "rededge", "description": "vegetation classification red edge", "center_wavelength": 0.783, "full_width_half_max": 0.028 }, { "gsd": 10, "name": "B08", "common_name": "nir", "description": "near infrared", "center_wavelength": 0.842, "full_width_half_max": 0.145 }, { "gsd": 20, "name": "B8A", "common_name": "rededge", "description": "vegetation classification red edge", "center_wavelength": 0.865, "full_width_half_max": 0.033 }, { "gsd": 60, "name": "B09", "description": "water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 }, { "gsd": 20, "name": "B11", "common_name": "swir16", "description": "short-wave infrared, snow/ice/cloud classification", "center_wavelength": 1.61, "full_width_half_max": 0.143 }, { "gsd": 20, "name": "B12", "common_name": "swir22", "description": "short-wave infrared, snow/ice/cloud classification", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ], "platform": [ "Sentinel-2A", "Sentinel-2B" ], "instruments": [ "msi" ], "constellation": [ "sentinel-2" ], "view:off_nadir": [ 3.8 ] }, "view:off_nadir": 3.8, "description": "The [Sentinel-2](https://sentinel.esa.int/web/sentinel/missions/sentinel-2) program provides global imagery in thirteen spectral bands at 10m-60m resolution and a revisit time of approximately five days. This dataset represents the global Sentinel-2 archive, from 2016 to the present, processed to L2A (bottom-of-atmosphere) using [Sen2Cor](https://step.esa.int/main/snap-supported-plugins/sen2cor/) and converted to [cloud-optimized GeoTIFF](https://www.cogeo.org/) format.", "item_assets": { "AOT": { "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Aerosol optical thickness (AOT)" }, "B01": { "gsd": 60, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 1 - Coastal aerosol - 60m", "eo:bands": [ { "name": "B01", "common_name": "coastal", "description": "Band 1 - Coastal aerosol", "center_wavelength": 0.443, "full_width_half_max": 0.027 } ] }, "B02": { "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 2 - Blue - 10m", "eo:bands": [ { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ] }, "B03": { "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 3 - Green - 10m", "eo:bands": [ { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 } ] }, "B04": { "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 4 - Red - 10m", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 } ] }, "B05": { "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 5 - Vegetation red edge 1 - 20m", "eo:bands": [ { "name": "B05", "common_name": "rededge", "description": "Band 5 - Vegetation red edge 1", "center_wavelength": 0.704, "full_width_half_max": 0.019 } ] }, "B06": { "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 6 - Vegetation red edge 2 - 20m", "eo:bands": [ { "name": "B06", "common_name": "rededge", "description": "Band 6 - Vegetation red edge 2", "center_wavelength": 0.74, "full_width_half_max": 0.018 } ] }, "B07": { "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 7 - Vegetation red edge 3 - 20m", "eo:bands": [ { "name": "B07", "common_name": "rededge", "description": "Band 7 - Vegetation red edge 3", "center_wavelength": 0.783, "full_width_half_max": 0.028 } ] }, "B08": { "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 8 - NIR - 10m", "eo:bands": [ { "name": "B08", "common_name": "nir", "description": "Band 8 - NIR", "center_wavelength": 0.842, "full_width_half_max": 0.145 } ] }, "B09": { "gsd": 60, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 9 - Water vapor - 60m", "eo:bands": [ { "name": "B09", "description": "Band 9 - Water vapor", "center_wavelength": 0.945, "full_width_half_max": 0.026 } ] }, "B11": { "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 11 - SWIR (1.6) - 20m", "eo:bands": [ { "name": "B11", "common_name": "swir16", "description": "Band 11 - SWIR (1.6)", "center_wavelength": 1.61, "full_width_half_max": 0.143 } ] }, "B12": { "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 12 - SWIR (2.2) - 20m", "eo:bands": [ { "name": "B12", "common_name": "swir22", "description": "Band 12 - SWIR (2.2)", "center_wavelength": 2.19, "full_width_half_max": 0.242 } ] }, "B8A": { "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Band 8A - Vegetation red edge 4 - 20m", "eo:bands": [ { "name": "B8A", "common_name": "rededge", "description": "Band 8A - Vegetation red edge 4", "center_wavelength": 0.865, "full_width_half_max": 0.033 } ] }, "SCL": { "gsd": 20, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Scene classfication map (SCL)" }, "WVP": { "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "Water vapour (WVP)" }, "visual": { "gsd": 10, "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "data" ], "title": "True color image", "eo:bands": [ { "name": "B04", "common_name": "red", "description": "Band 4 - Red", "center_wavelength": 0.665, "full_width_half_max": 0.038 }, { "name": "B03", "common_name": "green", "description": "Band 3 - Green", "center_wavelength": 0.56, "full_width_half_max": 0.045 }, { "name": "B02", "common_name": "blue", "description": "Band 2 - Blue", "center_wavelength": 0.49, "full_width_half_max": 0.098 } ] }, "preview": { "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": [ "thumbnail" ], "title": "Thumbnail" }, "safe-manifest": { "type": "application/xml", "roles": [ "metadata" ], "title": "SAFE manifest" }, "granule-metadata": { "type": "application/xml", "roles": [ "metadata" ], "title": "Granule metadata" }, "inspire-metadata": { "type": "application/xml", "roles": [ "metadata" ], "title": "INSPIRE metadata" }, "product-metadata": { "type": "application/xml", "roles": [ "metadata" ], "title": "Product metadata" }, "datastrip-metadata": { "type": "application/xml", "roles": [ "metadata" ], "title": "Datastrip metadata" } }, "stac_version": "1.0.0", "msft:container": "sentinel2-l2", "stac_extensions": [ "https://stac-extensions.github.io/item-assets/v1.0.0/schema.json", "https://stac-extensions.github.io/table/v1.2.0/schema.json" ], "msft:storage_account": "sentinel2l2a01", "msft:short_description": "The Sentinel-2 program provides global imagery in thirteen spectral bands at 10m-60m resolution and a revisit time of approximately five days. This dataset contains the global Sentinel-2 archive, from 2016 to the present, processed to L2A (bottom-of-atmosphere).", "msft:region": "westeurope" } ================================================ FILE: tests/functionaltests/suites/stac_api/data/simple-collection.json ================================================ { "id": "simple-collection", "type": "Collection", "stac_extensions": [ "https://stac-extensions.github.io/eo/v2.0.0/schema.json", "https://stac-extensions.github.io/projection/v2.0.0/schema.json", "https://stac-extensions.github.io/view/v1.0.0/schema.json" ], "stac_version": "1.1.0", "description": "A simple collection demonstrating core catalog fields with links to a couple of items", "title": "Simple Example Collection", "keywords": [ "simple", "example", "collection" ], "providers": [ { "name": "Remote Data, Inc", "description": "Producers of awesome spatiotemporal assets", "roles": [ "producer", "processor" ], "url": "http://remotedata.io" } ], "extent": { "spatial": { "bbox": [ [ 172.91173669923782, 1.3438851951615003, 172.95469614953714, 1.3690476620161975 ] ] }, "temporal": { "interval": [ [ "2020-12-11T22:38:32.125Z", "2020-12-14T18:02:31.437Z" ] ] } }, "license": "CC-BY-4.0", "summaries": { "platform": [ "cool_sat1", "cool_sat2" ], "constellation": [ "ion" ], "instruments": [ "cool_sensor_v1", "cool_sensor_v2" ], "gsd": { "minimum": 0.512, "maximum": 0.66 }, "eo:cloud_cover": { "minimum": 1.2, "maximum": 1.2 }, "proj:cpde": [ "EPSG:32659" ], "view:sun_elevation": { "minimum": 54.9, "maximum": 54.9 }, "view:off_nadir": { "minimum": 3.8, "maximum": 3.8 }, "view:sun_azimuth": { "minimum": 135.7, "maximum": 135.7 }, "statistics": { "type": "object", "properties": { "vegetation": { "description": "Percentage of pixels that are detected as vegetation, e.g. forests, grasslands, etc.", "minimum": 0, "maximum": 100 }, "water": { "description": "Percentage of pixels that are detected as water, e.g. rivers, oceans and ponds.", "minimum": 0, "maximum": 100 }, "urban": { "description": "Percentage of pixels that detected as urban, e.g. roads and buildings.", "minimum": 0, "maximum": 100 } } } }, "links": [ { "rel": "root", "href": "./collection.json", "type": "application/json", "title": "Simple Example Collection" }, { "rel": "item", "href": "./simple-item.json", "type": "application/geo+json", "title": "Simple Item" }, { "rel": "item", "href": "./core-item.json", "type": "application/geo+json", "title": "Core Item" }, { "rel": "item", "href": "./extended-item.json", "type": "application/geo+json", "title": "Extended Item" }, { "rel": "self", "href": "https://raw.githubusercontent.com/radiantearth/stac-spec/v1.1.0/examples/collection.json", "type": "application/json" } ] } ================================================ FILE: tests/functionaltests/suites/stac_api/data/woudc-total-column-ozone-totalozone.json ================================================ { "id": "woudc-total-column-ozone-totalozone", "type": "Feature", "time": { "interval": [ "1924-08-17T00:00:00Z", ".." ], "resolution": "P1D" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -180, -90 ], [ -180, 90 ], [ 180, 90 ], [ 180, -90 ], [ -180, -90 ] ] ] }, "conformsTo": [ "http://www.opengis.net/spec/ogcapi-records-1/1.0/req/record-core" ], "properties": { "created": "2021-02-08T00:00:00Z", "updated": "2021-02-08T00:00:00Z", "type": "dataset", "title": "Total Ozone - daily observations", "description": "A measurement of the total amount of atmospheric ozone in a given column from the surface to the edge of the atmosphere. Ground based instruments such as spectrophotometers and ozonemeters are used to measure results daily", "keywords": [ "total", "ozone", "level 1.0", "column", "dobson", "brewer", "saoz" ], "language": { "code": "en-CA", "name": "English (Canada)" }, "languages": [ { "code": "en-CA", "name": "English (Canada)" }, { "code": "fr-CA", "name": "French (Canada)" } ], "externalIds": [ { "scheme": "WMO:WIS", "value": "urn:x-wmo:md:int.wmo.wis::https://geo.woudc.org/def/data/ozone/total-column-ozone/totalozone" } ], "contacts": [ { "name": "World Ozone and Ultraviolet Radiation Data Centre", "links": [ { "href": "https://woudc.org", "rel": "about", "type": "text/html" } ], "contactInstructions": "SEE PAGE: https://woudc.org/contact.php", "roles": [ "publisher" ] } ], "themes": [ { "concepts": [ { "id": "dobson", "url": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode_dobson" }, { "id": "brewer", "url": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode_brewer" }, { "id": "vassey", "url": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode_vassey" }, { "id": "pion", "url": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode_pion" }, { "id": "microtops", "url": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode_microtops" }, { "id": "spectral", "url": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode_spectral" }, { "id": "hoelper", "url": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode_hoelper" }, { "id": "saoz", "url": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode_saoz" }, { "id": "filter", "url": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode_filter" } ], "scheme": "https://geo.woudc.org/codelists.xml#WOUDC_InstrumentCode" }, { "concepts": [ { "id": "atmosphericComposition", "url": "https://wis.wmo.int/2012/codelists/WMOCodeLists.xml#WMO_CategoryCode_atmosphericComposition" }, { "id": "pollution", "url": "https://wis.wmo.int/2012/codelists/WMOCodeLists.xml#WMO_CategoryCode_pollution" }, { "id": "observationPlatform", "url": "https://wis.wmo.int/2012/codelists/WMOCodeLists.xml#WMO_CategoryCode_observationPlatform" }, { "id": "rocketSounding", "url": "https://wis.wmo.int/2012/codelists/WMOCodeLists.xml#WMO_CategoryCode_rocketSounding" } ], "scheme": "https://wis.wmo.int/2012/codelists/WMOCodeLists.xml#WMO_CategoryCode" } ], "formats": [ { "name": "CSV", "mediaType": "text/csv" }, { "name": "GeoJSON", "mediaType": "application/geo+json" } ], "license": "other" }, "linkTemplates": [ { "rel": "describes", "type": "image/png", "title": "World Ozone and Ultraviolet Radiation Data Centre (WOUDC) stations", "uriTemplate": "https://geo.woudc.org/ows?service=WMS&version=1.3.0&request=GetMap&crs={crs}&bbox={bbox}&layers=stations&width={width}&height={height}&format=image/png", "variables": { "bbox": { "description": "...", "type": "array", "items": { "type": "number", "format": "double" }, "minItems": 4, "maxItems": 4 }, "crs": { "description": "...", "type": "string", "enum": [ "EPSG:4326", "EPSG:3857" ] }, "width": { "description": "...", "type": "number", "format": "integer", "minimum": 600, "maximum": 5000 }, "height": { "description": "...", "type": "number", "format": "integer", "minimum": 600, "maximum": 5000 } } } ], "links": [ { "rel": "alternate", "type": "text/html", "title": "This document as HTML", "href": "https://woudc.org/data/dataset_info.php?id=totalozone" }, { "rel": "preview", "type": "image/png", "title": "Total Ozone Preview Image", "href": "https://woudc.org/data/preview.png" }, { "rel": "enclosure", "type": "text/html", "title": "Web Accessible Folder (WAF)", "href": "https://woudc.org/archive/Archive-NewFormat/TotalOzone_1.0_1", "created": "2015-01-23T00:00:00Z", "updated": "2015-01-23T00:00:00Z" }, { "rel": "search", "type": "text/html", "title": "Data Search / Download User Interface", "href": "https://woudc.org/data/explore.php?dataset=totalozone" }, { "rel": "enclosure", "type": "application/zip", "title": "Static dataset archive file", "href": "https://woudc.org/archive/Summaries/dataset-snapshots/totalozone.zip", "created": "2015-01-23T00:00:00Z", "updated": "2015-01-23T00:00:00Z" }, { "rel": "service", "type": "application/xml", "title": "OGC Web Feature Service (WFS)", "href": "https://geo.woudc.org/ows" }, { "rel": "license", "href": "https://woudc.org/about/data-policy.php" } ] } ================================================ FILE: tests/functionaltests/suites/stac_api/test_stac_api_functional.py ================================================ # ================================================================= # # Authors: Tom Kralidis # Angelos Tzotsos # # Copyright (c) 2026 Tom Kralidis # Copyright (c) 2022 Angelos Tzotsos # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import json import pytest from pycsw.stac.api import STACAPI pytestmark = pytest.mark.functional def test_landing_page(config): api = STACAPI(config) headers, status, content = api.landing_page({}, {'f': 'json'}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert status == 200 assert len(content['links']) == 8 assert content['stac_version'] == '1.0.0' assert content['type'] == 'Catalog' assert len(content['conformsTo']) == 21 assert len(content['keywords']) == 3 def test_openapi(config): api = STACAPI(config) headers, status, content = api.openapi({}, {'f': 'json'}) content = json.loads(content) assert headers['Content-Type'] == 'application/vnd.oai.openapi+json;version=3.0' # noqa assert status == 200 def test_conformance(config): api = STACAPI(config) headers, status, content = api.conformance({}, {}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert status == 200 assert len(content['conformsTo']) == 21 conformances = [ 'http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/simple-query', 'https://api.stacspec.org/v1.0.0/core', 'https://api.stacspec.org/v1.0.0/ogcapi-features', 'https://api.stacspec.org/v1.0.0/item-search', 'https://api.stacspec.org/v1.0.0/item-search#filter', 'https://api.stacspec.org/v1.0.0/item-search#sort', 'https://api.stacspec.org/v1.0.0-rc.1/collection-search', 'https://api.stacspec.org/v1.0.0-rc.1/collection-search#free-text' ] for conformance in conformances: assert conformance in content['conformsTo'] def test_collections(config): api = STACAPI(config) headers, status, content = api.collections({}, {'f': 'json'}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert status == 200 assert len(content['links']) == 3 assert len(content['collections']) == 4 assert len(content['collections']) == content['numberMatched'] assert len(content['collections']) == content['numberReturned'] headers, status, content = api.collections({}, {'limit': 0, 'f': 'json'}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert status == 200 assert len(content['collections']) == 0 def test_collection(config): api = STACAPI(config) headers, status, content = api.collection({}, {'f': 'json'}, 'simple-collection') # noqa content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert status == 200 assert len(content['links']) == 4 assert content['id'] == 'simple-collection' assert content['title'] == 'Simple Example Collection' assert 'summaries' in content assert 'statistics' in content['summaries'] def test_queryables(config): api = STACAPI(config) headers, status, content = api.queryables({}, {}) content = json.loads(content) assert headers['Content-Type'] == 'application/schema+json' assert content['type'] == 'object' assert content['title'] == 'pycsw Geospatial Catalogue' assert content['$id'] == 'http://localhost/pycsw/oarec/stac/collections/metadata:main/queryables' # noqa assert content['$schema'] == 'http://json-schema.org/draft/2019-09/schema' assert len(content['properties']) == 19 assert 'geometry' in content['properties'] assert content['properties']['geometry']['$ref'] == 'https://geojson.org/schema/Polygon.json' # noqa headers, status, content = api.queryables({}, {}, collection='foo') assert status == 400 def test_items(config): api = STACAPI(config) headers, status, content = api.items({}, None, {}) content = json.loads(content) assert headers['Content-Type'] == 'application/json' assert status == 200 assert content['type'] == 'FeatureCollection' record = content['features'][0] assert record['stac_version'] == '1.0.0' # assert record['collection'] == 'S2MSI2A' for feature in content['features']: if feature.get('geometry') is not None: assert 'bbox' in feature assert isinstance(feature['bbox'], list) for link in feature['links']: assert 'href' in link assert 'rel' in link for link in content['links']: assert 'href' in link assert 'rel' in link assert 'metadata:main' not in link['href'] assert 'method' not in link assert 'body' not in link # test GET KVP requests content = json.loads(api.items({}, None, {'bbox': '-180,-90,180,90'})[2]) assert content['numberMatched'] == 26 content = json.loads(api.items({}, None, {'datetime': '2020-12-11T22:38:32.125Z'})[2]) # noqa assert content['numberMatched'] == 1 content = json.loads(api.items({}, None, {'bbox': '-180,-90,180,90', 'datetime': '2020-12-11T22:38:32.125Z'})[2]) assert content['numberMatched'] == 1 content = json.loads(api.items({}, None, {'sortby': 'title'})[2]) assert content['numberMatched'] == 26 assert content['features'][6]['properties']['title'] == 'S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE' # noqa content = json.loads(api.items({}, None, {'otherconstraints': 'other'})[2]) assert content['numberMatched'] == 1 assert content['features'][0]['properties']['license'] == 'other' content = json.loads(api.items({}, None, {'sortby': '-title'})[2]) assert content['numberMatched'] == 26 assert content['features'][5]['properties']['title'] == 'S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE' # noqa content = json.loads(api.items({}, None, {'sortby': 'datetime'})[2]) assert content['numberMatched'] == 26 assert content['features'][5]['properties']['title'] == 'S2B_MSIL1C_20190910T095029_N0208_R079_T33UXQ_20190910T120910.SAFE' # noqa content = json.loads(api.items({}, None, {'sortby': '-datetime'})[2]) assert content['numberMatched'] == 26 assert content['features'][6]['properties']['title'] == 'S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE' # noqa content = json.loads(api.items({}, None, {'sortby': '-description,-title'})[2]) # noqa assert content['numberMatched'] == 26 assert content['features'][6]['properties']['title'] == 'S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE' # noqa content = json.loads(api.items({}, None, {'sortby': '-description,title'})[2]) # noqa assert content['numberMatched'] == 26 assert content['features'][6]['properties']['title'] == 'S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE' # noqa params = {'filter': "title LIKE '%%T33TWN%%'"} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 4 assert content['numberReturned'] == 4 assert len(content['features']) == content['numberReturned'] params = {'filter': "title LIKE '%%T33TWN%%'", 'q': 'aeroSol'} content = json.loads(api.items({}, None, params)[2]) assert content['numberMatched'] == 4 assert content['numberReturned'] == 4 assert len(content['features']) == content['numberReturned'] # test POST JSON requests content = json.loads(api.items({}, {'bbox': [-180, -90, 180, 90]}, {})[2]) assert content['numberMatched'] == 26 content = json.loads(api.items({}, {'bbox': [-142, 42, -52, 84]}, {})[2]) assert content['numberMatched'] == 0 content = json.loads(api.items({}, {'bbox': [-180, -90, 180, 90], 'datetime': '2019-09-10T09:50:29.024000Z'}, # noqa {})[2]) assert content['numberMatched'] == 23 content = json.loads(api.items({}, {'datetime': '2024-11-28T09:23:31.024000Z'}, {})[2]) # noqa assert content['numberMatched'] == 2 content = json.loads(api.items({}, {'sortby': [{'field': 'title', 'direction': 'asc'}]}, # noqa {})[2]) assert content['numberMatched'] == 26 assert content['features'][6]['properties']['title'] == 'S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE' # noqa content = json.loads(api.items({}, {'sortby': [{'field': 'title', 'direction': 'desc'}]}, # noqa {})[2]) assert content['numberMatched'] == 26 assert content['features'][5]['properties']['title'] == 'S2B_MSIL2A_20190910T095029_N0500_R079_T33TWN_20230430T083712.SAFE' # noqa content = json.loads(api.items({}, {'sortby': [{'field': 'title', 'direction': 'asc'}, # noqa {'field': 'description', 'direction': 'desc'} # noqa ]}, # noqa {})[2]) assert content['numberMatched'] == 26 assert content['features'][6]['properties']['title'] == 'S2B_MSIL1C_20190910T095029_N0208_R079_T33UWQ_20190910T120910.SAFE' # noqa headers, status, content = api.items({}, None, {}, 'foo') assert status == 400 # test items from a specific collection headers, status, content = api.items({}, None, {}, 'S2MSI2A') assert status == 200 content = json.loads(content) assert content['numberMatched'] == 11 for feature in content['features']: assert feature['collection'] == 'S2MSI2A' # test items from a specific collection with a temporal query predicate headers, status, content = api.items({}, None, {'datetime': '2018-10-09T21:00:00.000Z/2019-10-23T12:51:01.271Z'}, 'S2MSI1C') # noqa assert status == 200 content = json.loads(content) assert content['numberMatched'] == 12 for feature in content['features']: assert feature['collection'] == 'S2MSI1C' # test limit content = json.loads(api.items({}, {'limit': 1}, {})[2]) assert content['numberReturned'] == 1 assert content['numberMatched'] == 26 # test ids ids = [ 'S2B_MSIL2A_20190910T095029_N0213_R079_T33UXQ_20190910T124513.SAFE', 'S2B_MSIL2A_20190910T095029_N0213_R079_T33UXP_20190910T124513.SAFE' ] content = json.loads(api.items({}, {'ids': ids}, {})[2]) assert content['numberReturned'] == 2 assert content['numberMatched'] == 2 content = json.loads(api.items({}, None, {'off_nadir': '3.8'})[2]) assert content['numberMatched'] == 1 assert content['features'][0]['properties']['view:off_nadir'] == 3.8 # test post CQL2 JSON requests cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [{ 'op': '=', 'args': [{ 'property': 'parentidentifier' }, 'S2MSI1C'] }] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 12 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [{ 'op': '=', 'args': [{ 'property': 'parentidentifier' }, 'S2MSI1C'] }] } } content = json.loads(api.items({}, cql_json, {'limit': 1})[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 1 cql_json = { 'filter-lang': 'cql2-json', 'limit': 1, 'filter': { 'op': 'and', 'args': [{ 'op': '=', 'args': [{ 'property': 'parentidentifier' }, 'S2MSI1C'] }] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 12 assert content['numberReturned'] == 1 cql_json = { 'bbox': [15, 48, 17, 50], 'filter-lang': 'cql2-json', 'collections': ['S2MSI1Ci'], 'filter': { 'op': 'and', 'args': [ { 'op': '=', 'args': [ { 'property': 'identifier' }, 'S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE' # noqa ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 0 cql_json = { 'bbox': [15, 48, 17, 50], 'filter-lang': 'cql2-json', 'collections': ['S2MSI1C'], 'filter': { 'op': 'and', 'args': [ { 'op': '=', 'args': [ { 'property': 'identifier' }, 'S2B_MSIL1C_20190910T095029_N0500_R079_T33UWQ_20230429T151337.SAFE' # noqa ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 1 for feature in content['features']: for link in feature['links']: if link['rel'] in ['self', 'parent', 'collection']: collection_match = f"collections/{cql_json['collections'][0]}" assert collection_match in link['href'] cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': '=', 'args': [{ 'property': 'parentidentifier' }, 'S2MSI1C'] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 12 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': 'in', 'args': [ { 'property': 'parentidentifier' }, [ 'ARD_S3', 'S3SLSTR' ] ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 0 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': 'in', 'args': [ { 'property': 'collections' }, [ 'ARD_S3', 'sentinel-2-l2a' ] ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 2 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': 'in', 'args': [ { 'property': 'parentidentifier' }, [ 'foo', 'sentinel-2-l2a' ] ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 2 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [{ 'op': '=', 'args': [{ 'property': 'identifier' }, 'S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE' # noqa ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 1 cql_json = { 'filter': { 'op': 'and', 'args': [ { 'op': '=', 'args': [ { 'property': 'parentidentifier' }, 'S2MSI2A' ] }, { 'op': 'in', 'args': [ { 'property': 'title' }, [ 'S2B_MSIL2A_20190910T095029_N0500_R079_T33UXP_20230430T083712.SAFE', # noqa 'S2B_MSIL2A_20190910T095029_N0500_R079_T33UXQ_20230430T083712.SAFE' # noqa ] ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 2 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': '<=', 'args': [ { 'property': 'date_creation' }, '2025-12-15' ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 1 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': '=', 'args': [ { 'property': 'platform' }, 'Sentinel-2A' ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 2 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': '=', 'args': [ { 'property': 'instrument' }, 'msi' ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 25 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': '<=', 'args': [ { 'property': 'date_modified' }, '2025-12-15' ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 1 cql_json = { 'filter': { 'op': 'and', 'args': [ { 'op': '=', 'args': [ { 'property': 'parentidentifier' }, 'S2MSI1C' ] }, { 'op': 's_intersects', 'args': [ { 'property': 'geometry' }, { 'type': 'Point', 'coordinates': [ 15.32, 46.88 ] } ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 2 cql_json = { 'filter': { 'op': 'and', 'args': [ { 'op': '=', 'args': [ { 'property': 'parentidentifier' }, 'S2MSI2A' ] }, { 'op': 's_intersects', 'args': [ { 'property': 'geometry' }, { 'type': 'Polygon', 'coordinates': [ [ [ 1.230469, 33.72434 ], [ 30.585938, 33.72434 ], [ 30.585938, 52.802761 ], [ 1.230469, 52.802761 ], [ 1.230469, 33.72434 ] ] ] } ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 11 cql_json = { 'collections': [ 'S2MSI2A' ], 'intersects': { 'geometry': { 'type': 'Polygon', 'coordinates': [ [ [ 1.230469, 33.72434 ], [ 30.585938, 33.72434 ], [ 30.585938, 52.802761 ], [ 1.230469, 52.802761 ], [ 1.230469, 33.72434 ] ] ] } } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 11 for link in content['links']: if link['rel'] == 'root': continue assert link['method'] == 'POST' assert link['body'] == cql_json cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': '<=', 'args': [ { 'property': 'cloudcover' }, 14 ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 2 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': '<=', 'args': [ { 'property': 'distancevalue' }, 0.66 ] } ] } } content = json.loads(api.items({}, cql_json, {})[2]) assert content['numberMatched'] == 1 cql_json = { 'filter-lang': 'cql2-json', 'filter': { 'op': 'and', 'args': [ { 'op': '=', 'args': [ { 'property': 'instrument' }, 'msi' ] } ] }, 'sortby': [{'field': 'datetime', 'direction': 'asc'}] } content = json.loads(api.items({}, cql_json, {})[2]) assert content['features'][0]['id'] == 'S2B_MSIL1C_20190910T095029_N0208_R079_T33TWN_20190910T120910.SAFE' # noqa cql_json['sortby'][0]['direction'] = 'desc' content = json.loads(api.items({}, cql_json, {})[2]) assert content['features'][0]['id'] == 'S2A_MSIL2A_20241128T092331_R093_T34SEJ_20241128T122153' # noqa def test_item(config): api = STACAPI(config) item = 'S2B_MSIL2A_20190910T095029_N0500_R079_T33TXN_20230430T083712.SAFE' headers, status, content = api.item({}, {}, 'metadata:main', item) content = json.loads(content) assert headers['Content-Type'] == 'application/geo+json' assert status == 200 assert content['id'] == item assert content['stac_version'] == '1.0.0' assert content['collection'] == 'S2MSI2A' assert content['geometry']['coordinates'][0][0][0] == 16.33660021997006 assert 'assets' in content assert 'B02' in content['assets'] assert 'product-metadata' in content['assets'] for link in content['links']: assert 'href' in link assert 'rel' in link headers, status, content = api.item({}, {}, 'foo', item) assert status == 400 def test_json_transaction(config, sample_collection, sample_item, sample_item_collection): api = STACAPI(config) request_headers = { 'Content-Type': 'application/json' } # ensure an item insert is part of a collection headers, status, content = api.manage_collection_item( request_headers, 'create', data=sample_item, collection='non-existent-collection') assert status == 400 # insert item headers, status, content = api.manage_collection_item( request_headers, 'create', data=sample_item, collection='metadata:main') assert status == 201 # test that item is in repository content = json.loads(api.item({}, {}, 'metadata:main', '20201211_223832_CS2')[2]) assert content['id'] == '20201211_223832_CS2' assert content['geometry'] is None assert content['properties']['datetime'] == '2020-12-11T22:38:32.125000Z' assert content['collection'] == 'metadata:main' # update item sample_item['properties']['datetime'] = '2021-12-14T22:38:32Z' headers, status, content = api.manage_collection_item( request_headers, 'update', item='20201211_223832_CS2', data=sample_item, collection='metadata:main') assert status == 204 # test that item is in repository content = json.loads(api.item({}, {}, 'metadata:main', '20201211_223832_CS2')[2]) assert content['id'] == '20201211_223832_CS2' assert content['properties']['datetime'] == sample_item['properties']['datetime'] # noqa assert content['collection'] == 'metadata:main' # delete item headers, status, content = api.manage_collection_item( request_headers, 'delete', item='20201211_223832_CS2') assert status == 200 # test that item is not in repository headers, status, content = api.item({}, {}, 'metadata:main', '20201211_223832_CS2') assert status == 404 content = api.items({}, None, {})[2] matched = json.loads(content)['numberMatched'] assert matched == 26 # insert item collection headers, status, content = api.manage_collection_item( request_headers, 'create', data=sample_item_collection, collection='metadata:main') assert status == 201 content = api.items({}, None, {})[2] matched = json.loads(content)['numberMatched'] assert matched == 28 # delete items from item collection headers, status, content = api.manage_collection_item( request_headers, 'delete', item='20201211_223832_CS2') assert status == 200 headers, status, content = api.manage_collection_item( request_headers, 'delete', item='20201212_223832_CS2') assert status == 200 collection_id = '123e4567-e89b-12d3-a456-426614174000' # insert collection headers, status, content = api.manage_collection_item( request_headers, 'create', data=sample_collection) assert status == 201 # test that collection is in repository headers, status, content = api.collections({}, {'f': 'json'}) content = json.loads(content) collection_found = False for collection in content['collections']: if collection['id'] == collection_id: collection_found = True assert collection_found headers, status, content = api.collection( {}, {'f': 'json'}, collection=collection_id) content = json.loads(content) assert content['id'] == collection_id assert content['title'] == 'ORT_SPOT7_20190922_094920500_000' # ensure collection is empty headers, status, content = api.items({}, {}, {'collections': collection_id, 'f': 'json'}) # noqa content = json.loads(content) assert content['numberMatched'] == 0 # update collection sample_collection['title'] = 'test title update' headers, status, content = api.manage_collection_item( request_headers, 'update', item=collection_id, data=sample_collection, collection='metadata:main') assert status == 204 headers, status, content = api.collection( {}, {'f': 'json'}, collection=collection_id) content = json.loads(content) assert content['title'] == sample_collection['title'] # test that item is in repository content = json.loads(api.item({}, {}, 'metadata:main', '20201211_223832_CS2')[2]) # delete collection headers, status, content = api.manage_collection_item( request_headers, 'delete', item=collection_id) content = json.loads(content) assert status == 200 # test that collection is not in repository headers, status, content = api.collections({}, {'f': 'json'}) content = json.loads(content) collection_found = False for collection in content['collections']: if collection['id'] == collection_id: collection_found = True assert not collection_found ================================================ FILE: tests/functionaltests/suites/utf-8/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/utf-8/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 10 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: ErrŹĆŁÓdd description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/utf-8/expected/post_GetCapabilities.xml ================================================ ErrŹĆŁÓdd pycsw is an OARec and OGC CSW server implementation written in Python catalogue discovery theme CSW 2.0.2 3.0.0 None None pycsw Kralidis, Tom Senior Systems Scientist +01-416-xxx-xxxx +01-416-xxx-xxxx TBA Toronto Ontario M9C 3Z9 Canada tomkralidis@gmail.com 0800h - 1600h EST During hours of service. Off on weekends. pointOfContact Filter_Capabilities OperationsMetadata ServiceIdentification ServiceProvider application/json application/xml http://www.w3.org/2001/XMLSchema http://www.w3.org/TR/xmlschema-1/ http://www.w3.org/XML/Schema csw:Record DescribeRecord.outputFormat DescribeRecord.schemaLanguage DescribeRecord.typeName GetCapabilities.sections GetRecordById.ElementSetName GetRecordById.outputFormat GetRecordById.outputSchema GetRecords.CONSTRAINTLANGUAGE GetRecords.ElementSetName GetRecords.outputFormat GetRecords.outputSchema GetRecords.resultType GetRecords.typeNames CQL_TEXT FILTER brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom hits results validate csw:Record csw:AnyText dc:contributor dc:creator dc:date dc:format dc:identifier dc:language dc:publisher dc:relation dc:rights dc:source dc:subject dc:title dc:type dct:abstract dct:alternative dct:modified dct:spatial ows:BoundingBox brief full summary application/json application/xml http://datacite.org/schema/kernel-4 http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://www.interlis.ch/INTERLIS2.3 http://www.opengis.net/cat/csw/2.0.2 http://www.opengis.net/cat/csw/csdgm http://www.w3.org/2005/Atom CSW 2.0.2 3.0.0 https://catalogue.arctic-sdi.org/csw 10 XML SOAP allowed gml:Point gml:LineString gml:Polygon gml:Envelope Between EqualTo GreaterThan GreaterThanEqualTo LessThan LessThanEqualTo Like NotEqualTo NullCheck length lower ltrim rtrim trim upper ================================================ FILE: tests/functionaltests/suites/utf-8/post/GetCapabilities.xml ================================================ 2.0.2 application/xml ================================================ FILE: tests/functionaltests/suites/xslt/custom.xslt ================================================ ================================================ FILE: tests/functionaltests/suites/xslt/default.yml ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2026 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= server: url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/xslt/default.yml mimetype: application/xml; charset=UTF-8 encoding: UTF-8 language: en-US maxrecords: 100 pretty_print: true #gzip_compresslevel: 8 #spatial_ranking: true profiles: - apiso logging: level: DEBUG # logfile: /tmp/pycsw.log federatedcatalogues: - id: fedcat01 type: CSW title: Arctic SDI url: https://catalogue.arctic-sdi.org/csw - id: fedcat02 type: OARec title: pycsw OGC CITE demo and Reference Implementation url: https://demo.pycsw.org/cite/collections/metadata:main manager: transactions: false allowed_ips: - 127.0.0.1 metadata: identification: title: pycsw Geospatial Catalogue description: pycsw is an OARec and OGC CSW server implementation written in Python keywords: - catalogue - discovery keywords_type: theme fees: None accessconstraints: None provider: name: pycsw url: https://pycsw.org/ contact: name: Kralidis, Tom position: Senior Systems Scientist address: TBA city: Toronto stateorprovince: Ontario postalcode: M9C 3Z9 country: Canada phone: +01-416-xxx-xxxx fax: +01-416-xxx-xxxx email: tomkralidis@gmail.com url: http://kralidis.ca/ hours: 0800h - 1600h EST instructions: During hours of service. Off on weekends. role: pointOfContact inspire: enabled: false languages_supported: - eng - gre default_language: eng date: 2011-03-29 gemet_keywords: - Utility and governmental services conformity_service: notEvaluated contact_name: National Technical University of Athens contact_email: tzotsos@gmail.com temp_extent: begin: 2011-02-01 end: 2011-03-30 xslt: - input_os: http://www.opengis.net/cat/csw/2.0.2 output_os: http://www.isotc211.org/2005/gmd transform: tests/functionaltests/suites/xslt/custom.xslt repository: # sqlite database: sqlite:///tests/functionaltests/suites/cite/data/cite.db table: records ================================================ FILE: tests/functionaltests/suites/xslt/expected/post_csw2-GetRecordById-xslt.xml ================================================ Mauris sed neque ================================================ FILE: tests/functionaltests/suites/xslt/expected/post_csw2-GetRecordById.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Mauris sed neque http://purl.org/dc/dcmitype/Dataset Vegetation-Cropland Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. 47.59 -4.1 51.22 0.89 ================================================ FILE: tests/functionaltests/suites/xslt/expected/post_csw2-GetRecords-all-xslt.xml ================================================ Lorem ipsum Maecenas enim Ut facilisis justo ut lacus Aliquam fermentum purus quis arcu Vestibulum massa purus Mauris sed neque Ñunç elementum Lorem ipsum dolor sit amet ================================================ FILE: tests/functionaltests/suites/xslt/expected/post_csw2-GetRecords-all.xml ================================================ Lorem ipsum Maecenas enim Ut facilisis justo ut lacus Aliquam fermentum purus quis arcu Vestibulum massa purus Mauris sed neque Ñunç elementum Lorem ipsum dolor sit amet ================================================ FILE: tests/functionaltests/suites/xslt/expected/post_csw3-GetRecordById-xslt.xml ================================================ Lorem ipsum ================================================ FILE: tests/functionaltests/suites/xslt/expected/post_csw3-GetRecordById.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f Lorem ipsum http://purl.org/dc/dcmitype/Image Tourism--Greece image/svg+xml Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. ================================================ FILE: tests/functionaltests/suites/xslt/expected/post_csw3-GetRecords-all-xslt.xml ================================================ Lorem ipsum Maecenas enim Ut facilisis justo ut lacus Aliquam fermentum purus quis arcu Vestibulum massa purus Mauris sed neque Ñunç elementum Lorem ipsum dolor sit amet ================================================ FILE: tests/functionaltests/suites/xslt/expected/post_csw3-GetRecords-all.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f http://purl.org/dc/dcmitype/Image image/svg+xml Lorem ipsum GR-22 Tourism--Greece Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd http://purl.org/dc/dcmitype/Service Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. 60.042 13.754 68.410 17.920 urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 Maecenas enim http://purl.org/dc/dcmitype/Text application/xhtml+xml Marine sediments Pellentesque tempus magna non sapien fringilla blandit. urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 http://purl.org/dc/dcmitype/Service Ut facilisis justo ut lacus Vegetation urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec Aliquam fermentum purus quis arcu http://purl.org/dc/dcmitype/Text Hydrography--Dictionaries application/pdf 2006-05-12 Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. ================================================ FILE: tests/functionaltests/suites/xslt/post/csw2-GetRecordById-xslt.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 summary ================================================ FILE: tests/functionaltests/suites/xslt/post/csw2-GetRecordById.xml ================================================ urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 summary ================================================ FILE: tests/functionaltests/suites/xslt/post/csw2-GetRecords-all-xslt.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/xslt/post/csw2-GetRecords-all.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/xslt/post/csw3-GetRecordById-xslt.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f ================================================ FILE: tests/functionaltests/suites/xslt/post/csw3-GetRecordById.xml ================================================ urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f ================================================ FILE: tests/functionaltests/suites/xslt/post/csw3-GetRecords-all-xslt.xml ================================================ full ================================================ FILE: tests/functionaltests/suites/xslt/post/csw3-GetRecords-all.xml ================================================ full ================================================ FILE: tests/functionaltests/test_xml_suites_functional.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # Tom Kralidis # # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Functional tests for several test suites""" import codecs from difflib import SequenceMatcher from difflib import unified_diff from io import BytesIO import json import os import re import wsgiref.util from lxml import etree from lxml import objectify import pytest from pycsw import server pytestmark = pytest.mark.functional def test_xml_based_suites( test_identifier, use_xml_canonicalisation, save_results_directory, configuration, request_method, request_data, expected_result, normalize_identifier_fields ): """Test XML-based suites. This function is automatically parametrized by pytest as a result of the ``conftest:pytest_generate_tests`` function. The input parameters are thus supplied by pytest as a result of discovering and parsing the existing test suites located under ``tests/functionaltests/suites``. Parameters ---------- configuration: dict The configuration to use with the pycsw server instance under test request_method: str The HTTP method of the request. Either GET or POST. request_data: str Either the path to the request file, for POST requests, or the request parameters, for GET requests expected_result: str Path to the file that holds the expected result normalize_identifier_fields: bool Whether to normalize the identifier fields in responses. This parameter is used only in the 'harvesting' and 'manager' suites use_xml_canonicalisation: bool Whether to compare results with their expected values by using xml canonicalisation or simply by doing a diff. save_results_directory: str Path to a directory where to test results should be saved to. A value of ``None`` (the default) means that results will not get saved to disk. """ request_environment = _prepare_wsgi_test_environment(request_method, request_data) pycsw_server = server.Csw(rtconfig=configuration, env=request_environment) encoding = "utf-8" status, raw_contents = pycsw_server.dispatch_wsgi() contents = raw_contents.decode(encoding) with codecs.open(expected_result, encoding=encoding) as fh: expected = fh.read() normalized_result = _normalize( contents, normalize_identifiers=normalize_identifier_fields ) if use_xml_canonicalisation: print("Comparing results using XML canonicalization...") matches_expected = _compare_with_xml_canonicalisation( normalized_result, expected) else: print("Comparing results using diffs...") matches_expected = _compare_without_xml_canonicalisation( normalized_result, expected) if not matches_expected and use_xml_canonicalisation: print(f"expected: {expected}") print(f"response: {normalized_result}") if save_results_directory is not None: _save_test_result(save_results_directory, normalized_result, test_identifier, encoding) assert matches_expected def _compare_with_xml_canonicalisation(normalized_result, expected): try: matches_expected = _test_xml_result(normalized_result, expected) except etree.XMLSyntaxError: # the file is either not XML (perhaps JSON?) or malformed matches_expected = _test_json_result(normalized_result, expected) except etree.C14NError: print("XML canonicalisation has failed. Trying to compare result " "with expected using difflib") matches_expected = _test_xml_diff(normalized_result, expected) return matches_expected def _compare_without_xml_canonicalisation(normalized_result, expected): return _test_xml_diff(normalized_result, expected) def _prepare_wsgi_test_environment(request_method, request_data): """Set up a testing environment for tests. Parameters ---------- request_method: str The HTTP method of the request. Sould be either GET or POST. request_data: str Either the path to the request file, for POST requests or the request parameters, for GET requests. Returns ------- request_environment: dict A mapping with the environment variables to use in the test """ request_environment = { "REQUEST_METHOD": request_method.upper(), "QUERY_STRING": "", "REMOTE_ADDR": "127.0.0.1" } if request_method == "POST": print(f"request_path: {request_data}") request_buffer = BytesIO() encoding = "utf-8" with codecs.open(request_data, encoding=encoding) as fh: contents = fh.read() request_buffer.write(contents.encode(encoding)) request_environment["CONTENT_LENGTH"] = request_buffer.tell() request_buffer.seek(0) request_environment["wsgi.input"] = request_buffer else: print(f"Request contents: {request_data}") request_environment["QUERY_STRING"] = request_data wsgiref.util.setup_testing_defaults(request_environment) return request_environment def _test_xml_result(result, expected, encoding="utf-8"): """Compare the XML test results with an expected value. This function compares the test result with the expected values by performing XML canonicalization (c14n)[1]_, which compares the semantic meanings of both XML files. Parameters ---------- result: str The result of running the test as a unicode string expected: str The expected outcome as a unicode string. Returns ------- bool Whether the result matches the expectations or not. Raises ------ etree.XMLSyntaxError If any of the input parameters is not a valid XMl. etree.C14NError If any of the input parameters cannot be canonicalized. This may happen if there are relative namespace URIs in any of the XML documents, as they are explicitly not allowed when doing XML c14n References ---------- .. [1] http://www.w3.org/TR/xml-c14n """ result_element = etree.fromstring(result.encode(encoding)) expected_element = etree.fromstring(expected.encode(encoding)) result_buffer = BytesIO() result_tree = result_element.getroottree() objectify.deannotate(result_tree, cleanup_namespaces=True) result_tree.write_c14n(result_buffer) expected_buffer = BytesIO() expected_tree = expected_element.getroottree() objectify.deannotate(expected_tree, cleanup_namespaces=True) expected_tree.write_c14n(expected_buffer) matches = result_buffer.getvalue() == expected_buffer.getvalue() return matches def _test_json_result(result, expected): """Compare the JSON test results with an expected value. Parameters ---------- result: str The result of running the test. expected: str The expected outcome. Returns ------- bool Whether the result matches the expectations or not. """ result_dict = json.loads(result) expected_dict = json.loads(expected) return result_dict == expected_dict def _test_xml_diff(result, expected): """Compare two XML strings by using python's ``difflib.SequenceMatcher``. This is a character-by-character comparison and does not take into account the semantic meaning of XML elements and attributes. Parameters ---------- result: str The result of running the test. expected: str The expected outcome. Returns ------- bool Whether the result matches the expectations or not. """ sequence_matcher = SequenceMatcher(None, result, expected) ratio = sequence_matcher.ratio() matches = ratio == pytest.approx(1.0) if not matches: print("Result does not match expected.") diff = unified_diff(result.splitlines(), expected.splitlines()) print("\n".join(list(diff))) return matches def _normalize(sresult, normalize_identifiers=False): """Normalize test output so it can be compared with the expected result. Several dynamic elements of a pycsw response (such as time, updateSequence, etc) are replaced with static constants to ease comparison. Parameters ---------- sresult: str The test result as a unicode string. normalize_identifiers: bool, optional Whether identifier fields should be normalized. Returns ------- str The normalized response. """ # XML responses version = re.search(r'', sresult) updatesequence = re.search(r'updateSequence="(\S+)"', sresult) timestamp = re.search(r'timestamp="(.*)"', sresult) timestamp2 = re.search(r'timeStamp="(.*)"', sresult) timestamp3 = re.search( r'(.*)', sresult ) timestamp4 = re.search( r'(.*)', sresult ) zrhost = re.search(r'(.*)', sresult) zrport = re.search(r'(.*)', sresult) elapsed_time = re.search(r'elapsedTime="(.*)"', sresult) expires = re.search(r'expires="(.*?)"', sresult) atom_updated = re.findall(r'(.*)', sresult) if version: sresult = sresult.replace(version.group(0), r'') if updatesequence: sresult = sresult.replace(updatesequence.group(0), r'updateSequence="PYCSW_UPDATESEQUENCE"') if timestamp: sresult = sresult.replace(timestamp.group(0), r'timestamp="PYCSW_TIMESTAMP"') if timestamp2: sresult = sresult.replace(timestamp2.group(0), r'timeStamp="PYCSW_TIMESTAMP"') if timestamp3: sresult = sresult.replace( timestamp3.group(0), r'PYCSW_TIMESTAMP' ) if timestamp4: sresult = sresult.replace( timestamp4.group(0), r'PYCSW_TIMESTAMP' ) if zrport: sresult = sresult.replace(zrport.group(0), r'PYCSW_PORT') if zrhost: sresult = sresult.replace(zrhost.group(0), r'PYCSW_HOST') if elapsed_time: sresult = sresult.replace(elapsed_time.group(0), r'elapsedTime="PYCSW_ELAPSED_TIME"') if expires: sresult = sresult.replace(expires.group(0), r'expires="PYCSW_EXPIRES"') for au in atom_updated: sresult = sresult.replace(au, r'PYCSW_TIMESTAMP') # for csw:HarvestResponse documents, mask identifiers # which are dynamically generated for OWS endpoints if sresult.find(r'HarvestResponse') != -1: identifier = re.findall( r'(\S+)', sresult ) for i in identifier: sresult = sresult.replace(i, r'PYCSW_IDENTIFIER') # JSON responses timestamp = re.search(r'"@timestamp": "(.*?)"', sresult) if timestamp: sresult = sresult.replace(timestamp.group(0), r'"@timestamp": "PYCSW_TIMESTAMP"') # harvesting-based GetRecords/GetRecordById responses if normalize_identifiers: dcid = re.findall( r'(urn:uuid.*)', sresult ) isoid = re.findall(r'id="(urn:uuid.*)"', sresult) isoid2 = re.findall( r'(urn:uuid.*) # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= import os JQUERY_VERSION = '3.6.0' print(''' pycsw Tester ''' % JQUERY_VERSION) print('''

pycsw Tester


HTTP POST

Request Response
Server:

HTTP GET

    ''') for root, dirs, files in os.walk('functionaltests/suites'): if files: for sfile in files: if sfile == 'requests.txt': # it's a list of GET requests file_path = os.path.join(root, sfile) with open(file_path) as f: for line in f: name, query_string = line.strip().partition(",")[::2] baseurl = "../csw.py" query_string = query_string.replace("&", "&") query = f"{baseurl}?{query_string}" print(f'
  • {name}
  • ') print('''

Valid HTML 5! Valid CSS!
''') ================================================ FILE: tests/unittests/test_fmt_json.py ================================================ # -*- coding: utf-8 -*- # ================================================================= # # Authors: Ricardo Garcia Silva # Tom Kralidis # # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2023 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Unit tests for pycsw.core.formats.fmt_json""" import pytest from pycsw.core.formats import fmt_json pytestmark = pytest.mark.unit def test_xml2dict(): identifier = "ac522ef2-89a6-11db-91b1-7eea55d89593" xml = f""" http://www.altova.com U.S. Geological Survey State of Texas U.S. Geological Survey Elevation, Hypsography, and Contours elevation Elevation data. {identifier} OfferedBy dd1b2ce7-0722-4642-8cd4-6f885f132777 Copyright © 2004, State of Texas Service National Elevation Mapping Service for Texas 2004-03-01 en -108.44 28.229 -96.223 34.353 2001-12-01T09:30:47Z 2001-12-17T09:30:47Z """.strip() namespaces = { "csw": "http://www.opengis.net/cat/csw/3.0", "ows": "http://www.opengis.net/ows/2.0", "xsi": "http://www.w3.org/2001/xmlschema-instance", "dc": "http://purl.org/dc/elements/1.1/", "dct": "http://purl.org/dc/terms/", } result = fmt_json.xml2dict(xml_string=xml, namespaces=namespaces) assert result["csw:GetRecordsResponse"]["csw:SearchResults"][ "csw:Record"]["dc:identifier"] == identifier ================================================ FILE: tests/unittests/test_metadata.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Unit tests for pycsw.core.metadata""" import pytest from pycsw.core import metadata pytestmark = pytest.mark.unit @pytest.mark.parametrize("bboxes, expected", [ ( [ "POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))", "POLYGON ((2 2, 2 3, 3 3, 3 2, 2 2))", ], "POLYGON((0.00 0.00, 0.00 3.00, 3.00 3.00, 3.00 0.00, 0.00 0.00))" ), ]) def test_bbox_from_polygons(bboxes, expected): result = metadata.bbox_from_polygons(bboxes) assert result == expected def test_bbox_from_polygons_invalid(): bboxes = "stuff" with pytest.raises(RuntimeError): metadata.bbox_from_polygons(bboxes) ================================================ FILE: tests/unittests/test_ogc_csw_csw3.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Unit tests for pycsw.ogc.csw.csw3""" import pytest from pycsw.ogc.csw import csw3 pytestmark = pytest.mark.unit @pytest.mark.parametrize("begin, end, expected", [ (0, 1, 1000), (3, 8, 5000), ]) def test_get_elapsed_time(begin, end, expected): result = csw3.get_elapsed_time(begin, end) assert result == expected ================================================ FILE: tests/unittests/test_opensearch.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Unit tests for pycsw.opensearch""" import pytest from pycsw import opensearch pytestmark = pytest.mark.unit @pytest.mark.parametrize("bbox, expected", [ ([10, 30, -10, -30], True), ([10.0, 30.0, -10.0, -30.0], True), (["10", "30", "-10", "-30"], True), ([-180, 30, -10, -30], True), ([180, 30, -10, -30], True), ([0, -90, -10, -30], True), ([0, 90, -10, -30], True), ([10, 30, -180, -30], True), ([10, 30, 180, -30], True), ([10, 30, -10, -90], True), ([10, 30, -10, 90], True), ([-190, 30, -10, -30], False), ([190, 30, -10, -30], False), ([10, 100, -10, -30], False), ([10, -100, -10, -30], False), ([10, 30, -190, -30], False), ([10, 30, 190, -30], False), ([10, 30, -10, -190], False), ([10, 30, -10, 190], False), ]) def test_validate_4326(bbox, expected): result = opensearch.validate_4326(bbox) assert result == expected ================================================ FILE: tests/unittests/test_repository.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # # Copyright (c) 2017 Ricardo Garcia Silva # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Unit tests for pycsw.core.repository""" import pytest from pycsw.core import repository pytestmark = pytest.mark.unit @pytest.mark.parametrize("data, input_, predicate, distance, expected", [ ("LINESTRING(0 0, 1 1)", "POINT(0.5 0.5)", "bbox", 0, "true"), ("LINESTRING(0 0, 1 1)", "POINT(2 2)", "bbox", 0, "false"), ("LINESTRING(0 0, 1 1)", "POINT(2 2)", "beyond", 1, "true"), ("LINESTRING(0 0, 1 1)", "POINT(2 2)", "beyond", 2, "false"), ("LINESTRING(0 0, 1 1)", "POINT(0.5 0.5)", "beyond", "false", "false"), ("LINESTRING(0 0, 1 1)", "POINT(0.5 0.5)", "contains", 0, "true"), ("LINESTRING(0 0, 1 1)", "POINT(2 2)", "contains", 0, "false"), ("LINESTRING(0 0, 1 1)", "LINESTRING(1 0, 0 1)", "crosses", 0, "true"), ("LINESTRING(0 0, 1 1)", "POINT(0.5 0.5)", "crosses", 0, "false"), ("POINT(1 1)", "POINT(1 1)", "equals", 0, "true"), ("LINESTRING(0 0, 1 1)", "POINT(0.5 0.5)", "equals", 0, "false"), ("LINESTRING(0 0, 1 1)", "POINT(0 0)", "touches", 0, "true"), ("LINESTRING(0 0, 1 1)", "POINT(0.5 0.5)", "touches", 0, "false"), ("POINT(0.5 0.5)", "LINESTRING(0 0, 1 1)", "within", 0, "true"), ("LINESTRING(0 0, 1 1)", "POINT(0.5 0.5)", "within", 0, "false"), (None, "POINT(0.5 0.5)", "within", 0, "false"), ("POINT(0.5 0.5)", None, "within", 0, "false"), (None, None, "within", 0, "false"), ("LINESTRING(0 0, 1 1)", "POINT(0.5 0.5)", "dwithin", "false", "false"), ]) def test_query_spatial(data, input_, predicate, distance, expected): result = repository.query_spatial( bbox_data_wkt=data, bbox_input_wkt=input_, predicate=predicate, distance=distance ) assert result == expected ================================================ FILE: tests/unittests/test_server.py ================================================ # ================================================================= # # Authors: Tom Kralidis # # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Unit tests for pycsw.server""" import io import os import pytest from pycsw.ogc.api.util import yaml_load pytestmark = pytest.mark.unit def test_config_env_vars(): os.environ['PYCSW_SERVER_URL'] = 'http://localhost:8000' cfg = """ server: url: ${PYCSW_SERVER_URL} """ parsed_config = yaml_load(io.StringIO(cfg)) assert parsed_config['server']['url'] == 'http://localhost:8000' ================================================ FILE: tests/unittests/test_util.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # Authors: Tom Kralidis # # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2025 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Unit tests for pycsw.core.util""" import datetime as dt import os import time from pathlib import Path from unittest import mock import pytest from shapely import from_geojson from shapely.wkt import loads from pycsw.core import util pytestmark = pytest.mark.unit def test_get_today_and_now(): fake_now = "2017-01-01T00:00:00Z" with mock.patch.object(util.time, "localtime") as mock_localtime: mock_localtime.return_value = time.strptime( fake_now, "%Y-%m-%dT%H:%M:%SZ" ) result = util.get_today_and_now() assert result == fake_now @pytest.mark.parametrize("value, expected", [ (dt.date(2017, 1, 23), "2017-01-23"), (dt.datetime(2017, 1, 23), "2017-01-23"), (dt.datetime(2017, 1, 23, 20, 32, 10), "2017-01-23T20:32:10Z"), (dt.datetime(2017, 1, 23, 10), "2017-01-23T10:00:00Z"), (dt.datetime(2017, 1, 23, 10, 20), "2017-01-23T10:20:00Z"), ]) def test_datetime2iso8601(value, expected): result = util.datetime2iso8601(value) assert result == expected @pytest.mark.parametrize("version, expected", [ ("2", -1), ("1.2", -1), ("5.4.3.2", -1), ("This is a regular string, not a version", -1), ("3.4.1", 30401), ]) def test_get_version_integer(version, expected): result = util.get_version_integer(version) assert result == expected @pytest.mark.parametrize("invalid_version", [ 2, 2.2, None, ]) def test_get_version_integer_invalid_version(invalid_version): with pytest.raises(RuntimeError): util.get_version_integer(invalid_version) @pytest.mark.parametrize("xpath_expression, expected", [ ("ns1:first", "{something}first"), ("ns1:first/ns2:second", "{something}first/{other}second"), ("ns1:first/ns2:second[1]", "{something}first/{other}second[1]"), ("ns1:first/*/ns3:third", "{something}first/*/{another}third"), ("", ""), ]) def test_nspath_eval(xpath_expression, expected): nsmap = { "ns1": "something", "ns2": "other", "ns3": "another", } result = util.nspath_eval(xpath_expression, nsmap) assert result == expected def test_nspath_eval_invalid_element(): with pytest.raises(RuntimeError): util.nspath_eval( xpath="ns1:tag1/ns2:ns3:tag2", nsmap={ "ns1": "something", "ns2": "other", "ns3": "another", } ) @pytest.mark.parametrize("envelope, expected", [ ("ENVELOPE (-180,180,90,-90)", "-180,-90,180,90"), (" ENVELOPE(-180,180,90,-90)", "-180,-90,180,90"), (" ENVELOPE( -180, 180, 90, -90) ", "-180,-90,180,90"), ]) def test_wktenvelope2bbox(envelope, expected): result = util.wktenvelope2bbox(envelope) assert result == expected # TODO - Add more WKT cases for other geometry types @pytest.mark.parametrize("wkt, bounds, expected", [ ("POINT (10 10)", True, (10.0, 10.0, 10.0, 10.0)), ("SRID=4326;POINT (10 10)", True, (10.0, 10.0, 10.0, 10.0)), ("POINT (10 10)", False, loads("POINT (10 10)")), ("SRID=4326;POINT (10 10)", False, loads("POINT (10 10)")), ]) def test_wkt2geom(wkt, bounds, expected): result = util.wkt2geom(wkt, bounds=bounds) assert result == expected @pytest.mark.parametrize("bbox, expected", [ ( "0.0, 10.0, 30.0, 15.0", "POLYGON((0.00 10.00, 0.00 15.00, 30.00 15.00, " "30.00 10.00, 0.00 10.00))" ), ( "-10.0, 10.0, 30.0, 15.0", "POLYGON((-10.00 10.00, -10.00 15.00, 30.00 15.00, " "30.00 10.00, -10.00 10.00))" ) ]) def test_bbox2wktpolygon(bbox, expected): result = util.bbox2wktpolygon(bbox) assert result == expected def test_transform_mappings(): queryables = { "q1": {"xpath": "p1", "dbcol": "col1"}, "q2": {"xpath": "p2", "dbcol": "col2"}, } typename = {"q2": "q1"} duplicate_queryables = queryables.copy() duplicate_typename = typename.copy() util.transform_mappings(duplicate_queryables, duplicate_typename) assert duplicate_queryables["q1"]["xpath"] == queryables["q2"]["xpath"] assert duplicate_queryables["q1"]["dbcol"] == queryables["q2"]["dbcol"] @pytest.mark.parametrize("name, value, expected", [ ("name", "john", "john"), ("date", dt.date(2017, 1, 1), "2017-01-01"), ("datetime", dt.datetime(2017, 1, 1, 10, 5), "2017-01-01T10:05:00Z"), ("some_callable", os.getcwd, os.getcwd()), ]) def test_getqattr_no_link(name, value, expected): class Phony(object): pass instance = Phony() setattr(instance, name, value) result = util.getqattr(instance, name) assert result == expected def test_getqattr_link(): some_object = mock.MagicMock() some_object.some_link.return_value = [ ["one", "two"], ["three", "four"], ] result = util.getqattr(some_object, "some_link") assert result == "one,two^three,four" def test_getqattr_invalid(): result = util.getqattr(dt.date(2017, 1, 1), "name") assert result is None def test_http_request_post(): # here we replace owslib.util.http_post with a mock object # because we are not interested in testing owslib method = "POST" url = "some_phony_url" request = "some_phony_request" timeout = 40 with mock.patch("pycsw.core.util.http_post", autospec=True) as mock_http_post: util.http_request( method=method, url=url, request=request, timeout=timeout ) mock_http_post.assert_called_with(url, request, timeout=timeout) @pytest.mark.parametrize("url, expected", [ ("http://host/wms", "http://host/wms?"), ("http://host/wms?foo=bar&", "http://host/wms?foo=bar&"), ("http://host/wms?foo=bar", "http://host/wms?foo=bar&"), ("http://host/wms?", "http://host/wms?"), ("http://host/wms?foo", "http://host/wms?foo&"), ]) def test_bind_url(url, expected): result = util.bind_url(url) assert result == expected @pytest.mark.parametrize("ip, netmask, expected", [ ("192.168.100.14", "192.168.100.0/24", True), ("192.168.100.14", "192.168.0.0/24", False), ("192.168.100.14", "192.168.0.0/16", True), ]) def test_ip_in_network_cidr(ip, netmask, expected): result = util.ip_in_network_cidr(ip, netmask) assert result == expected @pytest.mark.parametrize("ip, whitelist, expected", [ ("192.168.100.14", [], False), ("192.168.100.14", ["192.168.100.15"], False), ("192.168.100.14", ["192.168.100.15", "192.168.100.14"], True), ("192.168.100.14", ["192.168.100.*"], True), ("192.168.100.14", ["192.168.100.15", "192.168.100.*"], True), ("192.168.100.14", ["192.168.100.0/24"], True), ("192.168.100.14", ["192.168.100.15", "192.168.100.0/24"], True), ("192.168.10.14", ["192.168.100.15", "192.168.0.0/16"], True), ]) def test_ipaddress_in_whitelist(ip, whitelist, expected): result = util.ipaddress_in_whitelist(ip, whitelist) assert result == expected @pytest.mark.parametrize("linkstr, expected", [ # old style CSV ("roads,my roads,OGC:WMS,http://example.org/wms", [{ "name": "roads", "description": "my roads", "protocol": "OGC:WMS", "url": "http://example.org/wms" }] ), # old style CSV with some empty tokens (",,,http://example.org/wms", [{ "name": None, "description": None, "protocol": None, "url": "http://example.org/wms" }] ), # old style CSV with empty tokens (",,,", [{ "name": None, "description": None, "protocol": None, "url": None }] ), # old style CSV with 2 links ("roads,my roads,OGC:WMS,http://example.org/wms^roads,my roads,OGC:WFS,http://example.org/wfs", [{ "name": "roads", "description": "my roads", "protocol": "OGC:WMS", "url": "http://example.org/wms" }, { "name": "roads", "description": "my roads", "protocol": "OGC:WFS", "url": "http://example.org/wfs" }] ), # JSON style ('[{"name": "roads", "description": "my roads", "protocol": "OGC:WMS", "url": "http://example.org/wms"}]', [{ "name": "roads", "description": "my roads", "protocol": "OGC:WMS", "url": "http://example.org/wms" }] ), # JSON style with some empty keys ('[{"name": "roads", "description": null, "protocol": "OGC:WMS", "url": "http://example.org/wms"}]', [{ "name": "roads", "description": None, "protocol": "OGC:WMS", "url": "http://example.org/wms" }] ), # JSON style with multiple links ('[{"name": "roads", "description": null, "protocol": "OGC:WMS", "url": "http://example.org/wms"},' '{"name": "roads", "description": null, "protocol": "OGC:WFS", "url": "http://example.org/wfs"}]', [{ "name": "roads", "description": None, "protocol": "OGC:WMS", "url": "http://example.org/wms" }, { "name": "roads", "description": None, "protocol": "OGC:WFS", "url": "http://example.org/wfs" }] ) ]) def test_jsonify_links(linkstr, expected): result = util.jsonify_links(linkstr) assert isinstance(result, list) assert result == expected @pytest.mark.parametrize("value, result", [ ("foo", False), (None, True), ('', True), (' ', True), (' ', True), ]) def test_is_none_or_empty(value, result): assert util.is_none_or_empty(value) is result @pytest.mark.parametrize("import_path, expected_attribute", [ pytest.param("itertools", "count", id="import from stdlib"), pytest.param("pycsw.core.repository", "setup", id="dotted path import from pycsw"), pytest.param(__file__, "test_programmatic_import", id="filesystem path import"), ]) def test_programmatic_import(import_path, expected_attribute): imported_module = util.programmatic_import(import_path) assert getattr(imported_module, expected_attribute) @pytest.mark.parametrize("invalid_import_path", [ "dummy", "dummy.submodule", "/non-existent/path", str(Path(__file__).parent / "invalid_path"), ]) def test_programmatic_import_with_invalid_path(invalid_import_path): result = util.programmatic_import(invalid_import_path) assert result is None def test_sanitize_url(): result = util.sanitize_db_connect("postgresql://username:password@localhost/pycsw") assert result == "postgresql://***:***@localhost/pycsw" def test_str2bool(): assert util.str2bool('true') assert util.str2bool(True) assert util.str2bool('1') assert util.str2bool('yes') assert util.str2bool('on') assert not util.str2bool('0') assert not util.str2bool('false') assert not util.str2bool(False) assert not util.str2bool('off') assert not util.str2bool('no') @pytest.mark.parametrize("geometry,expected", [ ({ 'type': 'Point', 'coordinates': [102.0, 0.5] }, '102.0,0.5,102.0,0.5'), ({ 'type': 'LineString', 'coordinates': [ [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0] ] }, '102.0,0.0,105.0,1.0'), ({ 'type': 'Polygon', 'coordinates': [[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]] }, '100.0,0.0,101.0,1.0'), ({ 'type': 'MultiPolygon', 'coordinates': [[[ [30.0, 20.0], [45.0, 40.0], [10.0, 40.0], [30.0, 20.0] ]], [[ [15.0, 5.0], [40.0, 10.0], [10.0, 20.0], [5.0, 10.0], [15.0, 5.0] ]]] }, '5.0,5.0,45.0,40.0'), ({ 'type': 'MultiPoint', 'coordinates': [ [10.0, 40.0], [40.0, 30.0], [20.0, 20.0], [30.0, 10.0] ] }, '10.0,10.0,40.0,40.0') ]) def test_geojson_geometry2bbox(geometry, expected): bounds = util.geojson_geometry2bbox(geometry) assert bounds == expected ================================================ FILE: tests/unittests/test_wsgi.py ================================================ # ================================================================= # # Authors: Ricardo Garcia Silva # Tom Kralidis # # Copyright (c) 2017 Ricardo Garcia Silva # Copyright (c) 2024 Tom Kralidis # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ================================================================= """Unit tests for pycsw.wsgi""" from unittest import mock from wsgiref.util import setup_testing_defaults import pytest from pycsw import wsgi pytestmark = pytest.mark.unit @pytest.mark.parametrize("process_env, wsgi_env, fake_dir, expected", [ ({}, None, "dummy", "dummy"), ({"PYCSW_ROOT": "this"}, None, "dummy", "this"), ({"PYCSW_ROOT": "this"}, {"PYCSW_ROOT": "that"}, "dummy", "this"), ({}, {"PYCSW_ROOT": "that"}, "dummy", "that"), ]) def test_get_pycsw_root_path(process_env, wsgi_env, fake_dir, expected): with mock.patch("pycsw.wsgi.os", autospec=True) as mock_os: mock_os.path.dirname.return_value = fake_dir result = wsgi.get_pycsw_root_path( process_env, request_environment=wsgi_env ) assert result == expected @pytest.mark.parametrize("process_env, wsgi_env, pycsw_root, expected", [ ({}, {}, "dummy", "dummy/default.yml"), ({"PYCSW_CONFIG": "default.yml"}, {}, "dummy", "default.yml"), ( {"PYCSW_CONFIG": "/some/abs/path/default.yml"}, {}, "dummy", "/some/abs/path/default.yml" ), ( {"PYCSW_CONFIG": "default.yml"}, {"QUERY_STRING": ""}, "dummy", "default.yml" ), ( {"PYCSW_CONFIG": "default.yml"}, {"QUERY_STRING": "config=other.yml"}, "dummy", "other.yml" ), ( {"PYCSW_CONFIG": "default.yml"}, {"QUERY_STRING": "config=/other/path/other.yml"}, "dummy", "/other/path/other.yml" ), ]) def test_get_configuration_path(process_env, wsgi_env, pycsw_root, expected): result = wsgi.get_configuration_path(process_env, wsgi_env, pycsw_root) assert result == expected @pytest.mark.parametrize("compression_level", [ 1, 2, 3, 4, 5, 6, 7, 8, 9, ]) def test_compress_response(compression_level): fake_response = "dummy" with mock.patch("pycsw.wsgi.gzip", autospec=True) as mock_gzip: compressed_response, headers = wsgi.compress_response( fake_response, compression_level) creation_kwargs = mock_gzip.GzipFile.call_args[1] assert creation_kwargs["compresslevel"] == compression_level assert headers["Content-Encoding"] == "gzip" def test_application_no_gzip(): fake_config_path = "fake_config_path" fake_status = "fake_status" fake_response = "fake_response" fake_content_type = "fake_content_type" request_env = {} setup_testing_defaults(request_env) mock_start_response = mock.MagicMock() with mock.patch("pycsw.wsgi.server", autospec=True) as mock_server, \ mock.patch.object( wsgi, "get_configuration_path") as mock_get_config_path: mock_get_config_path.return_value = fake_config_path mock_csw_class = mock_server.Csw mock_pycsw = mock_csw_class.return_value mock_pycsw.dispatch_wsgi.return_value = (fake_status, fake_response) mock_pycsw.contenttype = fake_content_type result = wsgi.application(request_env, mock_start_response) mock_csw_class.assert_called_with(fake_config_path, request_env) start_response_args = mock_start_response.call_args[0] assert fake_status in start_response_args assert result == [fake_response] def test_application_gzip(): fake_config_path = "fake_config_path" fake_status = "fake_status" fake_response = "fake_response" fake_content_type = "fake_content_type" fake_compression_level = 5 fake_compressed_contents = "fake compressed contents" fake_compression_headers = {"phony": "dummy"} request_env = {"HTTP_ACCEPT_ENCODING": "gzip"} setup_testing_defaults(request_env) mock_start_response = mock.MagicMock() with mock.patch("pycsw.wsgi.server", autospec=True) as mock_server, \ mock.patch.object( wsgi, "get_configuration_path") as mock_get_config_path, \ mock.patch.object(wsgi, "compress_response") as mock_compress: mock_compress.return_value = (fake_compressed_contents, fake_compression_headers) mock_get_config_path.return_value = fake_config_path mock_csw_class = mock_server.Csw mock_csw_class.return_value = mock.MagicMock( config={"server": {"gzip_compresslevel": fake_compression_level}} ) mock_pycsw = mock_csw_class.return_value mock_pycsw.dispatch_wsgi.return_value = (fake_status, fake_response) mock_pycsw.contenttype = fake_content_type wsgi.application(request_env, mock_start_response) mock_compress.assert_called_with(fake_response, fake_compression_level) ================================================ FILE: tox.ini ================================================ # Tox (http://tox.testrun.org/) is a tool for running tests # in multiple virtualenvs. This configuration file will run the # test suite on all supported python versions. To use it, "pip3 install tox" # and then run "tox" from this directory. [tox] envlist = {py312}-sqlite skip_missing_interpreters = True [testenv] allowlist_externals = coverage deps = -rrequirements-dev.txt usedevelop = True commands = coverage run --parallel-mode --module pytest {posargs} coverage combine --append coverage report setenv = VIRTUALENV_SYSTEM_SITE_PACKAGES=true