-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BGDIINF_SB-2980: Add GeoJSON layer component for 3d
BGDIINF_SB-2980: Add GeoJSON layer component for 3d
- Loading branch information
1 parent
e9fc97f
commit 7a2cc91
Showing
8 changed files
with
256 additions
and
37 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
src/modules/map/components/cesium/CesiumGeoJSONLayer.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
<template> | ||
<div> | ||
<slot /> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
import { PrimitiveCollection } from 'cesium' | ||
import axios from 'axios' | ||
import OlStyleForPropertyValue from '@/modules/map/components/openlayers/utils/styleFromLiterals' | ||
import FeatureConverter from 'ol-cesium/src/olcs/FeatureConverter' | ||
import GeoJSON from 'ol/format/GeoJSON' | ||
import { Vector as VectorLayer } from 'ol/layer' | ||
import { Vector as VectorSource } from 'ol/source' | ||
import { updateCollectionOpacity } from '@/modules/map/components/cesium/utils/geoJsonUtils' | ||
import addLayerToViewer from '@/modules/map/components/cesium/utils/addLayerToViewer-mixins' | ||
import log from '@/utils/logging' | ||
const STYLE_RESOLUTION = 100 | ||
/** Adds a GeoJSON layer to the Cesium viewer */ | ||
export default { | ||
mixins: [addLayerToViewer], | ||
props: { | ||
layerId: { | ||
type: String, | ||
required: true, | ||
}, | ||
geojsonUrl: { | ||
type: String, | ||
required: true, | ||
}, | ||
styleUrl: { | ||
type: String, | ||
required: true, | ||
}, | ||
opacity: { | ||
type: Number, | ||
default: 0.9, | ||
}, | ||
}, | ||
methods: { | ||
addLayer(layer) { | ||
this.getViewer().scene.primitives.add(layer) | ||
this.isPresentOnMap = true | ||
}, | ||
removeLayer(layer) { | ||
const viewer = this.getViewer() | ||
layer.removeAll() | ||
viewer.scene.primitives.remove(layer) | ||
viewer.scene.requestRender() | ||
this.isPresentOnMap = false | ||
}, | ||
}, | ||
watch: { | ||
opacity(newOpacity) { | ||
updateCollectionOpacity(this.layer, newOpacity) | ||
this.getViewer().scene.requestRender() | ||
}, | ||
}, | ||
created() { | ||
const scene = this.getViewer().scene | ||
this.layer = new PrimitiveCollection() | ||
const featureConverter = new FeatureConverter(scene) | ||
const olLayer = new VectorLayer({ | ||
id: this.layerId, | ||
opacity: this.opacity, | ||
properties: { altitudeMode: 'relativeToGround' }, | ||
}) | ||
Promise.all([axios.get(this.geojsonUrl), axios.get(this.styleUrl)]) | ||
.then((responses) => { | ||
const geojsonData = responses[0].data | ||
const geojsonStyleLiterals = responses[1].data | ||
const style = new OlStyleForPropertyValue(geojsonStyleLiterals) | ||
olLayer.setSource( | ||
new VectorSource({ | ||
features: new GeoJSON().readFeatures(geojsonData), | ||
}) | ||
) | ||
olLayer.setStyle(function (feature, res) { | ||
return style.getFeatureStyle(feature, res) | ||
}) | ||
const counterpart = featureConverter.olVectorLayerToCesium( | ||
olLayer, | ||
{ | ||
getProjection: () => | ||
geojsonData.crs ? geojsonData.crs.properties.name : null, | ||
getResolution: () => STYLE_RESOLUTION, | ||
}, | ||
{} | ||
) | ||
// need to wait for terrain loaded otherwise primitives will be placed wrong | ||
if (this.layer) { | ||
if (scene.globe.tilesLoaded) { | ||
this.layer.add(counterpart.getRootPrimitive()) | ||
updateCollectionOpacity(this.layer, this.opacity) | ||
this.getViewer().scene.requestRender() | ||
} else { | ||
const unlisten = scene.globe.tileLoadProgressEvent.addEventListener( | ||
(queueLength) => { | ||
if (scene.globe.tilesLoaded && queueLength === 0) { | ||
this.layer.add(counterpart.getRootPrimitive()) | ||
updateCollectionOpacity(this.layer, this.opacity) | ||
this.getViewer().scene.requestRender() | ||
unlisten() | ||
} | ||
} | ||
) | ||
} | ||
} | ||
}) | ||
.catch((error) => { | ||
log.error( | ||
'Error while fetching GeoJSON data/style for layer ' + this.layerId, | ||
error | ||
) | ||
}) | ||
}, | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
src/modules/map/components/cesium/utils/addLayerToViewer-mixins.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Vue mixin that will handle the addition or removal of a Cesium layer. | ||
* | ||
* Each component that uses this mixin must create a layer (`this.layer`) and next methods: | ||
* | ||
* - `addLayer` that gets `layer` and `zIndex` (optional) as properties | ||
* - `removeLayer` that gets `layer` as property | ||
*/ | ||
const addLayerToViewer = { | ||
inject: ['getViewer'], | ||
data() { | ||
return { | ||
isPresentOnMap: false, | ||
} | ||
}, | ||
mounted() { | ||
if (this.layer && !this.isPresentOnMap) { | ||
this.addLayer(this.layer, this.zIndex) | ||
} | ||
}, | ||
unmounted() { | ||
if (this.layer && this.isPresentOnMap) { | ||
this.removeLayer(this.layer) | ||
} | ||
|
||
delete this.layer | ||
}, | ||
} | ||
|
||
export default addLayerToViewer |
Oops, something went wrong.