2023-07-15 15:03:08 +07:00
|
|
|
<template>
|
2023-08-24 23:18:05 +07:00
|
|
|
|
|
|
|
<div id="app">
|
|
|
|
<router-view />
|
|
|
|
<Popup
|
|
|
|
v-if="popupData"
|
|
|
|
:nearestStructureData="popupData"
|
|
|
|
:onClose="closePopup"
|
|
|
|
/>
|
|
|
|
</div>
|
2023-07-29 06:47:47 +07:00
|
|
|
|
2023-09-08 02:19:20 +07:00
|
|
|
<!-- <searchbar/> -->
|
|
|
|
<v-layout style="height: 40px;">
|
|
|
|
<v-app-bar scroll-threshold="0"
|
|
|
|
class="mx-auto px-auto"
|
|
|
|
>
|
2023-09-14 23:57:18 +07:00
|
|
|
|
|
|
|
<div class="flex-grow-1">
|
|
|
|
<v-text-field
|
|
|
|
v-model="searchQuery"
|
|
|
|
@keyup.enter="performSearch"
|
|
|
|
@input="performSearch"
|
2023-09-15 01:36:47 +07:00
|
|
|
@click="toggleSearchBar()"
|
2023-09-14 23:57:18 +07:00
|
|
|
density="compact"
|
|
|
|
variant="solo"
|
|
|
|
prepend-inner-icon="mdi-magnify"
|
|
|
|
single-line
|
|
|
|
hide-details
|
|
|
|
|
|
|
|
></v-text-field>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<v-btn icon @click="showSearchBar = !showSearchBar">
|
2023-09-08 02:19:20 +07:00
|
|
|
<v-icon>mdi-crosshairs-gps</v-icon>
|
|
|
|
</v-btn>
|
2023-09-14 23:57:18 +07:00
|
|
|
|
2023-09-08 02:19:20 +07:00
|
|
|
</v-app-bar>
|
|
|
|
|
|
|
|
</v-layout>
|
|
|
|
|
2023-09-15 01:36:47 +07:00
|
|
|
<!-- <div v-if="searchResults.length > 0" class="search-results">
|
|
|
|
<ul>
|
|
|
|
<li v-for="result in searchResults" :key="result.place_id" @click="moveToLocation(result)">
|
|
|
|
{{ result.display_name }}
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div> -->
|
|
|
|
|
|
|
|
|
|
|
|
<v-list v-if="searchResults.length > 0 && !showSearchBar" class="search-results">
|
|
|
|
<v-list-item
|
|
|
|
v-for="result in searchResults"
|
|
|
|
:key="result.place_id"
|
|
|
|
@click="moveToLocation(result),toggleSearchBar()"
|
|
|
|
>
|
|
|
|
<v-list-item-icon>
|
|
|
|
<v-icon>mdi-map-marker</v-icon>
|
|
|
|
</v-list-item-icon>
|
|
|
|
{{ result.display_name }}
|
|
|
|
</v-list-item>
|
|
|
|
</v-list>
|
|
|
|
|
2023-09-08 02:19:20 +07:00
|
|
|
<!-- <map/> -->
|
2023-07-15 17:52:21 +07:00
|
|
|
<ol-map
|
|
|
|
:loadTilesWhileAnimating="true"
|
|
|
|
:loadTilesWhileInteracting="true"
|
2023-07-29 02:10:58 +07:00
|
|
|
style=
|
2023-08-02 01:51:43 +07:00
|
|
|
"
|
|
|
|
height: 100%;
|
2023-07-29 02:10:58 +07:00
|
|
|
width: 100%;
|
2023-08-02 01:34:46 +07:00
|
|
|
position: fixed;
|
|
|
|
"
|
2023-08-23 22:44:12 +07:00
|
|
|
@click="handleMapClick"
|
2023-07-15 17:52:21 +07:00
|
|
|
>
|
|
|
|
<ol-view
|
|
|
|
ref="view"
|
|
|
|
:center="center"
|
|
|
|
:rotation="rotation"
|
|
|
|
:zoom="zoom"
|
|
|
|
:projection="projection"
|
|
|
|
/>
|
|
|
|
|
|
|
|
<ol-tile-layer>
|
|
|
|
<ol-source-osm />
|
|
|
|
</ol-tile-layer>
|
|
|
|
</ol-map>
|
2023-07-29 06:47:47 +07:00
|
|
|
|
2023-07-15 15:03:08 +07:00
|
|
|
</template>
|
|
|
|
|
2023-07-15 17:52:21 +07:00
|
|
|
|
2023-07-29 02:10:58 +07:00
|
|
|
|
2023-07-15 15:03:08 +07:00
|
|
|
<script setup>
|
2023-07-29 06:47:47 +07:00
|
|
|
|
|
|
|
import searchbar from '@/components/searchbar.vue';
|
2023-08-24 23:18:05 +07:00
|
|
|
import Popup from "@/components/Popup.vue"; // Import the Popup componen
|
2023-07-15 17:52:21 +07:00
|
|
|
import { ref } from "vue";
|
2023-08-23 22:44:12 +07:00
|
|
|
import axios from "axios";
|
2023-07-15 17:52:21 +07:00
|
|
|
|
2023-07-29 02:10:58 +07:00
|
|
|
const center = ref([100.538611, 13.764722]);
|
2023-07-15 17:52:21 +07:00
|
|
|
const projection = ref("EPSG:4326");
|
2023-07-29 02:10:58 +07:00
|
|
|
const zoom = ref(19);
|
2023-07-15 17:52:21 +07:00
|
|
|
const rotation = ref(0);
|
2023-08-23 22:44:12 +07:00
|
|
|
|
2023-08-24 23:18:05 +07:00
|
|
|
const popupData = ref(null);
|
|
|
|
|
2023-09-08 02:19:20 +07:00
|
|
|
//search
|
|
|
|
const searchQuery = ref("");
|
|
|
|
const searchResults = ref([]);
|
2023-09-14 23:57:18 +07:00
|
|
|
const showSearchBar = ref(false);
|
|
|
|
|
2023-09-15 01:36:47 +07:00
|
|
|
const toggleSearchBar = () => {
|
|
|
|
showSearchBar.value = !showSearchBar.value;
|
|
|
|
};
|
2023-09-08 02:19:20 +07:00
|
|
|
|
|
|
|
const moveToLocation = (result) => {
|
|
|
|
const lat = parseFloat(result.lat);
|
|
|
|
const lon = parseFloat(result.lon);
|
|
|
|
center.value = [lon, lat];
|
2023-09-15 01:36:47 +07:00
|
|
|
showSearchBar.value = false;
|
2023-09-08 02:19:20 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
const performSearch = async () => {
|
|
|
|
try {
|
|
|
|
const response = await axios.get(
|
|
|
|
`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(searchQuery.value)}`
|
|
|
|
);
|
|
|
|
|
|
|
|
searchResults.value = response.data.slice(0, 5);
|
|
|
|
} catch (error) {
|
|
|
|
console.error("Error fetching search results:", error);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-08-24 23:18:05 +07:00
|
|
|
//Show API
|
2023-08-23 22:44:12 +07:00
|
|
|
const handleMapClick = async event => {
|
|
|
|
const clickedCoordinate = event.coordinate;
|
|
|
|
|
|
|
|
try {
|
|
|
|
const response = await axios.get(
|
|
|
|
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${clickedCoordinate[1]}&lon=${clickedCoordinate[0]}`
|
|
|
|
);
|
|
|
|
|
|
|
|
const nearestStructureData = response.data;
|
2023-08-24 23:18:05 +07:00
|
|
|
popupData.value = nearestStructureData; // Show popup
|
|
|
|
|
2023-08-23 22:44:12 +07:00
|
|
|
} catch (error) {
|
|
|
|
console.error("Error fetching reverse geocoding data:", error);
|
|
|
|
}
|
|
|
|
};
|
2023-08-24 23:18:05 +07:00
|
|
|
|
|
|
|
const closePopup = () => {
|
|
|
|
popupData.value = null; // Hide popup
|
|
|
|
};
|
|
|
|
|
2023-08-02 01:34:46 +07:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
.ol-zoom{
|
|
|
|
top: 40px;
|
|
|
|
}
|
2023-08-02 01:51:43 +07:00
|
|
|
.ol-attribution ul{
|
|
|
|
padding:1px .5em;
|
|
|
|
margin-bottom: 8em;
|
|
|
|
}
|
2023-09-08 02:19:20 +07:00
|
|
|
.search-results {
|
|
|
|
position: absolute;
|
|
|
|
width: 100%;
|
|
|
|
max-height: 200px;
|
|
|
|
height: 300px;
|
|
|
|
overflow-y: auto;
|
|
|
|
background-color: #fff;
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
|
|
|
|
z-index: 100;
|
|
|
|
top: 4em;
|
|
|
|
}
|
|
|
|
|
|
|
|
.search-results ul {
|
|
|
|
list-style-type: none;
|
|
|
|
padding: 0;
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.search-results li {
|
|
|
|
padding: 10px;
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
.search-results li:hover {
|
|
|
|
background-color: #f0f0f0;
|
|
|
|
}
|
2023-08-02 01:34:46 +07:00
|
|
|
</style>
|