Skip to content

Commit

Permalink
MGEO_SB-972 : POC search geocat metadata in search bar
Browse files Browse the repository at this point in the history
  • Loading branch information
pakb committed Dec 2, 2024
1 parent a9eb9a0 commit 74a1693
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 0 deletions.
183 changes: 183 additions & 0 deletions src/api/geocat.api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import axios from 'axios'

import ExternalWMSLayer from '@/api/layers/ExternalWMSLayer.class'
import { SearchResultTypes } from '@/api/search.api'
import { LV95, WGS84 } from '@/utils/coordinates/coordinateSystems'
import { projExtent } from '@/utils/extentUtils'

const SOURCES_FOR_ELASTIC_REQUESTS = [
'uuid',
'id',
'title',
'resource*',
'resourceTitleObject',
'resourceAbstractObject',
'overview',
'logo',
'codelist_status_text',
'linkProtocol',
'linkUrl',
'contactForResource*.organisation*',
'contact*.organisation*',
'contact*.email',
'userSavedCount',
'cl_topic',
'cl_maintenanceAndUpdateFrequency',
'tag',
'MD_LegalConstraintsUseLimitationObject',
'qualityScore',
'geom',
]

function generateGeographicQuery(extent) {
const extentInWGS84 = projExtent(LV95, WGS84, extent)
const extentPolygon = [
[extentInWGS84[0], extentInWGS84[1]],
[extentInWGS84[0], extentInWGS84[3]],
[extentInWGS84[2], extentInWGS84[3]],
[extentInWGS84[2], extentInWGS84[1]],
[extentInWGS84[0], extentInWGS84[1]],
]
return {
aggregations: {},
from: 0,
size: 10,
sort: [
{
_score: 'desc',
},
],
query: {
bool: {
must: [],
should: [
{
geo_shape: {
geom: {
shape: {
type: 'Polygon',
coordinates: [extentPolygon],
},
relation: 'within',
},
boost: 10,
},
},
],
filter: [
{
terms: {
isTemplate: ['n'],
},
},
{
geo_shape: {
geom: {
shape: {
type: 'Polygon',
coordinates: [extentPolygon],
},
relation: 'intersects',
},
},
},
],
},
},
track_total_hits: true,
_source: SOURCES_FOR_ELASTIC_REQUESTS,
}
}

function generatePureTextSearchQuery(searchQuery) {
return {
query: {
bool: {
must: [
{
terms: {
isTemplate: ['n'],
},
},
{
multi_match: {
query: searchQuery,
type: 'bool_prefix',
fields: [
'resourceTitleObject.langeng^14',
'resourceTitleObject.*^4',
'resourceAbstractObject.langeng^13',
'resourceAbstractObject.*^3',
'tag^2',
'resourceIdentifier',
],
},
},
],
},
},
_source: SOURCES_FOR_ELASTIC_REQUESTS,
from: 0,
size: 20,
}
}

/**
* @param searchQuery
* @returns Promise<GeocatSearchResult[]>
*/
export async function searchOnGeocat(searchQuery, extent) {
const geocatResults = await axios({
method: 'POST',
url: 'https://www.geocat.ch/geonetwork/srv/api/search/records/_search?bucket=bucket',
data: extent ? generateGeographicQuery(extent) : generatePureTextSearchQuery(searchQuery),
})
if (geocatResults?.data?.hits?.hits?.length > 0) {
const wmsHits = geocatResults.data.hits.hits.filter((hit) =>
// hit._score > 100 &&
hit._source.linkProtocol?.some((protocol) => ['OGC:WMS'].includes(protocol))
)
const result = wmsHits.map((hit) => {
console.log('geocat WMS hit', hit)
const source = hit._source
const indexOfWmsLink = source.linkProtocol.indexOf('OGC:WMS')
let wmsUrl = source.linkUrl[indexOfWmsLink]
wmsUrl = wmsUrl.substring(0, wmsUrl.indexOf('?') + 1)
let layerId
if (source.resourceIdentifier) {
layerId = source.resourceIdentifier[0].code
} else {
layerId = source.resourceAbstractObject.default
}
let extent = null
if (source.geom && source.geom.coordinates) {
const elasticExtent = source.geom.coordinates[0]
extent = [
elasticExtent[0][0],
elasticExtent[0][1],
elasticExtent[2][0],
elasticExtent[2][1],
]
console.log('geocat extent found', extent)
}
return {
resultType: SearchResultTypes.GEOCAT,
id: source.id,
title: source.resourceTitleObject.default,
sanitizedTitle: source.resourceTitleObject.default,
layer: new ExternalWMSLayer({
id: layerId,
name: source.resourceTitleObject.default,
baseUrl: wmsUrl,
isLoading: false,
// extent: extent,
}),
}
})
console.log('geocat wms results', result)
return result
} else {
console.log('geocat pas de chance', geocatResults)
}
return []
}
7 changes: 7 additions & 0 deletions src/api/search.api.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const SearchResultTypes = {
LAYER: 'LAYER',
LOCATION: 'LOCATION',
FEATURE: 'FEATURE',
GEOCAT: 'GEOCAT',
}

