diff --git a/src/components/MapClient.d.ts b/src/components/MapClient.d.ts
index 45b76fc..32e90aa 100644
--- a/src/components/MapClient.d.ts
+++ b/src/components/MapClient.d.ts
@@ -19,3 +19,13 @@ export enum ShapeTypes {
}
export type DrawingModes = 'MARKER' | 'RECTANGLE' | 'POLYGON'
+
+/** well known text simplified result object, as returned by mapSearch */
+export type WKTResult = {
+ uri: string
+ link: string
+ wkt: string
+ fcLabel: string
+ label: string
+ id?: string
+}
diff --git a/src/components/MapClient.vue b/src/components/MapClient.vue
index 7f28a36..a6ae9be 100644
--- a/src/components/MapClient.vue
+++ b/src/components/MapClient.vue
@@ -6,7 +6,7 @@ import { wktToGeoJSON } from "@terraformer/wkt"
import { mapConfigKey, type MapConfig } from "@/types";
import { convertConfigTypes } from '@/util/mapSearchHelper'
import type { MapOptionsCenter } from '@/types'
-import type { WKTResult } from '@/stores/mapSearchStore.d';
+import type { WKTResult } from "@/components/MapClient.d";
import { ShapeTypes, type DrawingModes } from "@/components/MapClient.d";
diff --git a/src/components/search/CatPrezSearchMap.vue b/src/components/search/CatPrezSearchMap.vue
index 60f1b23..e162714 100644
--- a/src/components/search/CatPrezSearchMap.vue
+++ b/src/components/search/CatPrezSearchMap.vue
@@ -172,7 +172,6 @@ async function getThemes() {
* Performs search via a SPARQL query
*/
async function doSearch() {
- console.log("performing search...")
const searchData = await searchSparqlGetRequest(`${apiBaseUrl}/sparql`, query.value);
if (searchData && !searchError.value) {
results.value = (searchData.results.bindings as SparqlBinding[]).map(result => {
@@ -317,7 +316,6 @@ onMounted(async () => {
diff --git a/src/components/search/SpacePrezSearchMap.vue b/src/components/search/SpacePrezSearchMap.vue
index 5cdc674..018e7ac 100644
--- a/src/components/search/SpacePrezSearchMap.vue
+++ b/src/components/search/SpacePrezSearchMap.vue
@@ -256,6 +256,9 @@ async function doSearch() {
label: result.f_label ? result.f_label.value : ""
}
});
+ if (searchMap.value) {
+ searchMap.value.drawShape(results.value);
+ }
}
}
}
diff --git a/src/stores/catalogQueries.d.ts b/src/stores/catalogQueries.d.ts
deleted file mode 100644
index 364c43c..0000000
--- a/src/stores/catalogQueries.d.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export type RDCatalog = {
- c: string;
- t: string;
-}
-
-export type RDTheme = {
- count: string;
- pl: string;
- th: string;
-}
-
-export type RDSearch = {
- r: string;
- t: string;
- d: string;
- thlist: string;
- thpllist: string;
- weight: string;
-}
-
diff --git a/src/stores/catalogQueries.ts b/src/stores/catalogQueries.ts
deleted file mode 100644
index 34be86f..0000000
--- a/src/stores/catalogQueries.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-export const QUERY_GET_CATALOGS = `
-PREFIX dcterms:
-PREFIX dcat:
-
-SELECT ?c ?t
-WHERE {
- GRAPH ?g {
- ?c a dcat:Catalog ;
- dcterms:title ?t .
- }
-}
-ORDER BY ?t`
-
-export function QUERY_GET_THEMES(catalogs:string[]=[]) {
- return `
-PREFIX skos:
-PREFIX dcterms:
-PREFIX dcat:
-SELECT ?th ?pl (COUNT(?th) AS ?count)
-WHERE {
- ?r a dcat:Resource ;
- ^dcterms:hasPart ?hasPart .
- ${catalogs.length > 0 ? `FILTER (?hasPart IN (${catalogs.map(cat=>`<${cat}>`).join(', ')}))` : ``}
- ?r dcat:theme ?th .
- ?th skos:prefLabel ?pl .
-}
-GROUP BY ?th ?pl
-ORDER BY DESC(?count) ?pl
-LIMIT 10`
-}
-
-export function QUERY_SEARCH(catalogs:string[]=[], searchTerms:string='', themes:string[]=[], shape:string='', limit:number=0) {
- return `
- PREFIX skos:
- PREFIX dcat:
- PREFIX dcterms:
- PREFIX geo:
- PREFIX geof:
-
- SELECT ?r ?t ?d (GROUP_CONCAT(?th;separator="\t") AS ?thlist) (GROUP_CONCAT(?thpl;separator="\t") AS ?thpllist) ?weight
- WHERE {
- # Only look for Resources (not spatial Datasets)
- ?r a dcat:Resource .
-
- # Only look in selected cats
- ?r ^dcterms:hasPart ?hasPart .
- ${catalogs.length > 0 ? `FILTER (?hasPart IN (${catalogs.map(cat=>`<${cat}>`).join(', ')}))` : ``}
-
- # Weighted text search
- {
- SELECT DISTINCT ?r ?t ?d (SUM(?w) AS ?weight)
- WHERE {
- ?r a dcat:Resource .
- {
- ?r
- dcterms:title ?t ;
- dcterms:description ?d ;
- .
- BIND (50 AS ?w)
- FILTER REGEX(?t, "^${searchTerms}$", "i")
- }
- UNION
- {
- ?r
- dcterms:title ?t ;
- dcterms:description ?d ;
- .
- BIND (10 AS ?w)
- FILTER REGEX(?t, "${searchTerms}", "i")
- FILTER(?d!="")
- }
- UNION
- {
- ?r
- dcterms:title ?t ;
- dcterms:description ?d ;
- .
- BIND (5 AS ?w)
- FILTER REGEX(?d, "${searchTerms}", "i")
- }
- }
- GROUP BY ?r ?t ?d ?match
- ORDER BY DESC(?weight) ?t
- }
-
- # Theme filter. each theme's IRI is a new line in the VALUES {}
- ${themes.length > 0 ? `VALUES ?th { ${themes.map(theme=>`<${theme}>`).join(' ')} }` : ``}
- ?r dcat:theme ?th .
- ?th skos:prefLabel ?thpl .
-
- # Spatial Filter
- ${shape != '' ? `
- ?r geo:hasBoundingBox/geo:asWKT ?wkt ;
- FILTER (geof:sfOverlaps("${shape})"^^geo:wktLiteral, ?wkt))` : ``}
-
- } GROUP BY ?r ?t ?d ?weight
- ${limit > 0 ? `LIMIT ${limit}` : ``}`
-
-}
diff --git a/src/stores/datasetsStore.d.ts b/src/stores/datasetsStore.d.ts
deleted file mode 100644
index 26642cb..0000000
--- a/src/stores/datasetsStore.d.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Term } from "n3"
-
-/**
- * @typedef {Object} MatchFilter - A match object type to provide to the N3 match function to filter results
- * @property {Term | null} subject - The subject term to match
- * @property {Term | null} object - The object term to match
- * @property {Term | null} predicate - The predicate term to match
- */
-export type MatchFilter = {
- subject?: Term | null,
- object?: Term | null,
- predicate?: Term | null
-}
-
-/**
- * @typedef {Object} SimpleQueryResult - This simple query result object is to enable a view to easily work with a result set to display, without needing to worry about getting an id/value or processing of the literal text properly
- * @property {string} subject - The subject of the triple/quad
- * @property {string} predicate - The predicate of the triple/quad
- * @property {string} object - The object of the triple/quad, with the literal value processed if applicable
- */
-export type SimpleQueryResult = {
- subject: string,
- predicate: string,
- object: string
-}
-
-/**
- * @typedef {Object} DatasetTreeNode - The node containing the item and featureCollection list
- * @property {SimpleQueryResult} item - The item being represented in the tree node
- * @property {SimpleQueryResult[]} featureCollections - The child featureCollections for the given item
- */
-export type DatasetTreeNode = {
- item: SimpleQueryResult,
- featureCollections: SimpleQueryResult[]
-}
-
-/**
- * @typedef {DatasetTreeNode[]} DatasetTree - This tree object provides a way to store the main list of datasets and child featureCollections
- */
-export type DatasetTree = DatasetTreeNode[]
-
diff --git a/src/stores/datasetsStore.ts b/src/stores/datasetsStore.ts
deleted file mode 100644
index d199fdf..0000000
--- a/src/stores/datasetsStore.ts
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * This is a pinia store module that makes a sparql API query to get datasets and feature collection information.
- * It uses the N3.js library for parsing and querying RDF data, and axios for HTTP requests.
- * This store provides a method to get a full tree representation of the datasets and their child feature collections,
- * and a method to get a list of datasets with their titles.
- */
-import { defineStore } from 'pinia'
-import axios from 'axios'
-import { Util, Store, Parser, DataFactory, Quad } from "n3";
-const { namedNode } = DataFactory;
-import type { DatasetTree, MatchFilter, SimpleQueryResult } from '@/stores/datasetsStore.d'
-import { mapConfigKey, type MapConfig, type MapSearchConfig } from "@/types";
-import { apiBaseUrlConfigKey } from "@/types";
-import { inject } from 'vue';
-import { convertConfigTypes } from '@/util/mapSearchHelper';
-
-/**
- * SPARQL query to return all datasets and feature collections required
- */
-const getDatasetFeatureQuery = (config: MapSearchConfig) => {
- return `PREFIX geo:
-PREFIX rdf:
-PREFIX prez:
-
-CONSTRUCT {?ds a <${config.spatial.datasetClass}> ;
- <${config.props.dsLabel}> ?ds_title ;
- <${config.spatial.membershipRelationship}> ?fc .
- ?fc a geo:FeatureCollection ;
- <${config.props.fcLabel}> ?fc_title}
-WHERE { ?ds a <${config.spatial.datasetClass}> ;
- <${config.spatial.membershipRelationship}> ?fc ;
- <${config.props.dsLabel}> ?ds_title .
- ?fc <${config.props.fcLabel}> ?fc_title
- }`
-}
-
-/**
- * Converts a quad/triple object from N3 into a simple result type for easier template processing
- * @param {Object} quad - The quad/triple object from N3 to convert
- * @returns {SimpleQueryResult} - The simple query result object
- */
-export const quadToSimpleQueryResult = (quad:any):SimpleQueryResult => {
- // Note: Quad type import issues, conflict with RDF library, so has an any type for now...
- return {
- subject: quad.subject.id,
- predicate: quad.predicate.id,
- object: Util.isLiteral(quad.object) ? quad.object.value : quad.object.id
- }
-}
-
-/**
- * Main search store for processing the results of a search SPARQL query
- */
-export const datasetsStore = defineStore({
- id: 'datasetsStore',
-
- /**
- * The initial store state
- * @returns {Object}
- */
- state: () => {
- // get the default map settings
- const mapConfig = convertConfigTypes(inject(mapConfigKey)) as MapConfig;
- const apiBaseUrl = inject(apiBaseUrlConfigKey) as string;
- //const config = inject(configKey, defaultConfig)
- return {
- data: [],
- success: false,
- store: new Store(),
- loading: false,
- error: null,
- apiBaseUrl,
- mapConfig
- }
- },
-
- /**
- * Callable actions
- */
- actions: {
-
- /**
- * Get a list of triple/quads matching the provided filter, simplified for easier template processing
- * @param {MatchFilter} filter - The filter to match the triples/quads
- * @returns {SimpleQueryResult[]} - The list of matching triples/quads
- */
- getMatchedData(filter:MatchFilter) {
- const data:SimpleQueryResult[] = []
-
- const { subject=null, predicate=null, object=null } = filter
- for (const item of this.store.match(subject, predicate, object)) {
- data.push(quadToSimpleQueryResult(item))// {subject: item.subject.id, predicate: item.predicate.id, object: Util.isLiteral(item.object) ? item.object.value : item.object.id})
- }
- return data
- },
-
- /**
- * Get a full tree representation of the datasets and child feature collections
- * @returns {DatasetTree} - The tree representation of the datasets and child feature collections
- */
- getDatasetTree() {
- const datasetTree:DatasetTree = [
- ]
- this.getDatasets().forEach(dataset=>{
- datasetTree.push({
- item: dataset,
- featureCollections: this.getFeatureCollections([dataset.subject])
- })
- })
- return datasetTree;
-
- },
-
-
- /**
- * Get a list of dataset, performs a second match on the dataset subject to get the title
- * @returns SimpleQueryResult array
- */
- getDatasets() {
- let results: SimpleQueryResult[] = []
- const matched = this.getMatchedData({object: namedNode(this.mapConfig.search.spatial.datasetClass)})
- matched.forEach(itemLink=>{
- for(const item of this.store.match(namedNode(itemLink.subject), namedNode(this.mapConfig.search.props.dsLabel))) {
- results.push(quadToSimpleQueryResult(item))
- }
- })
- return results
- },
-
-
- /**
- * Returns a list of SimpleQueryResult objects representing all feature collections for a given list of dataset subjects.
- * If no datasetSubjects are provided, all matching feature collections will be returned.
- * @param datasetSubjects - List of dataset subjects to filter feature collections by.
- * @returns List of SimpleQueryResult objects representing the feature collections.
- */
- getFeatureCollections(datasetSubjects:string[]):SimpleQueryResult[] {
- if(datasetSubjects.length == 0) {
- return [] // changed to return empty
- // simply returns all matching feature collections
- // return this.getMatchedData({predicate: namedNode('http://purl.org/dc/terms/title')})
- } else {
- // narrow down to a specific dataset
- let results:SimpleQueryResult[] = []
- datasetSubjects.forEach(subject=>{
- const matchedFCs = this.getMatchedData({predicate: namedNode(this.mapConfig.search.spatial.membershipRelationship), subject: namedNode(subject)})
- matchedFCs.forEach(itemLink=>{
- for(const item of this.store.match(namedNode(itemLink.object), namedNode(this.mapConfig.search.props.fcLabel))) {
- results.push(quadToSimpleQueryResult(item))
- }
- })
- })
- return results
- }
- },
-
- /**
- * Calls the spacePrez search endpoint using the query for spacePrez
- */
- async fetchSpacePrezData() {
- return await this.fetchData(`${this.apiBaseUrl}/sparql`, getDatasetFeatureQuery(this.mapConfig.search));
- },
-
- /**
- * Makes a GET request to the specified API endpoint with the provided SPARQL query.
- * Parses the response with the N3 parser and creates a new N3 store from the parsed data.
- * @param apiUrl - The URL of the SPARQL endpoint.
- * @param query - The SPARQL query to execute.
- */
- async fetchData(apiUrl:string, query:string) {
- try {
- // initialise the state
- const parser = new Parser();
- this.loading = true
- this.success = false
-
- // make the API call to the SPARQL endpoint
- const response = await axios.get(apiUrl, { params: { query }})
-
- // process the response through the N3 parser
- this.data = parser.parse(response.data)
-
- // create a new N3 store from the parsed data
- this.store = new Store(this.data)
-
- // successfully processed
- this.success = true
- this.error = null
-
- } catch (error:any) {
-
- // set the error status
- this.error = error.message
- this.success = false
-
- } finally {
- // always set loading to complete
- this.loading = false
- }
- }
- }
-})
diff --git a/src/stores/mapSearchStore.d.ts b/src/stores/mapSearchStore.d.ts
deleted file mode 100644
index 6cc68dc..0000000
--- a/src/stores/mapSearchStore.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-/** well known text simplified result object, as returned by mapSearch */
-export type WKTResult = {
- uri: string
- link: string
- wkt: string
- fcLabel: string
- label: string
- id?: string
-}
diff --git a/src/stores/mapSearchStore.ts b/src/stores/mapSearchStore.ts
deleted file mode 100644
index a5a163c..0000000
--- a/src/stores/mapSearchStore.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * This is a pinia store module that provides search functionality for a triple store. It uses the N3.js library for parsing and querying RDF data, and axios for HTTP requests.
- * The searchStore provides a method to get a full tree representation of the datasets and their child feature collections, and a method to get a list of datasets with their titles.
- */
-import { defineStore } from 'pinia'
-import axios from 'axios'
-import { inject } from 'vue';
-import type { WKTResult } from '@/stores/mapSearchStore.d'
-
-import { apiBaseUrlConfigKey } from "@/types";
-
-const linkPrefix = '/object?uri='
-
-/**
- * Main search store for processing the results of a search SPARQL query
- */
-export const mapSearchStore = defineStore({
- id: 'mapSearchStore',
-
- /**
- * The initial store state
- * @returns {Object}
- */
- state: () => {
- const apiBaseUrl = inject(apiBaseUrlConfigKey) as string;
-
- // const config = inject(configKey, defaultConfig)
- return {
- data: [],
- success: false,
- loading: false,
- error: null as null | string,
- apiBaseUrl: apiBaseUrl
- }
- },
-
- /**
- * Callable actions
- */
- actions: {
-
- /**
- * Calls the spacePrez search endpoint using a passed in generated query, sets the result WKT in the data object
- */
- async searchMap(query:string) {
- // make the API call to the SPARQL endpoint
- const url = `${this.apiBaseUrl}/sparql`
- this.loading = true
- this.success = false
-
- try {
- const response = await axios.get(url, { headers: {"accept": "application/sparql-results+json"}, params: { query }})
- this.data = response.data.results.bindings.filter((item:any)=>item.fc_label?.value).map((item:any)=>{
- return {
- uri: item.f_uri.value,
- link: `${linkPrefix}${item.f_uri.value}`,
- wkt: item.wkt.value,
- fcLabel: item.fc_label?.value,
- label: item.f_label.value
- }
- })
- // successfully processed
- this.success = true
- this.error = null
-
- } catch (error:any) {
- // set the error status
- this.error = error.message as string
- this.data = []
- this.success = false
-
- } finally {
- // always set loading to complete
- this.loading = false
- }
-
- }
-
- }
-})
diff --git a/src/stores/refDataStore.ts b/src/stores/refDataStore.ts
deleted file mode 100644
index f37b862..0000000
--- a/src/stores/refDataStore.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * This is a pinia store module that provides search functionality for a triple store. It uses the N3.js library for parsing and querying RDF data, and axios for HTTP requests.
- * The searchStore provides a method to get a full tree representation of the datasets and their child feature collections, and a method to get a list of datasets with their titles.
- */
-import { defineStore } from 'pinia'
-import axios from 'axios'
-import { inject } from 'vue';
-import { apiBaseUrlConfigKey } from "@/types";
-
-
-/**
- * Factory store function
- */
-export function refDataStore(id:string) {
-
- return defineStore(
- {
- id,
-
- /**
- * The initial store state
- * @returns {Object}
- */
- state: () => {
- const apiBaseUrl = inject(apiBaseUrlConfigKey) as string;
-
- // const config = inject(configKey, defaultConfig)
- return {
- data: [] as Array