openStreetMap

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2023-09-12 11:24:50 +07:00
parent 70b40cf36c
commit 23e44b01bd
4 changed files with 307 additions and 141 deletions

View file

@ -23,22 +23,28 @@
"@fullcalendar/vue3": "^6.0.1", "@fullcalendar/vue3": "^6.0.1",
"@quasar/extras": "^1.15.8", "@quasar/extras": "^1.15.8",
"@tato30/vue-pdf": "^1.5.1", "@tato30/vue-pdf": "^1.5.1",
"@types/geojson": "^7946.0.10",
"@vuepic/vue-datepicker": "^3.6.3", "@vuepic/vue-datepicker": "^3.6.3",
"bma-org-chart": "^0.0.7", "bma-org-chart": "^0.0.7",
"keycloak-js": "^20.0.2", "keycloak-js": "^20.0.2",
"moment": "^2.29.4", "moment": "^2.29.4",
"ol": "^7.5.2",
"ol-contextmenu": "^5.2.1",
"ol-ext": "^4.0.11",
"pinia": "^2.0.29", "pinia": "^2.0.29",
"quasar": "^2.11.1", "quasar": "^2.11.1",
"structure-chart": "^0.0.9", "structure-chart": "^0.0.9",
"vue": "^3.2.45", "vue": "^3.2.45",
"vue-router": "^4.1.6", "vue-router": "^4.1.6",
"vue3-datepicker": "^0.3.4", "vue3-datepicker": "^0.3.4",
"vue3-openlayers": "^1.2.2",
"vue3-pdfjs": "^0.1.6" "vue3-pdfjs": "^0.1.6"
}, },
"devDependencies": { "devDependencies": {
"@quasar/vite-plugin": "^1.3.0", "@quasar/vite-plugin": "^1.3.0",
"@rushstack/eslint-patch": "^1.1.4", "@rushstack/eslint-patch": "^1.1.4",
"@types/jsdom": "^20.0.1", "@types/jsdom": "^20.0.1",
"@types/leaflet": "^1.9.4",
"@types/node": "^18.11.12", "@types/node": "^18.11.12",
"@vitejs/plugin-vue": "^4.0.0", "@vitejs/plugin-vue": "^4.0.0",
"@vitejs/plugin-vue-jsx": "^3.0.0", "@vitejs/plugin-vue-jsx": "^3.0.0",
@ -61,5 +67,4 @@
"vue-table-to-excel": "^1.0.6", "vue-table-to-excel": "^1.0.6",
"vue-tsc": "^1.0.12" "vue-tsc": "^1.0.12"
} }
} }

View file

@ -9,6 +9,7 @@ import "@vuepic/vue-datepicker/dist/main.css"
import "quasar/src/css/index.sass" import "quasar/src/css/index.sass"
import http from "./plugins/http" import http from "./plugins/http"
import OpenLayersMap from "vue3-openlayers";
// import './assets/main.css' // import './assets/main.css'
@ -25,6 +26,7 @@ app.use(Quasar, {
}, },
lang: th, lang: th,
}) })
app.use(OpenLayersMap /* options */);
app.component( app.component(
"datepicker", "datepicker",

View file

@ -0,0 +1,100 @@
<template>
<div>
<div id="map"></div>
</div>
</template>
<script setup lang="ts">
import { onMounted } from "vue";
import Map from "ol/Map";
import View from "ol/View";
import { fromLonLat } from "ol/proj";
import { Tile as TileLayer } from "ol/layer";
import { OSM } from "ol/source";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import Circle from "ol/geom/Circle";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { Style, Icon, Fill, Stroke } from "ol/style";
onMounted(() => {
const map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: fromLonLat([98.981716, 18.7883]),
zoom: 12,
}),
});
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition((position) => {
console.log(position);
const lon = position.coords.longitude;
const lat = position.coords.latitude;
const coordinates = fromLonLat([lon, lat]);
currentLocationFeature.setGeometry(new Point(coordinates));
map.getView().setCenter(coordinates);
});
}
// feature
const currentLocationFeature = new Feature({
geometry: new Point(fromLonLat([98.981716, 18.7883])),
});
currentLocationFeature.setStyle(
new Style({
image: new Icon({
src: "https://assets.untappd.com/site/beer_logos_hd/beer-4817317_108bb_hd.jpeg",
scale: 0.02,
}),
})
);
const currentLocationLayer = new VectorLayer({
source: new VectorSource({
features: [currentLocationFeature],
}),
});
map.addLayer(currentLocationLayer);
//
const circleFeature = new Feature({
geometry: new Circle(fromLonLat([98.981716, 18.7883]), 1000),
});
circleFeature.setStyle(
new Style({
fill: new Fill({
color: "rgba(2, 169, 152, 0.2)",
}),
stroke: new Stroke({
color: "rgb(2, 169, 152)",
width: 2,
}),
})
);
const circleLayer = new VectorLayer({
source: new VectorSource({
features: [circleFeature],
}),
});
map.addLayer(circleLayer);
});
</script>
<style scoped>
#map {
width: 100%;
height: 400px;
}
</style>

View file