// comes from https://stackoverflow.com/questions/5002111/how-to-strip-html-tags-from-string-in-javascript
Expand Down Expand Up @@ -99,6 +100,12 @@ export function sanitizeTitle(title = '') {
* @param {GeoAdminLayer} layer The layer of this feature.
*/

/**
* @extends SearchResult
* @typedef {Object} GeocatSearchResult
* @param {AbstractLayer} layer
*/

/**
* @param {String} query
* @param {String} lang
Expand Down
12 changes: 12 additions & 0 deletions src/modules/menu/components/search/SearchResultList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ const layerResults = computed(() =>
const layerFeatureResults = computed(() =>
results.value.filter((result) => result.resultType === SearchResultTypes.FEATURE)
)
const geocatResults = computed(() =>
results.value.filter((result) => result.resultType === SearchResultTypes.GEOCAT)
)
const categories = computed(() => {
return [
Expand All @@ -49,6 +52,10 @@ const categories = computed(() => {
id: 'featuresearch',
results: layerFeatureResults.value,
},
{
id: 'metadata',
results: geocatResults.value,
},
]
})
Expand Down Expand Up @@ -112,6 +119,11 @@ const setPreviewDebounced = debounce((entry) => {
if (previewedPinnedLocation.value) {
store.dispatch('setPreviewedPinnedLocation', { coordinates: null, ...dispatcher })
}
} else if (entry.resultType === SearchResultTypes.GEOCAT) {
store.dispatch('setPreviewLayer', {
layer: entry.layer,
...dispatcher,
})
} else if (entry.coordinate) {
store.dispatch('setPreviewedPinnedLocation', {
coordinates: entry.coordinate,
Expand Down
10 changes: 10 additions & 0 deletions src/modules/menu/components/search/SearchResultListEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useStore } from 'vuex'
import { SearchResultTypes } from '@/api/search.api'
import LayerDescriptionPopup from '@/modules/menu/components/LayerDescriptionPopup.vue'
import TextSearchMarker from '@/utils/components/TextSearchMarker.vue'
import ZoomToExtentButton from '@/utils/components/ZoomToExtentButton.vue'
const dispatcher = { dispatcher: 'SearchResultListEntry.vue' }
Expand All @@ -32,6 +33,14 @@ const emits = defineEmits([
const { index, entry } = toRefs(props)
const resultType = computed(() => entry.value.resultType)
const extent = computed(() => {
const entryExtent = entry.value.extent
if (Array.isArray(entryExtent) && entryExtent.length === 4) {
console.log('geocat extent', entryExtent)
return entryExtent
}
return null
})
const showLayerDescription = ref(false)
const item = ref(null)
Expand Down Expand Up @@ -121,6 +130,7 @@ defineExpose({
<FontAwesomeIcon size="lg" :icon="['fas', 'info-circle']" />
</button>
</div>
<ZoomToExtentButton v-if="extent" :extent="extent" />
<LayerDescriptionPopup
v-if="showLayerDescription"
:layer-id="entry.layerId"
Expand Down
21 changes: 21 additions & 0 deletions src/store/modules/search.store.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import GeoJSON from 'ol/format/GeoJSON'

import getFeature from '@/api/features/features.api'
import LayerFeature from '@/api/features/LayerFeature.class'
import { searchOnGeocat } from '@/api/geocat.api'
import LayerTypes from '@/api/layers/LayerTypes.enum'
import reframe from '@/api/lv03Reframe.api'
import search, { SearchResultTypes } from '@/api/search.api'
Expand Down Expand Up @@ -171,6 +172,18 @@ const actions = {
layersToSearch: getters.visibleLayers,
limit: state.autoSelect ? 1 : null,
})
const firstLocationMatch = results.find(
(result) => result.resultType === SearchResultTypes.LOCATION
)
const geocatResults = await searchOnGeocat(
query,
firstLocationMatch?.extent
? flattenExtent(firstLocationMatch?.extent)
: null
)
if (geocatResults?.length > 0) {
results.push(...geocatResults)
}
if (
(originUrlParam && results.length === 1) ||
(originUrlParam && state.autoSelect && results.length >= 1)
Expand Down Expand Up @@ -279,6 +292,14 @@ const actions = {
}

break

case SearchResultTypes.GEOCAT:
console.log('geocat entry selected', entry)
dispatch('addLayer', {
layer: entry.layer,
dispatcher,
})
break
}
if (state.autoSelect) {
dispatch('setAutoSelect', {
Expand Down

0 comments on commit 74a1693

Please sign in to comment.