Compare commits

...

6 Commits
main ... map

@ -1,87 +1,144 @@
<template> <template>
<div class="map-wrap"> <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 id="map" class="map" ref="mapContainer"></div>
</div> </div>
</template> </template>
<script> <script>
import maplibregl from "maplibre-gl"; import maplibregl from "maplibre-gl";
import { markRaw, onMounted, onUnmounted, reactive, shallowRef, watch } from "vue"; import {
markRaw,
onMounted,
onUnmounted,
reactive,
shallowRef,
watch,
} from "vue";
export default { export default {
name: "map-component", name: "map-component",
props: { props: {
idlist: { idlist: {
type: Array, type: Array,
required: true, required: true,
} },
},
data() {
return {
valuebm: "",
options: ["Карта", "Спутник", "Монохром"],
valuecb: true,
label: "Месторождения",
};
}, },
setup(props, context) { setup(props, context) {
const mapContainer = shallowRef(null); const mapContainer = shallowRef(null);
const map = shallowRef(null); const map = shallowRef(null);
let currentFadr = reactive({ "fadr": [] }); let currentFadr = reactive({ fadr: [] });
const apiKey = "pk.eyJ1IjoiZ2hlcm1hbnQiLCJhIjoiY2pncDUwcnRmNDQ4ZjJ4czdjZXMzaHZpNyJ9.3rFyYRRtvLUngHm027HZ7A"; const apiKey =
"pk.eyJ1IjoiZ2hlcm1hbnQiLCJhIjoiY2pncDUwcnRmNDQ4ZjJ4czdjZXMzaHZpNyJ9.3rFyYRRtvLUngHm027HZ7A";
watch(
watch(() => [...props.idlist], (_currentValue, _oldValue) => { () => [...props.idlist],
updateSamplesLayer() (_currentValue, _oldValue) => {
}); updateSamplesLayer();
}
);
const buildMap = () => { const buildMap = () => {
map.value = markRaw(new maplibregl.Map({ map.value = markRaw(
new maplibregl.Map({
container: mapContainer.value, // container id container: mapContainer.value, // container id
// DOCS: https://maplibre.org/maplibre-gl-js-docs/style-spec/ // DOCS: https://maplibre.org/maplibre-gl-js-docs/style-spec/
style: { style: {
version: 8, version: 8,
sources: {}, sources: {},
layers: [] layers: [],
}, },
center: [80, 40], // starting position [lng, lat] center: [80, 40], // starting position [lng, lat]
zoom: 2, // starting zoom zoom: 2, // starting zoom
maxZoom: 10 maxZoom: 10,
}));
map.value.on('load', () => {
map.value.addSource('basemap-source', {
'type': 'raster',
'tiles': [`https://api.mapbox.com/styles/v1/ghermant/cl8vg2r97001m14o4c2qzw9t6/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`]
}) })
);
map.value.addLayer( map.value.on("load", () => {
{ const basemapTiles = {
'id': 'basemap-layer', "topo": [`https://api.mapbox.com/styles/v1/ghermant/cl9vd1nji002n15s2xxj25f4m/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`],
'type': 'raster', "satellite": [`https://api.mapbox.com/styles/v1/ghermant/cl9vd1nji002n15s2xxj25f4m/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`],
'source': 'basemap-source', "mono": [`https://api.mapbox.com/styles/v1/ghermant/cl9olarp0002i14vq9a2d0e7g/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`]
'paint': {}
} }
);
map.value.addSource("basemap", {
type: "raster",
tiles: [
`https://api.mapbox.com/styles/v1/ghermant/cl9vd1nji002n15s2xxj25f4m/tiles/256/{z}/{x}/{y}@2x?access_token=${apiKey}`,
],
});
map.value.addSource('samples', { map.value.addLayer({
'type': 'vector', id: "basemap-layer",
"tiles": ["http://localhost:8080/martin/public.geodata/{z}/{x}/{y}.pbf"], type: "raster",
'promoteId': 'fadr', source: "topo-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({ map.value.addLayer({
'id': 'samples-layer', id: "fields-layer",
'source': 'samples', type: "fill",
'source-layer': 'public.geodata', source: "fields",
'type': 'circle', "source-layer": "mygeomapZoom2-2utkfs",
'paint': { paint: {
'circle-stroke-width': 1, "fill-color": "#fc9272",
'circle-stroke-color': '#FFFFFF', "fill-opacity": 0.5,
'circle-color': [ },
'case', layout: {
['boolean', ['feature-state', 'beenClicked'], false], visibility: "visible",
'#fec44f', },
'#d95f0e' minzoom: 4
});
map.value.addSource("samples", {
type: "vector",
tiles: [
"http://localhost:8080/martin/public.geodata/{z}/{x}/{y}.pbf",
], ],
'circle-opacity': 0.8, promoteId: "fadr",
'circle-radius': 8 });
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] filter: ["match", ["get", "internal_id"], props.idlist, true, false],
}); });
}); });
@ -90,9 +147,24 @@ export default {
closeOnClick: false, closeOnClick: false,
}) })
map.value.on('mouseover', 'samples-layer', (e) => { 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. // Change the cursor style as a UI indicator.
map.value.getCanvas().style.cursor = 'pointer'; map.value.getCanvas().style.cursor = "pointer";
// Populate the popup and set its coordinates // Populate the popup and set its coordinates
// based on the feature found. // based on the feature found.
popup popup
@ -101,35 +173,35 @@ export default {
.addTo(map.value); .addTo(map.value);
}); });
map.value.on('mouseleave', 'samples-layer', (e) => { map.value.on("mouseleave", "samples-layer", (e) => {
map.value.getCanvas().style.cursor = ''; map.value.getCanvas().style.cursor = "";
popup.remove(); popup.remove();
}); });
map.value.on('click', 'samples-layer', (e) => { map.value.on("click", "samples-layer", (e) => {
let newFadr = e.features[0].properties["fadr"]; let newFadr = e.features[0].properties["fadr"];
let newFadrFound = currentFadr["fadr"].indexOf(newFadr) let newFadrFound = currentFadr["fadr"].indexOf(newFadr);
if (newFadrFound > -1) { if (newFadrFound > -1) {
//remove old paint //remove old paint
map.value.setFeatureState( map.value.setFeatureState(
{ {
source: 'samples', source: "samples",
sourceLayer: 'public.geodata', sourceLayer: "public.geodata",
id: newFadr id: newFadr,
}, },
{ beenClicked: false } { beenClicked: false }
); );
// remove from filters // remove from filters
currentFadr["fadr"].splice(newFadrFound, 1) currentFadr["fadr"].splice(newFadrFound, 1);
} else { } else {
// apply new paint // apply new paint
map.value.setFeatureState( map.value.setFeatureState(
{ {
source: 'samples', source: "samples",
sourceLayer: 'public.geodata', sourceLayer: "public.geodata",
id: newFadr id: newFadr,
}, },
{ beenClicked: true } { beenClicked: true }
); );
@ -138,78 +210,75 @@ export default {
currentFadr["fadr"].push(newFadr); currentFadr["fadr"].push(newFadr);
} }
context.emit('mapClick', currentFadr); context.emit("mapClick", currentFadr);
}); });
map.value.on("click", (e) => {
map.value.on('click', (e) => { const features = map.value.queryRenderedFeatures(e.point);
const features = map.value.queryRenderedFeatures(e.point)
if (!features.length) { if (!features.length) {
currentFadr["fadr"].forEach((oldFadr) => { currentFadr["fadr"].forEach((oldFadr) => {
map.value.setFeatureState( map.value.setFeatureState(
{ {
source: 'samples', source: "samples",
sourceLayer: 'public.geodata', sourceLayer: "public.geodata",
id: oldFadr id: oldFadr,
}, },
{ beenClicked: false } { beenClicked: false }
); );
}) });
currentFadr["fadr"].length = 0; currentFadr["fadr"].length = 0;
} }
context.emit('mapClick', currentFadr); context.emit("mapClick", currentFadr);
}); });
}; };
const updateSamplesLayer = () => { const updateSamplesLayer = () => {
if (map.value.getLayer('samples-layer')) { if (map.value.getLayer("samples-layer")) {
map.value.removeLayer('samples-layer'); map.value.removeLayer("samples-layer");
} }
if (props.idlist.length) { if (props.idlist.length) {
map.value.addLayer({ map.value.addLayer({
'id': 'samples-layer', id: "samples-layer",
'source': 'samples', source: "samples",
'source-layer': 'public.geodata', "source-layer": "public.geodata",
'type': 'circle', type: "circle",
'paint': { paint: {
'circle-stroke-width': 1, "circle-stroke-width": 1,
'circle-stroke-color': '#FFFFFF', "circle-stroke-color": "#FFFFFF",
'circle-color': [ "circle-color": [
'case', "case",
['boolean', ['feature-state', 'beenClicked'], false], ["boolean", ["feature-state", "beenClicked"], false],
'#fec44f', "#fec44f",
'#d95f0e' "#d95f0e",
], ],
'circle-opacity': 0.8, "circle-opacity": 0.8,
'circle-radius': 8 "circle-radius": 8,
}, },
filter: ["match", ["get", "internal_id"], props.idlist, true, false] filter: ["match", ["get", "internal_id"], props.idlist, true, false],
}); });
} }
}; };
onMounted(() => { onMounted(() => {
buildMap() buildMap();
}); });
onUnmounted(() => { onUnmounted(() => {
// TODO: remove even listeners too // TODO: remove even listeners too
map.value?.remove(); map.value?.remove();
}) });
return { return {
map, mapContainer, currentFadr map,
} mapContainer,
} currentFadr,
} };
},
};
</script> </script>
<style lang="css"> <style lang="css">
.map-wrap { .map-wrap {
position: relative; position: relative;
@ -223,6 +292,12 @@ export default {
bottom: 0; bottom: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
/* z-index: -1; */ z-index: -1;
}
#layer-control {
position: absolute;
top: 1rem;
right: 1rem;
} }
</style> </style>

@ -17,7 +17,7 @@ export default {
<style lang="css"> <style lang="css">
.sidebar-proper { .sidebar-proper {
height: max(100vh, 100%); height: max(100vh, 100%);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.75); box-shadow: 0 0 15px rgba(0, 0, 0, 0.25);
clip-path: inset(0px -15px 0px 0px); clip-path: inset(0px -15px 0px 0px);
overflow-y: hidden; overflow-y: hidden;
} }

Loading…
Cancel
Save