@ -17,44 +17,97 @@
<div class="col-12"> <div class="col-12">
<q-card bordered class="q-pa-md"> <q-card bordered class="q-pa-md">
<div class="col-12 row justify-center q-pb-sm"> <div class="col-12 row justify-center q-pb-sm">
<div class="col-xs-12 col-sm-10 text-h6 text-primary text-center text-weight-bold">เวลาในขณะน</div> <div
class="col-xs-12 col-sm-10 text-h6 text-primary text-center text-weight-bold"
>
เวลาในขณะน
</div>
<div class="row col-12 justify-center q-py-md"> <div class="row col-12 justify-center q-py-md">
<div class="colunm"> <div class="colunm">
<div class="text-h2 text-weight-bold">{{ formattedH }}<span class="q-ma-md">:</span></div> <div class="text-h2 text-weight-bold">
{{ formattedH }}<span class="q-ma-md">:</span>
</div>
<div>วโมง</div> <div>วโมง</div>
</div> </div>
<div class="colunm"> <div class="colunm">
<div class="text-h2 text-weight-bold">{{ formattedM }}<span class="q-ma-md">:</span></div> <div class="text-h2 text-weight-bold">
{{ formattedM }}<span class="q-ma-md">:</span>
</div>
<div>นาท</div> <div>นาท</div>
</div> </div>
<div class="colunm"> <div class="colunm">
<div class="text-h2 text-weight-bold">{{ formattedS }} </div> <div class="text-h2 text-weight-bold">{{ formattedS }}</div>
<div>นาท</div> <div>นาท</div>
</div> </div>
</div> </div>
<!-- <div class="col-12 text-center text-weight-medium items-center text-dark q-pt-md"><q-icon color="primary" name="mdi-calendar-outline" class="q-mr-sm"/>นท {{dateNow}}</div> --> <!-- <div class="col-12 text-center text-weight-medium items-center text-dark q-pt-md"><q-icon color="primary" name="mdi-calendar-outline" class="q-mr-sm"/>นท {{dateNow}}</div> -->
<div class="col-12 row q-col-gutter-md"> <div class="col-12 row q-col-gutter-md">
<div class="col-12 col-sm-8"> <div class="col-12 col-sm-8">
<q-card bordered flat class="col-12 bg-grey-3"> <q-card
<q-img src="@/assets/map1.png" :style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'"> </q-img> bordered
flat
class="col-12 bg-grey-3"
:style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'"
>
<!-- <mapCheckin /> -->
<q-img
src="@/assets/map1.png"
:style="
$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'
"
>
</q-img>
</q-card> </q-card>
</div> </div>
<div class="col-12 col-sm-4"> <div class="col-12 col-sm-4">
<q-card flat class="col-12 bg-grey-3 items-center row" :style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'"> <q-card
flat
class="col-12 bg-grey-3 items-center row"
:style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'"
>
<div class="column col-12" v-if="!camera"> <div class="column col-12" v-if="!camera">
<div class="text-center"><q-icon name="mdi-image-off-outline" size="100px" color="grey-7" /></div> <div class="text-center">
<div class="text-center q-pt-md text-grey-7">ไมปภาพ</div> <q-icon
name="mdi-image-off-outline"
size="100px"
color="grey-7"
/>
</div> </div>
<q-img v-else src="@/assets/camera.jpg" :style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'"> </q-img> <div class="text-center q-pt-md text-grey-7">
ไมปภาพ
</div>
</div>
<q-img
v-else
src="@/assets/camera.jpg"
:style="
$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'
"
>
</q-img>
<div class="absolute-bottom-right q-ma-md"> <div class="absolute-bottom-right q-ma-md">
<q-btn round push icon="mdi-camera" size="md" color="positive" @click="photo()" /> <q-btn
round
push
icon="mdi-camera"
size="md"
color="positive"
@click="photo()"
/>
</div> </div>
</q-card> </q-card>
</div> </div>
</div> </div>
</div> </div>
<div class="col-12 text-right q-pt-md" v-if="camera"> <div class="col-12 text-right q-pt-md" v-if="camera">
<q-btn label="ยืนยันเวลาเข้างาน" color="blue" push size="16px" :class="$q.screen.gt.xs ? 'q-px-md' : 'full-width'" @click="confirm" /> <q-btn
label="ยืนยันเวลาเข้างาน"
color="blue"
push
size="16px"
:class="$q.screen.gt.xs ? 'q-px-md' : 'full-width'"
@click="confirm"
/>
</div> </div>
</q-card> </q-card>
</div> </div>
@ -68,7 +121,9 @@
</q-card-section> </q-card-section>
<q-card-section style="max-height: 50vh"> <q-card-section style="max-height: 50vh">
<div class="row col-12 justify-center q-pb-md"> <div class="row col-12 justify-center q-pb-md">
<div class="text-h2 text-weight-bold">{{ formattedH }}<span class="q-ma-md">:</span></div> <div class="text-h2 text-weight-bold">
{{ formattedH }}<span class="q-ma-md">:</span>
</div>
<div class="text-h2 text-weight-bold">{{ formattedM }}</div> <div class="text-h2 text-weight-bold">{{ formattedM }}</div>
</div> </div>
</q-card-section> </q-card-section>
@ -85,7 +140,8 @@ import type { QTableProps } from "quasar";
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import { useQuasar } from "quasar"; import { useQuasar } from "quasar";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import moment, { Moment } from 'moment' import moment, { Moment } from "moment";
// import mapCheckin from "../componenst/mapCheck.vue";
const router = useRouter(); const router = useRouter();
const $q = useQuasar(); const $q = useQuasar();
@ -97,16 +153,19 @@ const map = ref(null);
const camera = ref(false); const camera = ref(false);
const dialogTime = ref(false); const dialogTime = ref(false);
const photo = () => { camera.value = true }; const photo = () => {
const confirm = () => { dialogTime.value = true }; camera.value = true;
};
const confirm = () => {
dialogTime.value = true;
};
var date = Date.now() var date = Date.now();
let formattedH = (moment(date)).format('HH') let formattedH = moment(date).format("HH");
let formattedM = (moment(date)).format('mm') let formattedM = moment(date).format("mm");
let formattedS = (moment(date)).format('ss') let formattedS = moment(date).format("ss");
const time = new Date().toLocaleTimeString(); const time = new Date().toLocaleTimeString();
</script> </script>
<style></style> <style></style>