feat(geocoding): remove server side fetch
This commit is contained in:
@@ -3,6 +3,7 @@ import type { Category, CreateReportRequest } from '~/types/api'
|
||||
import type { LeafletMouseEvent, Map as LeafletMap, Marker as LeafletMarker } from 'leaflet'
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import { BARI_BOUNDS, BARI_CENTER, isWithinBariBounds } from '~/utils/bari'
|
||||
import { reverseGeocode, searchAddresses } from '~/utils/geocoding'
|
||||
|
||||
interface Props {
|
||||
isLoading?: boolean
|
||||
@@ -19,14 +20,6 @@ interface GeocodingSuggestion {
|
||||
longitude: number
|
||||
}
|
||||
|
||||
interface SearchAddressesResponse {
|
||||
suggestions: GeocodingSuggestion[]
|
||||
}
|
||||
|
||||
interface ReverseGeocodeResponse {
|
||||
address: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
isLoading: false,
|
||||
categories: () => []
|
||||
@@ -123,18 +116,20 @@ const fetchAddressSuggestions = async (query: string) => {
|
||||
addressSearchError.value = ''
|
||||
|
||||
try {
|
||||
const response = await $fetch<SearchAddressesResponse>('/api/geocoding/search', {
|
||||
query: { q: query }
|
||||
})
|
||||
if (requestId !== addressSearchRequestId) {
|
||||
return
|
||||
}
|
||||
|
||||
const suggestions = await searchAddresses(query)
|
||||
|
||||
if (requestId !== addressSearchRequestId) {
|
||||
return
|
||||
}
|
||||
|
||||
addressSuggestions.value = response.suggestions
|
||||
showAddressSuggestions.value = response.suggestions.length > 0
|
||||
addressSuggestions.value = suggestions
|
||||
showAddressSuggestions.value = suggestions.length > 0
|
||||
|
||||
if (!response.suggestions.length) {
|
||||
if (!suggestions.length) {
|
||||
addressSearchError.value = 'Nessun indirizzo trovato nel Comune di Bari.'
|
||||
}
|
||||
} catch {
|
||||
@@ -157,15 +152,11 @@ const resolveAddressFromCoordinates = async (lat: number, lng: number, fallbackA
|
||||
addressSearchError.value = ''
|
||||
|
||||
try {
|
||||
const response = await $fetch<ReverseGeocodeResponse>('/api/geocoding/reverse', {
|
||||
query: { lat, lng }
|
||||
})
|
||||
|
||||
if (requestId !== reverseGeocodeRequestId) {
|
||||
return
|
||||
}
|
||||
|
||||
const resolvedAddress = response.address?.trim() || fallbackAddress.trim()
|
||||
const resolvedAddress = (await reverseGeocode(lat, lng))?.trim() || fallbackAddress.trim()
|
||||
|
||||
if (resolvedAddress) {
|
||||
setAddressValue(resolvedAddress)
|
||||
@@ -694,4 +685,3 @@ textarea {
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { BARI_BOUNDS, isWithinBariBounds } from '~/utils/bari'
|
||||
|
||||
interface NominatimAddress {
|
||||
road?: string
|
||||
house_number?: string
|
||||
@@ -27,26 +29,8 @@ export interface GeocodingSuggestion {
|
||||
}
|
||||
|
||||
const NOMINATIM_BASE_URL = 'https://nominatim.openstreetmap.org'
|
||||
const BARI_BOUNDS = {
|
||||
north: 41.1696,
|
||||
south: 41.0718,
|
||||
east: 16.9521,
|
||||
west: 16.7564
|
||||
}
|
||||
|
||||
const NOMINATIM_HEADERS = {
|
||||
'User-Agent': 'Visione Frontend/1.0 (https://visione.studentindipendenti.it)',
|
||||
'Referer': 'https://visione.studentindipendenti.it/'
|
||||
}
|
||||
|
||||
const bariViewbox = `${BARI_BOUNDS.west},${BARI_BOUNDS.north},${BARI_BOUNDS.east},${BARI_BOUNDS.south}`
|
||||
|
||||
const isWithinBariBounds = (latitude: number, longitude: number) =>
|
||||
latitude >= BARI_BOUNDS.south &&
|
||||
latitude <= BARI_BOUNDS.north &&
|
||||
longitude >= BARI_BOUNDS.west &&
|
||||
longitude <= BARI_BOUNDS.east
|
||||
|
||||
const compactAddress = (displayName: string, address?: NominatimAddress) => {
|
||||
if (!address) {
|
||||
return displayName
|
||||
@@ -91,9 +75,7 @@ export const searchAddresses = async (query: string, limit = 5) => {
|
||||
limit: String(limit)
|
||||
})
|
||||
|
||||
const results = await $fetch<NominatimResult[]>(`${NOMINATIM_BASE_URL}/search?${params.toString()}`, {
|
||||
headers: NOMINATIM_HEADERS
|
||||
})
|
||||
const results = await $fetch<NominatimResult[]>(`${NOMINATIM_BASE_URL}/search?${params.toString()}`)
|
||||
|
||||
return results
|
||||
.map(toSuggestion)
|
||||
@@ -111,9 +93,7 @@ export const reverseGeocode = async (latitude: number, longitude: number) => {
|
||||
'accept-language': 'it'
|
||||
})
|
||||
|
||||
const result = await $fetch<NominatimResult | null>(`${NOMINATIM_BASE_URL}/reverse?${params.toString()}`, {
|
||||
headers: NOMINATIM_HEADERS
|
||||
})
|
||||
const result = await $fetch<NominatimResult | null>(`${NOMINATIM_BASE_URL}/reverse?${params.toString()}`)
|
||||
|
||||
if (!result) {
|
||||
return ''
|
||||
+1
-23
@@ -8,6 +8,7 @@ export default defineNuxtConfig({
|
||||
'@nuxtjs/sitemap',
|
||||
'@nuxtjs/robots'
|
||||
],
|
||||
ssr: false,
|
||||
|
||||
runtimeConfig: {
|
||||
public: {
|
||||
@@ -35,29 +36,6 @@ export default defineNuxtConfig({
|
||||
]
|
||||
},
|
||||
|
||||
nitro: {
|
||||
devProxy: {
|
||||
'/api/v1': {
|
||||
target: 'https://bk.visione.studentindipendenti.it/api/v1',
|
||||
changeOrigin: true,
|
||||
headers: {
|
||||
host: 'bk.visione.studentindipendenti.it',
|
||||
origin: 'https://visione.studentindipendenti.it',
|
||||
referer: 'https://visione.studentindipendenti.it/'
|
||||
}
|
||||
},
|
||||
'/uploads': {
|
||||
target: 'https://bk.visione.studentindipendenti.it/uploads',
|
||||
changeOrigin: true,
|
||||
headers: {
|
||||
host: 'bk.visione.studentindipendenti.it',
|
||||
origin: 'https://visione.studentindipendenti.it',
|
||||
referer: 'https://visione.studentindipendenti.it/'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
app: {
|
||||
head: {
|
||||
link: [
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { createError, getQuery } from 'h3'
|
||||
import { reverseGeocode } from '../../utils/geocoding'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const query = getQuery(event)
|
||||
const latitude = typeof query.lat === 'string' ? Number.parseFloat(query.lat) : Number.NaN
|
||||
const longitude = typeof query.lng === 'string' ? Number.parseFloat(query.lng) : Number.NaN
|
||||
|
||||
if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Invalid coordinates'
|
||||
})
|
||||
}
|
||||
|
||||
const address = await reverseGeocode(latitude, longitude)
|
||||
|
||||
return { address }
|
||||
})
|
||||
@@ -1,20 +0,0 @@
|
||||
import { createError, getQuery } from 'h3'
|
||||
import { searchAddresses } from '../../utils/geocoding'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const query = getQuery(event)
|
||||
const rawText = typeof query.q === 'string' ? query.q.trim() : ''
|
||||
const rawLimit = typeof query.limit === 'string' ? Number.parseInt(query.limit, 10) : 5
|
||||
const limit = Number.isFinite(rawLimit) ? Math.min(Math.max(rawLimit, 1), 8) : 5
|
||||
|
||||
if (rawText.length < 3) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Query too short'
|
||||
})
|
||||
}
|
||||
|
||||
const suggestions = await searchAddresses(rawText, limit)
|
||||
|
||||
return { suggestions }
|
||||
})
|
||||
Reference in New Issue
Block a user