Open
Description
Hello,
I’m currently working with the ol-ext library in a Vue app and trying to display 3D features using the custom component from https://vue3openlayers.netlify.app/pluginsguide/ , but I’m unable to render any features on the map. I have followed the documentation and used Vector3DLayer, but the features do not appear in the 3D layer at all.
ol-ext example: https://github.com/Viglino/ol-ext/blob/master/examples/map/map.layer.3D.2.html
<template>
<form>
<label for="zoom">Zoom:</label>
<input type="number" id="zoom" v-model="zoom" />
</form>
<ol-map style="height: 400px" ref="mapRef">
<ol-view
ref="view"
:center="center"
:rotation="rotation"
:zoom="zoom"
:projection="projection"
@change:center="centerChanged"
@change:resolution="resolutionChanged"
@change:rotation="rotationChanged"
/>
<ol-tile-layer>
<ol-source-osm />
</ol-tile-layer>
<!-- 3D слой -->
<Vector3DLayer
:source="vectorSource"
:style="styleFunction"
:height="heightFunction"
ref="ref3Dlayer"
/>
<ol-rotate-control />
<ol-interaction-link />
</ol-map>
<div class="info">
<button @click="animateLayer">Animate!</button>
</div>
<div v-if="loading" class="loading">Loading data...</div>
<ul>
<li>center: {{ currentCenter }}</li>
<li>resolution: {{ currentResolution }}</li>
<li>zoom: {{ currentZoom }}</li>
<li>rotation: {{ currentRotation }}</li>
</ul>
</template>
<script setup>
import { ref, onMounted } from "vue";
import Vector3DLayer from "./Vector3DLayer.vue"; // Компонент для 3D слоя
import GeoJSON from "ol/format/GeoJSON";
import VectorSource from "ol/source/Vector";
import { Stroke } from "ol/style";
const center = ref([256267.70558611996, 6250141]);
const projection = ref("EPSG:3857");
const zoom = ref(15);
const rotation = ref(0);
const currentCenter = ref(center.value);
const currentZoom = ref(zoom.value);
const currentRotation = ref(rotation.value);
const currentResolution = ref(0);
function resolutionChanged(event) {
currentResolution.value = event.target.getResolution();
currentZoom.value = event.target.getZoom();
}
function centerChanged(event) {
currentCenter.value = event.target.getCenter();
}
function rotationChanged(event) {
currentRotation.value = event.target.getRotation();
}
const mapRef = ref(null);
const ref3Dlayer = ref(null);
const vectorSource = ref(new VectorSource());
const loading = ref(true);
let isAnimating = false;
const geojsonData = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [
[
[256267.70558611996, 6250141],
[256400.70558611996, 6250200],
[256350.70558611996, 6250300],
[256220.70558611996, 6250300],
[256267.70558611996, 6250141],
],
],
},
properties: { nb: 10 },
},
{
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [
[
[256500.70558611996, 6250200],
[256600.70558611996, 6250300],
[256550.70558611996, 6250400],
[256450.70558611996, 6250400],
[256500.70558611996, 6250200],
],
],
},
properties: { nb: 5 },
},
],
};
const loadGeoJSON = () => {
const features = new GeoJSON().readFeatures(geojsonData);
console.log("Загружены фичи:", features);
vectorSource.value.addFeatures(features);
loading.value = false;
};
// Анимация 3D слоя
const animateLayer = () => {
if (isAnimating) return;
const render3DLayer = ref3Dlayer.value?.vectorLayer;
if (!render3DLayer) {
console.error("3D слой ещё не инициализирован");
return;
}
isAnimating = true;
console.log("Анимация слоя...", render3DLayer);
render3DLayer.animate(
{ height: (f) => f.get("nb") * 20 },
{
duration: 2000,
complete: () => {
isAnimating = false;
},
}
);
};
onMounted(() => {
loadGeoJSON();
});
const styleFunction = (feature) => {
return {
stroke: new Stroke({
width: 5,
color: [255, 0, 0, 0.5],
}),
geometry: feature.getGeometry().getInteriorPoint(),
};
};
const heightFunction = (feature) => feature.get("nb") * 20 || 0;
</script>
Vector3DLayer
<template>
<slot></slot>
</template>
<script setup>
import { ref, onMounted, provide, defineExpose } from "vue";
import Vector3D from "ol-ext/layer/Render3D";
// Define props
const props = defineProps({
source: Object, // Data source (VectorSource)
style: Function, // Style function for the features
height: Function, // Function to determine the height of features
});
const layer = ref(null);
onMounted(() => {
// Create the Vector3D layer
layer.value = new Vector3D({
source: props.source,
styler: function (feature) {
// Pass the style function from props
return props.style ? props.style(feature) : null;
},
height: function (feature) {
// Pass the height function from props
return props.height ? props.height(feature) : 0;
},
});
// Define layer_ if necessary
layer.value.layer_ = layer.value;
// Provide the layer via provide for usage in other components
provide("vectorLayer", layer.value);
});
// Expose the layer for external use
defineExpose({
vectorLayer: layer,
});
</script>
Metadata
Metadata
Assignees
Labels
No labels