Skip to content
Snippets Groups Projects
Commit 18234f16 authored by esikkala's avatar esikkala
Browse files

Add Hellerau perspective

parent 59afba65
No related branches found
No related tags found
No related merge requests found
Showing
with 663 additions and 2 deletions
...@@ -5,6 +5,7 @@ import Perspective2 from './Perspective2' ...@@ -5,6 +5,7 @@ import Perspective2 from './Perspective2'
import Perspective3 from './Perspective3' import Perspective3 from './Perspective3'
import Finds from './Finds' import Finds from './Finds'
import EmloActors from './EmloActors' import EmloActors from './EmloActors'
import Hellerau from './Hellerau'
/** /**
* A component for creating a faceted search perspective for a semantic portal. * A component for creating a faceted search perspective for a semantic portal.
...@@ -153,6 +154,34 @@ const FacetedSearchPerspective = props => { ...@@ -153,6 +154,34 @@ const FacetedSearchPerspective = props => {
rootUrl={props.rootUrl} rootUrl={props.rootUrl}
/> />
break break
case 'hellerau':
perspectiveElement =
<Hellerau
facetResults={props.facetResults}
placesResults={props.placesResults}
leafletMapLayers={props.leafletMap}
facetData={props.facetData}
facetDataConstrainSelf={props.facetDataConstrainSelf}
fetchPaginatedResults={props.fetchPaginatedResults}
fetchResults={props.fetchResults}
fetchFacetConstrainSelf={props.fetchFacetConstrainSelf}
fetchGeoJSONLayers={props.fetchGeoJSONLayers}
fetchGeoJSONLayersBackend={props.fetchGeoJSONLayersBackend}
clearGeoJSONLayers={props.clearGeoJSONLayers}
fetchByURI={props.fetchByURI}
updatePage={props.updatePage}
updateRowsPerPage={props.updateRowsPerPage}
updateFacetOption={props.updateFacetOption}
sortResults={props.sortResults}
showError={props.showError}
routeProps={props.routeProps}
perspective={props.perspective}
animationValue={props.animationValue}
animateMap={props.animateMap}
screenSize={props.screenSize}
rootUrl={props.rootUrl}
/>
break
default: default:
perspectiveElement = <div /> perspectiveElement = <div />
break break
......
import React from 'react'
import PropTypes from 'prop-types'
import { Route, Redirect } from 'react-router-dom'
import PerspectiveTabs from '../../main_layout/PerspectiveTabs'
import ResultTable from '../../facet_results/ResultTable'
import LeafletMap from '../../facet_results/LeafletMap'
import Deck from '../../facet_results/Deck'
import Export from '../../facet_results/Export'
import MigrationsMapLegend from './MigrationsMapLegend'
import { MAPBOX_ACCESS_TOKEN, MAPBOX_STYLE } from '../../../configs/sampo/GeneralConfig'
const Hellerau = props => {
const { rootUrl, perspective } = props
return (
<>
<PerspectiveTabs
routeProps={props.routeProps}
tabs={props.perspective.tabs}
screenSize={props.screenSize}
/>
<Route
exact path={`${rootUrl}/${perspective.id}/faceted-search`}
render={() => <Redirect to={`${rootUrl}/${perspective.id}/faceted-search/table`} />}
/>
<Route
path={[`${props.rootUrl}/${perspective.id}/faceted-search/table`, '/iframe.html']}
render={routeProps =>
<ResultTable
data={props.facetResults}
facetUpdateID={props.facetData.facetUpdateID}
resultClass='hellerau'
facetClass='hellerau'
fetchPaginatedResults={props.fetchPaginatedResults}
updatePage={props.updatePage}
updateRowsPerPage={props.updateRowsPerPage}
sortResults={props.sortResults}
routeProps={routeProps}
rootUrl={rootUrl}
/>}
/>
<Route
path={`${rootUrl}/${perspective.id}/faceted-search/migrations`}
render={() =>
<Deck
results={props.facetResults.results}
facetUpdateID={props.facetData.facetUpdateID}
resultClass='hellerauMigrations'
facetClass='hellerau'
fetchResults={props.fetchResults}
fetching={props.placesResults.fetching}
legendComponent={<MigrationsMapLegend />}
layerType='arcLayer'
mapBoxAccessToken={MAPBOX_ACCESS_TOKEN}
mapBoxStyle={MAPBOX_STYLE}
/>}
/>
</>
)
}
Hellerau.propTypes = {
facetResults: PropTypes.object.isRequired,
placesResults: PropTypes.object.isRequired,
leafletMapLayers: PropTypes.object.isRequired,
facetData: PropTypes.object.isRequired,
fetchResults: PropTypes.func.isRequired,
clearGeoJSONLayers: PropTypes.func.isRequired,
fetchGeoJSONLayers: PropTypes.func.isRequired,
fetchGeoJSONLayersBackend: PropTypes.func.isRequired,
fetchPaginatedResults: PropTypes.func.isRequired,
fetchByURI: PropTypes.func.isRequired,
updatePage: PropTypes.func.isRequired,
updateRowsPerPage: PropTypes.func.isRequired,
sortResults: PropTypes.func.isRequired,
routeProps: PropTypes.object.isRequired,
updateFacetOption: PropTypes.func.isRequired,
perspective: PropTypes.object.isRequired,
animationValue: PropTypes.array.isRequired,
animateMap: PropTypes.func.isRequired,
screenSize: PropTypes.string.isRequired,
rootUrl: PropTypes.string.isRequired,
showError: PropTypes.func.isRequired
}
export default Hellerau
...@@ -307,6 +307,42 @@ export const perspectiveConfig = [ ...@@ -307,6 +307,42 @@ export const perspectiveConfig = [
} }
] ]
}, },
{
id: 'hellerau',
isHidden: true,
frontPageImage: null,
perspectiveDescHeight: 160,
defaultActiveFacets: new Set(['prefLabel']),
tabs: [
{
id: 'table',
value: 0,
icon: <CalendarViewDayIcon />
},
{
id: 'migrations',
value: 1,
icon: <RedoIcon />
},
{
id: 'export',
value: 2,
icon: <CloudDownloadIcon />
}
],
instancePageTabs: [
{
id: 'table',
value: 0,
icon: <CalendarViewDayIcon />
},
{
id: 'export',
value: 1,
icon: <CloudDownloadIcon />
}
]
},
{ {
id: 'clientFSPlaces', id: 'clientFSPlaces',
frontPageImage: placesImage, frontPageImage: placesImage,
......
...@@ -626,6 +626,9 @@ const mapStateToProps = state => { ...@@ -626,6 +626,9 @@ const mapStateToProps = state => {
emloActors: state.emloActors, emloActors: state.emloActors,
emloActorsFacets: state.emloActorsFacets, emloActorsFacets: state.emloActorsFacets,
emloActorsFacetsConstrainSelf: state.emloActorsFacetsConstrainSelf, emloActorsFacetsConstrainSelf: state.emloActorsFacetsConstrainSelf,
hellerau: state.hellerau,
hellerauFacets: state.hellerauFacets,
hellerauFacetsConstrainSelf: state.hellerauFacetsConstrainSelf,
leafletMap: state.leafletMap, leafletMap: state.leafletMap,
fullTextSearch: state.fullTextSearch, fullTextSearch: state.fullTextSearch,
clientFS: state.clientSideFacetedSearch, clientFS: state.clientSideFacetedSearch,
......
...@@ -23,6 +23,9 @@ import findsFacets from './sampo/findsFacets' ...@@ -23,6 +23,9 @@ import findsFacets from './sampo/findsFacets'
import emloActors from './sampo/emloActors' import emloActors from './sampo/emloActors'
import emloActorsFacets from './sampo/emloActorsFacets' import emloActorsFacets from './sampo/emloActorsFacets'
import emloActorsFacetsConstrainSelf from './sampo/emloActorsFacetsConstrainSelf' import emloActorsFacetsConstrainSelf from './sampo/emloActorsFacetsConstrainSelf'
import hellerau from './sampo/hellerau'
import hellerauFacets from './sampo/hellerauFacets'
import hellerauFacetsConstrainSelf from './sampo/hellerauFacetsConstrainSelf'
import findsFacetsConstrainSelf from './sampo/findsFacetsConstrainSelf' import findsFacetsConstrainSelf from './sampo/findsFacetsConstrainSelf'
import perspective1Facets from './sampo/perspective1Facets' import perspective1Facets from './sampo/perspective1Facets'
import perspective1FacetsConstrainSelf from './sampo/perspective1FacetsConstrainSelf' import perspective1FacetsConstrainSelf from './sampo/perspective1FacetsConstrainSelf'
...@@ -54,6 +57,9 @@ const reducer = combineReducers({ ...@@ -54,6 +57,9 @@ const reducer = combineReducers({
emloActors, emloActors,
emloActorsFacets, emloActorsFacets,
emloActorsFacetsConstrainSelf, emloActorsFacetsConstrainSelf,
hellerau,
hellerauFacets,
hellerauFacetsConstrainSelf,
leafletMap, leafletMap,
animation, animation,
options, options,
......
import { handleDataFetchingAction } from '../general/results'
export const INITIAL_STATE = {
results: null,
resultUpdateID: 0,
resultsSparqlQuery: null,
paginatedResults: [],
paginatedResultsSparqlQuery: null,
resultCount: 0,
page: -1,
pagesize: 10,
sortBy: null,
sortDirection: null,
fetching: false,
fetchingResultCount: false,
facetedSearchHeaderExpanded: false,
instancePageHeaderExpanded: false,
instanceTableData: null,
instanceTableExternalData: null,
instanceAnalysisData: null,
instanceAnalysisDataUpdateID: 0,
instanceSparqlQuery: null,
properties: [
{
id: 'uri',
valueType: 'object',
makeLink: true,
externalLink: true,
sortValues: true,
numberedList: false,
onlyOnInstancePage: true
},
{
id: 'prefLabel',
valueType: 'object',
makeLink: true,
externalLink: false,
sortValues: true,
numberedList: false,
minWidth: 250
}
]
}
const resultClasses = new Set([
'hellerau', 'hellerauMigrations'
])
const hellerau = (state = INITIAL_STATE, action) => {
if (resultClasses.has(action.resultClass)) {
return handleDataFetchingAction(state, action)
} else return state
}
export default hellerau
import { handleFacetAction } from '../general/facets'
export const INITIAL_STATE = {
updatedFacet: null,
facetUpdateID: 0,
updatedFilter: null,
facets: {
prefLabel: {
id: 'prefLabel',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: null,
sortDirection: null,
sortButton: false,
spatialFilterButton: false,
isFetching: false,
searchField: false,
containerClass: 'one',
filterType: 'textFilter',
textFilter: null,
priority: 1
}
}
}
const hellerauFacets = (state = INITIAL_STATE, action) => {
if (action.facetClass === 'hellerau') {
return handleFacetAction(state, action)
} else return state
}
export default hellerauFacets
import { handleFacetConstrainSelfAction } from '../general/facetsConstrainSelf'
export const INITIAL_STATE = {
updatedFacet: null,
facetUpdateID: 0,
updatedFilter: null,
facets: {
findName: {
id: 'find_name',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
pieChartButton: true,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
priority: 1
},
objectType: {
id: 'objectType',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
pieChartButton: true,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
type: 'hierarchical',
priority: 6
},
specification: {
id: 'specification',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
pieChartButton: true,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
priority: 2
},
type: {
id: 'type',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
chartButton: true,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
priority: 2
},
subCategory: {
id: 'subCategory',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
chartButton: false,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
priority: 3
},
objectSubCategory: {
id: 'subCategory',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
chartButton: false,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
priority: 3
},
material: {
id: 'material',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
chartButton: false,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
priority: 4,
type: 'hierarchical'
},
period: {
id: 'period',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
chartButton: false,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
priority: 5
},
periodObject: {
id: 'periodObject',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
chartButton: false,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
type: 'hierarchical',
priority: 5
},
materialLiteral: {
id: 'materialLiteral',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
pieChartButton: true,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
priority: 4
},
place: {
id: 'place',
// predicate: defined in backend
distinctValueCount: 0,
values: [],
flatValues: [],
sortBy: 'instanceCount',
sortDirection: 'desc',
sortButton: true,
spatialFilterButton: false,
pieChartButton: true,
isFetching: false,
searchField: true,
containerClass: 'ten',
filterType: 'uriFilter',
uriFilter: null,
type: 'hierarchical',
priority: 6
}
}
}
const hellerauFacetsConstrainSelf = (state = INITIAL_STATE, action) => {
if (action.facetClass === 'hellerau') {
return handleFacetConstrainSelfAction(state, action)
} else return state
}
export default hellerauFacetsConstrainSelf
...@@ -1939,6 +1939,124 @@ export default { ...@@ -1939,6 +1939,124 @@ export default {
} }
} }
}, },
hellerau: {
label: 'Hellerau',
facetResultsType: 'people',
shortDescription: 'Description',
longDescription: `
<p class="MuiTypography-root MuiTypography-body1 MuiTypography-paragraph">
Use this perspective to access data related to events associated with the
histories of manuscripts and manuscript collections over the centuries.
See <a href="/instructions">instructions</a> for using the filters.
The result view can be selected using the tabs:
</p>
<ul class="MuiTypography-root MuiTypography-body1">
<li>
<strong>TABLE</STRONG> view includes all events in the MMM data.
</li>
<li>
<strong>MAP</STRONG> view visualizes the events that have location information on a map.
</li>
<li>
<strong>EXPORT</strong> the SPARQL query used to generate the result
table view into YASGUI query editor.
</li>
</ul>
`,
instancePage: {
label: 'Place',
description: `
<p class="MuiTypography-root MuiTypography-body1 MuiTypography-paragraph">
Events refer to various activities related to Manuscripts and Actors. Event
types include Production, Transfer of Custody, and Activity events.
Production events refer to the production of the physical manuscript.
Transfer of Custody events indicate a change of ownership that involved
a transaction of some kind, usually through an auction house or bookseller.
The generic Activity event type covers all other types of events.
</p>
`
},
properties: {
uri: {
label: 'URI',
description: 'Uniform Resource Identifier'
},
type: {
label: 'Type',
description: `
Distinguish between “Transfer of Custody”, “Production”, and other
types of “Activity” events.
`
},
prefLabel: {
label: 'Label',
description: `
Preferable place label.
`
},
country: {
label: 'Country',
description: `
Related country.
`
},
broader: {
label: 'Parent place',
description: `
Parent place, e.g. a municipality, county or country.
`
},
narrower: {
label: 'Places within',
description: `
Smaller places, e.g. towns and villages contained within the place.
`
},
place: {
label: 'Place',
description: `
The specific place(s) associated with the event.
`
},
placeType: {
label: 'Place type',
description: `
The type of the specific place(s) associated with the event.
`
},
note: {
label: 'Note',
description: `
Note
`
},
surrender: {
label: 'Custody surrendered by',
description: `
Custody surrendered by
`
},
receiver: {
label: 'Custody received by',
description: `
Custody received by
`
},
observedOwner: {
label: 'Observed owner',
description: `
Observed owner
`
},
source: {
label: 'Source',
description: `
The source database (Schoenberg, Bibale, and Bodleian) that provided
the information about the event.
`
}
}
},
clientFSPlaces: { clientFSPlaces: {
label: 'ClientFS', label: 'ClientFS',
shortDescription: 'Client-side faceted search', shortDescription: 'Client-side faceted search',
......
...@@ -3,6 +3,7 @@ import { perspective2Config } from './perspective_configs/Perspective2Config' ...@@ -3,6 +3,7 @@ import { perspective2Config } from './perspective_configs/Perspective2Config'
import { perspective3Config } from './perspective_configs/Perspective3Config' import { perspective3Config } from './perspective_configs/Perspective3Config'
import { findsConfig } from './perspective_configs/FindsConfig' import { findsConfig } from './perspective_configs/FindsConfig'
import { actorsConfig } from './perspective_configs/EmloActorsConfig' import { actorsConfig } from './perspective_configs/EmloActorsConfig'
import { hellerauConfig } from './perspective_configs/HellerauConfig'
import { import {
productionPlacesQuery, productionPlacesQuery,
lastKnownLocationsQuery, lastKnownLocationsQuery,
...@@ -48,6 +49,7 @@ import { ...@@ -48,6 +49,7 @@ import {
emloPlacePropertiesInfoWindow, emloPlacePropertiesInfoWindow,
emloPeopleRelatedTo emloPeopleRelatedTo
} from './sparql_queries/SparqlQueriesEmloPlaces' } from './sparql_queries/SparqlQueriesEmloPlaces'
import { hellerauMigrationsQuery } from './sparql_queries/SparqlQueriesHellerau'
import { federatedSearchDatasets } from './sparql_queries/SparqlQueriesFederatedSearch' import { federatedSearchDatasets } from './sparql_queries/SparqlQueriesFederatedSearch'
import { fullTextSearchProperties } from './sparql_queries/SparqlQueriesFullText' import { fullTextSearchProperties } from './sparql_queries/SparqlQueriesFullText'
import { makeObjectList } from '../SparqlObjectMapper' import { makeObjectList } from '../SparqlObjectMapper'
...@@ -63,6 +65,7 @@ export const backendSearchConfig = { ...@@ -63,6 +65,7 @@ export const backendSearchConfig = {
perspective3: perspective3Config, perspective3: perspective3Config,
finds: findsConfig, finds: findsConfig,
emloActors: actorsConfig, emloActors: actorsConfig,
hellerau: hellerauConfig,
manuscripts: { manuscripts: {
perspectiveID: 'perspective1', // get rest of the config from 'perspective1' perspectiveID: 'perspective1', // get rest of the config from 'perspective1'
instance: { instance: {
...@@ -78,7 +81,7 @@ export const backendSearchConfig = { ...@@ -78,7 +81,7 @@ export const backendSearchConfig = {
} }
}, },
events: { events: {
perspectiveID: 'perspective1', perspectiveID: 'perspective1',
instance: { instance: {
properties: eventProperties, properties: eventProperties,
relatedInstances: '' relatedInstances: ''
...@@ -213,6 +216,12 @@ export const backendSearchConfig = { ...@@ -213,6 +216,12 @@ export const backendSearchConfig = {
// filterTarget: 'id', // filterTarget: 'id',
resultMapper: mapMultipleLineChart resultMapper: mapMultipleLineChart
}, },
hellerauMigrations: {
perspectiveID: 'hellerau',
q: hellerauMigrationsQuery,
filterTarget: 'person__id',
resultMapper: makeObjectList
},
perspective1KnowledgeGraphMetadata: { perspective1KnowledgeGraphMetadata: {
perspectiveID: 'perspective1', perspectiveID: 'perspective1',
q: knowledgeGraphMetadataQuery, q: knowledgeGraphMetadataQuery,
......
import {
personPropertiesFacetResults,
findPropertiesInstancePage
} from '../sparql_queries/SparqlQueriesHellerau'
import { prefixes } from '../sparql_queries/SparqlQueriesPrefixes'
export const hellerauConfig = {
endpoint: {
// url: 'https://ldf.fi/sualt-fha-finds/sparql',
url: 'http://localhost:3037/ds/sparql',
prefixes,
useAuth: false
},
facetClass: 'foaf:person',
paginatedResults: {
properties: personPropertiesFacetResults
},
instance: {
properties: findPropertiesInstancePage,
relatedInstances: ''
},
facets: {
prefLabel: {
id: 'prefLabel',
labelPath: 'skos:prefLabel',
textQueryPredicate: '', // empty for querying the facetClass
textQueryProperty: '',
type: 'text'
}
}
}
const perspectiveID = 'hellerau'
export const personPropertiesFacetResults =
` {
?id skos:prefLabel ?prefLabel__id .
BIND (?prefLabel__id as ?prefLabel__prefLabel)
BIND(CONCAT("/${perspectiveID}/page/", REPLACE(STR(?id), "^.*\\\\/(.+)", "$1")) AS ?prefLabel__dataProviderUrl)
}
`
// # https://github.com/uber/deck.gl/blob/master/docs/layers/arc-layer.md
export const hellerauMigrationsQuery = `
SELECT DISTINCT ?id ?person__id ?person__prefLabel ?person__dataProviderUrl
?from__id ?from__prefLabel ?from__lat ?from__long
?to__id ?to__prefLabel ?to__lat ?to__long
WHERE {
<FILTER>
# Koulun nimi ennen muuttoa 1925: Schule Hellerau für Rhythmus, Musik und Körperbildung.
# Sijainti: Hellerau-Dresden: https://www.geonames.org/2906837/hellerau.html
BIND(<https://sws.geonames.org/2906837/> as ?from__id)
?person__id h-schema:home_1930|h-schema:home_1937 ?to__id ;
skos:prefLabel ?person__prefLabel .
BIND(CONCAT("/${perspectiveID}/page/", REPLACE(STR(?person__id), "^.*\\\\/(.+)", "$1")) AS ?person__dataProviderUrl)
?from__id gn:name ?from__prefLabel ;
wgs84:lat ?from__lat ;
wgs84:long ?from__long .
?to__id gn:name ?to__prefLabel ;
wgs84:lat ?to__lat ;
wgs84:long ?to__long .
BIND(IRI(CONCAT(STR(?from__id), "-", REPLACE(STR(?to__id), "https://sws.geonames.org", "--->"))) as ?id)
}
`
...@@ -16,5 +16,8 @@ export const prefixes = ` ...@@ -16,5 +16,8 @@ export const prefixes = `
PREFIX wgs84: <http://www.w3.org/2003/01/geo/wgs84_pos#> PREFIX wgs84: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX spatial: <http://jena.apache.org/spatial#> PREFIX spatial: <http://jena.apache.org/spatial#>
PREFIX text: <http://jena.apache.org/text#> PREFIX text: <http://jena.apache.org/text#>
PREFIX sd: <http://www.w3.org/ns/sparql-service-description#> PREFIX sd: <http://www.w3.org/ns/sparql-service-description#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX h-schema: <http://ldf.fi/schema/hellerau/>
PREFIX gn: <http://www.geonames.org/ontology#>
` `
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment