Compare commits
6 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
d331af259e | 3 years ago |
|
|
ca020ab3b3 | 3 years ago |
|
|
f838889afd | 3 years ago |
|
|
6f0ed6960b | 3 years ago |
|
|
ed609322fa | 3 years ago |
|
|
78df895fe9 | 3 years ago |
@ -1,38 +0,0 @@
|
||||
"""Cast resolution as float
|
||||
|
||||
Revision ID: 15b3c7a8e804
|
||||
Revises: 4968a333a100
|
||||
Create Date: 2022-10-31 23:55:04.806055
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "15b3c7a8e804"
|
||||
down_revision = "4968a333a100"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands MANUALLY composed for Alembic ###
|
||||
op.execute(
|
||||
sa.text(
|
||||
"ALTER TABLE geodata ALTER COLUMN resolution TYPE FLOAT USING resolution::double precision"
|
||||
)
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic ###
|
||||
op.alter_column(
|
||||
"geodata",
|
||||
"resolution",
|
||||
existing_type=sa.Float(),
|
||||
type_=sa.VARCHAR(),
|
||||
existing_nullable=True,
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
@ -1,47 +1,36 @@
|
||||
{
|
||||
order jwtauth before basicauth
|
||||
}
|
||||
|
||||
:80 {
|
||||
encode zstd gzip
|
||||
encode zstd gzip
|
||||
|
||||
handle_path /api/v1/* {
|
||||
rewrite * {path}
|
||||
reverse_proxy geodata:8000
|
||||
}
|
||||
handle_path /api/v1/* {
|
||||
rewrite * {path}
|
||||
reverse_proxy geodata:8000
|
||||
}
|
||||
|
||||
redir /openapi.json /api/v1/openapi.json permanent
|
||||
redir /openapi.json /api/v1/openapi.json permanent
|
||||
|
||||
handle_path /martin/* {
|
||||
rewrite * {path}
|
||||
reverse_proxy martin:3000
|
||||
}
|
||||
|
||||
@is_admin {
|
||||
vars {http.auth.user.id} "demo"
|
||||
}
|
||||
handle_path /martin/* {
|
||||
rewrite * {path}
|
||||
reverse_proxy martin:3000
|
||||
}
|
||||
|
||||
handle_path /pgweb/* {
|
||||
jwtauth {
|
||||
sign_key {$SECRET_KEY}
|
||||
from_cookies user_session
|
||||
}
|
||||
|
||||
rewrite * {path}
|
||||
reverse_proxy @is_admin pgweb:8081
|
||||
redir /login/ 401
|
||||
}
|
||||
handle_path /pgweb/* {
|
||||
rewrite * {path}
|
||||
reverse_proxy pgweb:8081
|
||||
}
|
||||
|
||||
handle_path /static/previews/* {
|
||||
rewrite * {path}
|
||||
file_server
|
||||
}
|
||||
handle_path /static/previews/* {
|
||||
rewrite * {path}
|
||||
file_server
|
||||
}
|
||||
|
||||
# play nice with vue-router
|
||||
# https://caddy.community/t/caddy-with-vue-router/12352
|
||||
handle {
|
||||
# play nice with vue-router
|
||||
# https://caddy.community/t/caddy-with-vue-router/12352
|
||||
handle {
|
||||
root * /usr/share/caddy
|
||||
try_files {path}.html {path} /index.html
|
||||
file_server
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,18 +1,12 @@
|
||||
# build stage
|
||||
FROM caddy:2-builder-alpine as xcaddy-stage
|
||||
RUN xcaddy build --with github.com/ggicci/caddy-jwt
|
||||
|
||||
|
||||
FROM node:12.22.12-bullseye as build-stage
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm install
|
||||
COPY . .
|
||||
RUN npx browserslist@latest --update-db
|
||||
RUN npm run build
|
||||
|
||||
# production stage
|
||||
FROM caddy:2-alpine as production-stage
|
||||
COPY --from=xcaddy-stage /usr/bin/caddy /usr/bin/caddy
|
||||
COPY --from=build-stage /app/dist /usr/share/caddy
|
||||
EXPOSE 80
|
||||
@ -1,304 +1,303 @@
|
||||
<template>
|
||||
<div class="map-wrap">
|
||||
<div id="layer-control" class="d-flex flex-direction-column">
|
||||
<va-radio class="radio-switcher" v-for="(option, index) in viewOptions" :key="index"
|
||||
v-model="selectedOption" :option="option" :label="viewLabels[index]"></va-radio>
|
||||
<va-checkbox class="mb-4 fields-switch" v-model="valuecb" label="Месторождения" />
|
||||
</div>
|
||||
<div id="map" class="map" ref="mapContainer"></div>
|
||||
<div class="map-wrap">
|
||||
<div id="layer-control" class="d-flex flex-direction-column">
|
||||
<va-radio
|
||||
v-for="(option, index) in options"
|
||||
:key="index"
|
||||
v-model="selectedOption"
|
||||
:option="option"
|
||||
:label="labels[index]"
|
||||
/>
|
||||
<va-checkbox class="mb-4" v-model="valuecb" :label="label" />
|
||||
</div>
|
||||
<div id="map" class="map" ref="mapContainer"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import maplibregl from "maplibre-gl";
|
||||
import { markRaw, onMounted, onUnmounted, reactive, ref, shallowRef, watch } from "vue";
|
||||
import {
|
||||
markRaw,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
reactive,
|
||||
shallowRef,
|
||||
watch,
|
||||
} from "vue";
|
||||
export default {
|
||||
name: "map-component",
|
||||
props: {
|
||||
idlist: {
|
||||
type: Array,
|
||||
required: true,
|
||||
}
|
||||
name: "map-component",
|
||||
props: {
|
||||
idlist: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
setup(props, context) {
|
||||
const mapContainer = shallowRef(null);
|
||||
const map = shallowRef(null);
|
||||
let currentFadr = reactive({ "fadr": [] });
|
||||
const valuecb = ref(true);
|
||||
const selectedOption = ref("topo");
|
||||
const viewOptions = ["topo", "satellite", "mono"];
|
||||
const viewLabels = ["Карта", "Спутник", "Монохром"];
|
||||
|
||||
const apiKey = "pk.eyJ1IjoiZ2hlcm1hbnQiLCJhIjoiY2pncDUwcnRmNDQ4ZjJ4czdjZXMzaHZpNyJ9.3rFyYRRtvLUngHm027HZ7A";
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
valuebm: "",
|
||||
options: ["Карта", "Спутник", "Монохром"],
|
||||
valuecb: true,
|
||||
label: "Месторождения",
|
||||
};
|
||||
},
|
||||
setup(props, context) {
|
||||
const mapContainer = shallowRef(null);
|
||||
const map = shallowRef(null);
|
||||
let currentFadr = reactive({ fadr: [] });
|
||||
|
||||
const apiKey =
|
||||
"pk.eyJ1IjoiZ2hlcm1hbnQiLCJhIjoiY2pncDUwcnRmNDQ4ZjJ4czdjZXMzaHZpNyJ9.3rFyYRRtvLUngHm027HZ7A";
|
||||
|
||||
watch(
|
||||
() => [...props.idlist],
|
||||
(_currentValue, _oldValue) => {
|
||||
updateSamplesLayer();
|
||||
}
|
||||
);
|
||||
|
||||
const buildMap = () => {
|
||||
map.value = markRaw(
|
||||
new maplibregl.Map({
|
||||
container: mapContainer.value, // container id
|
||||
// DOCS: https://maplibre.org/maplibre-gl-js-docs/style-spec/
|
||||
style: {
|
||||
version: 8,
|
||||
sources: {},
|
||||
layers: [],
|
||||
},
|
||||
center: [80, 40], // starting position [lng, lat]
|
||||
zoom: 2, // starting zoom
|
||||
maxZoom: 10,
|
||||
})
|
||||
);
|
||||
|
||||
map.value.on("load", () => {
|
||||
const basemapTiles = {
|
||||
"topo": [`https://api.mapbox.com/styles/v1/ghermant/cl9vd1nji002n15s2xxj25f4m/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`],
|
||||
"satellite": [`https://api.mapbox.com/styles/v1/ghermant/cl9olarp0002i14vq9a2d0e7g/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`],
|
||||
"mono": [`https://api.mapbox.com/styles/v1/ghermant/cl9vd7xwi004u14nxu3j83scj/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`]
|
||||
|
||||
};
|
||||
"topo": [`https://api.mapbox.com/styles/v1/ghermant/cl9vd1nji002n15s2xxj25f4m/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`],
|
||||
"satellite": [`https://api.mapbox.com/styles/v1/ghermant/cl9vd1nji002n15s2xxj25f4m/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`],
|
||||
"mono": [`https://api.mapbox.com/styles/v1/ghermant/cl9olarp0002i14vq9a2d0e7g/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`]
|
||||
}
|
||||
|
||||
watch(() => [...props.idlist], (_currentValue, _oldValue) => {
|
||||
updateSamplesLayer()
|
||||
map.value.addSource("basemap", {
|
||||
type: "raster",
|
||||
tiles: [
|
||||
`https://api.mapbox.com/styles/v1/ghermant/cl9vd1nji002n15s2xxj25f4m/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`,
|
||||
],
|
||||
});
|
||||
|
||||
watch(() => valuecb.value, (_currentValue, _oldValue) => {
|
||||
updateFieldsLayer()
|
||||
map.value.addLayer({
|
||||
id: "basemap-layer",
|
||||
type: "raster",
|
||||
source: "topo-basemap",
|
||||
paint: {},
|
||||
});
|
||||
|
||||
watch(() => selectedOption.value, (_currentValue, _oldValue) => {
|
||||
updateBaseLayer()
|
||||
})
|
||||
|
||||
const buildMap = () => {
|
||||
map.value = markRaw(new maplibregl.Map({
|
||||
container: mapContainer.value, // container id
|
||||
// DOCS: https://maplibre.org/maplibre-gl-js-docs/style-spec/
|
||||
style: {
|
||||
version: 8,
|
||||
sources: {},
|
||||
layers: []
|
||||
},
|
||||
center: [80, 40], // starting position [lng, lat]
|
||||
zoom: 2, // starting zoom
|
||||
maxZoom: 10
|
||||
}));
|
||||
|
||||
map.value.on('load', () => {
|
||||
map.value.addSource('basemap', {
|
||||
'type': 'raster',
|
||||
'tiles': basemapTiles[selectedOption.value]
|
||||
})
|
||||
|
||||
map.value.addLayer(
|
||||
{
|
||||
'id': 'basemap-layer',
|
||||
'type': 'raster',
|
||||
'source': 'basemap',
|
||||
'paint': {}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
map.value.addSource("fields", {
|
||||
type: "vector",
|
||||
tiles: [`https://api.mapbox.com/v4/ghermant.cpc0xaaw/{z}/{x}/{y}.mvt?access_token=${apiKey}`]
|
||||
})
|
||||
map.value.addLayer({
|
||||
'id': 'fields-layer',
|
||||
'type': 'fill',
|
||||
'source': 'fields',
|
||||
'source-layer': 'mygeomapZoom2-2utkfs',
|
||||
'paint': {
|
||||
'fill-color': '#fc9272',
|
||||
'fill-opacity': 0.5
|
||||
},
|
||||
'layout': {
|
||||
'visibility': 'visible'
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
map.value.addSource('samples', {
|
||||
'type': 'vector',
|
||||
"tiles": ["http://localhost/martin/public.geodata/{z}/{x}/{y}.pbf"],
|
||||
'promoteId': 'fadr',
|
||||
});
|
||||
|
||||
map.value.addLayer({
|
||||
'id': 'samples-layer',
|
||||
'source': 'samples',
|
||||
'source-layer': 'public.geodata',
|
||||
'type': 'circle',
|
||||
'paint': {
|
||||
'circle-stroke-width': 1,
|
||||
'circle-stroke-color': '#FFFFFF',
|
||||
'circle-color': [
|
||||
'case',
|
||||
['boolean', ['feature-state', 'beenClicked'], false],
|
||||
'#fec44f',
|
||||
'#d95f0e'
|
||||
],
|
||||
'circle-opacity': 0.8,
|
||||
'circle-radius': 8
|
||||
},
|
||||
filter: ["match", ["get", "internal_id"], props.idlist, true, false]
|
||||
});
|
||||
});
|
||||
|
||||
const popup = new maplibregl.Popup({
|
||||
closeButton: false,
|
||||
closeOnClick: false,
|
||||
});
|
||||
|
||||
map.value.on("click", "fields-layer", (e) => {
|
||||
new maplibregl.Popup({})
|
||||
.setLngLat(e.lngLat)
|
||||
.setHTML(e.features[0].properties["descriptio"])
|
||||
.addTo(map.value);
|
||||
});
|
||||
|
||||
map.value.on("mouseover", "fields-layer", (e) => {
|
||||
map.value.getCanvas().style.cursor = "pointer";
|
||||
});
|
||||
|
||||
map.value.on("mouseleave", "fields-layer", (e) => {
|
||||
map.value.getCanvas().style.cursor = "";
|
||||
});
|
||||
|
||||
|
||||
map.value.on('mouseover', 'samples-layer', (e) => {
|
||||
// Change the cursor style as a UI indicator.
|
||||
map.value.getCanvas().style.cursor = 'pointer';
|
||||
// Populate the popup and set its coordinates
|
||||
// based on the feature found.
|
||||
popup
|
||||
.setLngLat(e.features[0].geometry.coordinates)
|
||||
.setHTML(`Записей в точке: <b>${e.features.length}</b>`)
|
||||
.addTo(map.value);
|
||||
});
|
||||
|
||||
map.value.on('mouseleave', 'samples-layer', (e) => {
|
||||
map.value.getCanvas().style.cursor = '';
|
||||
popup.remove();
|
||||
});
|
||||
|
||||
map.value.on('click', 'samples-layer', (e) => {
|
||||
let newFadr = e.features[0].properties["fadr"];
|
||||
|
||||
let newFadrFound = currentFadr["fadr"].indexOf(newFadr)
|
||||
if (newFadrFound > -1) {
|
||||
//remove old paint
|
||||
map.value.setFeatureState(
|
||||
{
|
||||
source: 'samples',
|
||||
sourceLayer: 'public.geodata',
|
||||
id: newFadr
|
||||
},
|
||||
{ beenClicked: false }
|
||||
);
|
||||
|
||||
// remove from filters
|
||||
currentFadr["fadr"].splice(newFadrFound, 1)
|
||||
} else {
|
||||
// apply new paint
|
||||
map.value.setFeatureState(
|
||||
{
|
||||
source: 'samples',
|
||||
sourceLayer: 'public.geodata',
|
||||
id: newFadr
|
||||
},
|
||||
{ beenClicked: true }
|
||||
);
|
||||
|
||||
// add to filters
|
||||
currentFadr["fadr"].push(newFadr);
|
||||
}
|
||||
|
||||
context.emit('mapClick', currentFadr);
|
||||
});
|
||||
|
||||
|
||||
map.value.on('click', (e) => {
|
||||
const features = map.value.queryRenderedFeatures(e.point)
|
||||
if (!features.length) {
|
||||
currentFadr["fadr"].forEach((oldFadr) => {
|
||||
map.value.setFeatureState(
|
||||
{
|
||||
source: 'samples',
|
||||
sourceLayer: 'public.geodata',
|
||||
id: oldFadr
|
||||
},
|
||||
{ beenClicked: false }
|
||||
);
|
||||
})
|
||||
currentFadr["fadr"].length = 0;
|
||||
}
|
||||
|
||||
context.emit('mapClick', currentFadr);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
const updateSamplesLayer = () => {
|
||||
if (props.idlist.length < 2000) {
|
||||
map.value.setFilter('samples-layer', ["in", "internal_id", ...props.idlist])
|
||||
} else {
|
||||
map.value.setFilter('samples-layer', null)
|
||||
}
|
||||
};
|
||||
|
||||
const updateFieldsLayer = () => {
|
||||
const visibility = valuecb.value ? 'visible' : 'none';
|
||||
map.value.setLayoutProperty('fields-layer', 'visibility', visibility);
|
||||
};
|
||||
|
||||
const updateBaseLayer = () => {
|
||||
const selectedBasemap = selectedOption.value;
|
||||
// https://stackoverflow.com/questions/38631344/recommended-way-to-switch-tile-urls-in-mapbox-gl-js
|
||||
// Set the tile url to a cache-busting url (to circumvent browser caching behaviour):
|
||||
map.value.getSource('basemap').tiles = basemapTiles[selectedBasemap]
|
||||
// Remove the tiles for a particular source
|
||||
map.value.style.sourceCaches['basemap'].clearTiles()
|
||||
// Load the new tiles for the current viewport (map.value.transform -> viewport)
|
||||
map.value.style.sourceCaches['basemap'].update(map.value.transform)
|
||||
// Force a repaint, so that the map will be repainted without you having to touch the map
|
||||
map.value.triggerRepaint()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
buildMap()
|
||||
map.value.addSource("fields", {
|
||||
type: "vector",
|
||||
tiles: [
|
||||
`https://api.mapbox.com/v4/ghermant.cpc0xaaw/{z}/{x}/{y}.mvt?access_token=${apiKey}`,
|
||||
],
|
||||
});
|
||||
map.value.addLayer({
|
||||
id: "fields-layer",
|
||||
type: "fill",
|
||||
source: "fields",
|
||||
"source-layer": "mygeomapZoom2-2utkfs",
|
||||
paint: {
|
||||
"fill-color": "#fc9272",
|
||||
"fill-opacity": 0.5,
|
||||
},
|
||||
layout: {
|
||||
visibility: "visible",
|
||||
},
|
||||
minzoom: 4
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
// TODO: remove even listeners too
|
||||
map.value?.remove();
|
||||
})
|
||||
map.value.addSource("samples", {
|
||||
type: "vector",
|
||||
tiles: [
|
||||
"http://localhost:8080/martin/public.geodata/{z}/{x}/{y}.pbf",
|
||||
],
|
||||
promoteId: "fadr",
|
||||
});
|
||||
|
||||
map.value.addLayer({
|
||||
id: "samples-layer",
|
||||
source: "samples",
|
||||
"source-layer": "public.geodata",
|
||||
type: "circle",
|
||||
paint: {
|
||||
"circle-stroke-width": 1,
|
||||
"circle-stroke-color": "#FFFFFF",
|
||||
"circle-color": [
|
||||
"case",
|
||||
["boolean", ["feature-state", "beenClicked"], false],
|
||||
"#fec44f",
|
||||
"#d95f0e",
|
||||
],
|
||||
"circle-opacity": 0.8,
|
||||
"circle-radius": 8,
|
||||
},
|
||||
filter: ["match", ["get", "internal_id"], props.idlist, true, false],
|
||||
});
|
||||
});
|
||||
|
||||
const popup = new maplibregl.Popup({
|
||||
closeButton: false,
|
||||
closeOnClick: false,
|
||||
})
|
||||
|
||||
map.value.on("click", "fields-layer", (e) => {
|
||||
new maplibregl.Popup({})
|
||||
.setLngLat(e.lngLat)
|
||||
.setHTML(e.features[0].properties["descriptio"])
|
||||
.addTo(map.value);
|
||||
})
|
||||
|
||||
map.value.on("mouseover", "fields-layer", (e) => {
|
||||
map.value.getCanvas().style.cursor = "pointer";
|
||||
})
|
||||
|
||||
map.value.on("mouseleave", "fields-layer", (e) => {
|
||||
map.value.getCanvas().style.cursor = "";
|
||||
})
|
||||
|
||||
map.value.on("mouseover", "samples-layer", (e) => {
|
||||
// Change the cursor style as a UI indicator.
|
||||
map.value.getCanvas().style.cursor = "pointer";
|
||||
// Populate the popup and set its coordinates
|
||||
// based on the feature found.
|
||||
popup
|
||||
.setLngLat(e.lngLat)
|
||||
.setHTML(`Записей в точке: <b>${e.features.length}</b>`)
|
||||
.addTo(map.value);
|
||||
});
|
||||
|
||||
map.value.on("mouseleave", "samples-layer", (e) => {
|
||||
map.value.getCanvas().style.cursor = "";
|
||||
popup.remove();
|
||||
});
|
||||
|
||||
map.value.on("click", "samples-layer", (e) => {
|
||||
let newFadr = e.features[0].properties["fadr"];
|
||||
|
||||
let newFadrFound = currentFadr["fadr"].indexOf(newFadr);
|
||||
if (newFadrFound > -1) {
|
||||
//remove old paint
|
||||
map.value.setFeatureState(
|
||||
{
|
||||
source: "samples",
|
||||
sourceLayer: "public.geodata",
|
||||
id: newFadr,
|
||||
},
|
||||
{ beenClicked: false }
|
||||
);
|
||||
|
||||
// remove from filters
|
||||
currentFadr["fadr"].splice(newFadrFound, 1);
|
||||
} else {
|
||||
// apply new paint
|
||||
map.value.setFeatureState(
|
||||
{
|
||||
source: "samples",
|
||||
sourceLayer: "public.geodata",
|
||||
id: newFadr,
|
||||
},
|
||||
{ beenClicked: true }
|
||||
);
|
||||
|
||||
// add to filters
|
||||
currentFadr["fadr"].push(newFadr);
|
||||
}
|
||||
|
||||
return {
|
||||
map, mapContainer, currentFadr, valuecb, selectedOption, viewOptions, viewLabels
|
||||
context.emit("mapClick", currentFadr);
|
||||
});
|
||||
|
||||
map.value.on("click", (e) => {
|
||||
const features = map.value.queryRenderedFeatures(e.point);
|
||||
if (!features.length) {
|
||||
currentFadr["fadr"].forEach((oldFadr) => {
|
||||
map.value.setFeatureState(
|
||||
{
|
||||
source: "samples",
|
||||
sourceLayer: "public.geodata",
|
||||
id: oldFadr,
|
||||
},
|
||||
{ beenClicked: false }
|
||||
);
|
||||
});
|
||||
currentFadr["fadr"].length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.emit("mapClick", currentFadr);
|
||||
});
|
||||
};
|
||||
|
||||
const updateSamplesLayer = () => {
|
||||
if (map.value.getLayer("samples-layer")) {
|
||||
map.value.removeLayer("samples-layer");
|
||||
}
|
||||
|
||||
if (props.idlist.length) {
|
||||
map.value.addLayer({
|
||||
id: "samples-layer",
|
||||
source: "samples",
|
||||
"source-layer": "public.geodata",
|
||||
type: "circle",
|
||||
paint: {
|
||||
"circle-stroke-width": 1,
|
||||
"circle-stroke-color": "#FFFFFF",
|
||||
"circle-color": [
|
||||
"case",
|
||||
["boolean", ["feature-state", "beenClicked"], false],
|
||||
"#fec44f",
|
||||
"#d95f0e",
|
||||
],
|
||||
"circle-opacity": 0.8,
|
||||
"circle-radius": 8,
|
||||
},
|
||||
filter: ["match", ["get", "internal_id"], props.idlist, true, false],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
buildMap();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
// TODO: remove even listeners too
|
||||
map.value?.remove();
|
||||
});
|
||||
|
||||
return {
|
||||
map,
|
||||
mapContainer,
|
||||
currentFadr,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="css">
|
||||
.map-wrap {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.map {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* z-index: -1; */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
#layer-control {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
z-index: 5;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.radio-switcher {
|
||||
padding-left: 0.3rem;
|
||||
}
|
||||
|
||||
.fields-switch {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.va-radio__text, .va-checkbox__label {
|
||||
color: white;
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<va-select class="multi-selector" :options="datalistOptions" v-model="selectedOptions"
|
||||
@update:model-value="applyFilter" multiple searchable>
|
||||
</va-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "datalist-filter",
|
||||
data() {
|
||||
return {
|
||||
datalistOptions: [
|
||||
// SELECT DISTINCT BTRIM(UNNEST(STRING_TO_ARRAY(datalist,','))) FROM geodata;
|
||||
"Project",
|
||||
"Rec",
|
||||
"Data",
|
||||
"Raw",
|
||||
"Report",
|
||||
],
|
||||
selectedOptions: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
applyFilter() {
|
||||
const filter = { "datalist": this.selectedOptions }
|
||||
this.$emit('filter', filter, this.name)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="css">
|
||||
.multi-selector {
|
||||
--va-select-min-width: 12 rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<va-select class="multi-selector" :options="descriptionOptions" v-model="selectedOptions"
|
||||
@update:model-value="applyFilter" multiple searchable>
|
||||
</va-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "description-filter",
|
||||
data() {
|
||||
return {
|
||||
descriptionOptions: [
|
||||
"терригенная порода-коллектор",
|
||||
"черви",
|
||||
"бусины из скорлупы страуса",
|
||||
"осколки скорлупы яиц страуса",
|
||||
"лопатка лощади ",
|
||||
"грунты",
|
||||
"глинисто-карбонатная порода",
|
||||
"Искусстенная модель осадочных пород",
|
||||
"угли",
|
||||
],
|
||||
selectedOptions: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
applyFilter() {
|
||||
const filter = { "description": this.selectedOptions }
|
||||
this.$emit('filter', filter, this.name)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="css">
|
||||
.multi-selector {
|
||||
--va-select-min-width: 12 rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,42 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<va-select class="multi-selector" :options="formDimentionsOptions" v-model="selectedOptions"
|
||||
@update:model-value="applyFilter" multiple searchable>
|
||||
</va-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "form-dimentions-filter",
|
||||
data() {
|
||||
return {
|
||||
formDimentionsOptions: [
|
||||
"фрагмент 20 см",
|
||||
"фрагменты 5-7 см",
|
||||
"полноразмерный керн, 65 мм",
|
||||
"цилиндр, 8 мм",
|
||||
"цилиндр, 10 мм",
|
||||
"цилиндр, 30 мм",
|
||||
"полноразмерный керн",
|
||||
"полноразмерный керн, 100 мм",
|
||||
],
|
||||
selectedOptions: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
applyFilter() {
|
||||
const filter = { "form_dimentions": this.selectedOptions }
|
||||
this.$emit('filter', filter, this.name)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="css">
|
||||
.multi-selector {
|
||||
--va-select-min-width: 12 rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,42 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<va-select class="multi-selector" :options="projectOptions" v-model="selectedOptions"
|
||||
@update:model-value="applyFilter" multiple searchable>
|
||||
</va-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "project-filter",
|
||||
data() {
|
||||
return {
|
||||
projectOptions: [
|
||||
"AAK",
|
||||
"AAM",
|
||||
"ABB",
|
||||
"ABE",
|
||||
"AER",
|
||||
"AJL",
|
||||
"ASX",
|
||||
"ATM",
|
||||
],
|
||||
selectedOptions: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
applyFilter() {
|
||||
const filter = { "project": this.selectedOptions }
|
||||
this.$emit('filter', filter, this.name)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="css">
|
||||
.multi-selector {
|
||||
--va-select-min-width: 12 rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<div class="range-input">
|
||||
<va-input placeholder="1.59" v-model="reso_min" input-class="text--center"
|
||||
:mask="{ numeral: true, delimiter: '', numeralDecimalMark: ',' }" @change="applyFilter" />
|
||||
<va-input placeholder="264" v-model="reso_max" input-class="text--center"
|
||||
:mask="{ numeral: true, delimiter: '', numeralDecimalMark: ',' }" @change="applyFilter" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "resolution-filter",
|
||||
data() {
|
||||
return {
|
||||
// SELECT MIN(resolution), MAX(resolution) FROM geodata;
|
||||
reso_min: "1.59",
|
||||
reso_max: "264",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
applyFilter() {
|
||||
const filter = { "resolution": [this.reso_min, this.reso_max] }
|
||||
this.$emit('filter', filter, this.name)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="css">
|
||||
.range-input {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: 5rem
|
||||
}
|
||||
|
||||
.range-input>div {
|
||||
--va-input-wrapper-min-width: 4rem;
|
||||
width: 4rem;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in new issue