Skip to content

Commit

Permalink
wip: Improve map styling #816
Browse files Browse the repository at this point in the history
  • Loading branch information
cnouguier committed Jan 30, 2024
1 parent 89884bd commit 8af3d28
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 78 deletions.
5 changes: 3 additions & 2 deletions map/client/components/KTimezoneMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { api, utils as kCoreUtils } from '../../../core/client'
import * as mapMixins from '../mixins/map'
import * as mixins from '../mixins'
import { useCatalog, useCurrentActivity } from '../composables'
import { convertToLeafletFromSimpleStyleSpec, createLeafletMarkerFromStyle } from '../leaflet/utils/index.js'
import meta from 'moment-timezone/data/meta/latest.json'
// Convert timezones to GeoJson
Expand Down Expand Up @@ -75,8 +76,8 @@ export default {
},
getTimezoneMarker (feature, latlng) {
const isSelected = (this.timezone === feature.properties.name)
return this.createMarkerFromStyle(latlng,
this.convertFromSimpleStyleSpec({
return createLeafletMarkerFromStyle(latlng,
convertToLeafletFromSimpleStyleSpec({
'marker-type': 'circleMarker',
radius: isSelected ? 8 : 5,
'stroke-color': getCssVar('primary'),
Expand Down
54 changes: 54 additions & 0 deletions map/client/leaflet/utils/utils.style.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import _ from 'lodash'
import chroma from 'chroma-js'
import moment from 'moment'
import L from 'leaflet'
import { Time, Units } from '../../../../core/client/index.js'
import { ShapeMarker } from '../ShapeMarker.js'

L.shapeMarker = function (latlng, options) {
Expand Down Expand Up @@ -109,3 +112,54 @@ export function convertToLeafletFromSimpleStyleSpec (style, inPlace) {
if (_.has(convertedStyle, 'shadowPane')) _.set(convertedStyle, 'shadowPane', _.get(convertedStyle, 'shadowPane').toString())
return convertedStyle
}

export function getDefaultMarker (feature, latlng, options) {
const properties = feature.properties
const leafletOptions = options.leaflet || options
const style = Object.assign({},
_.get(this, 'activityOptions.engine.pointStyle'),
leafletOptions.layerStyle,
convertToLeafletFromSimpleStyleSpec(feature.style || feature.properties))
// We allow to template style properties according to feature,
// because it can be slow you have to specify a subset of properties
const context = { properties, feature, chroma, moment, Units, Time }
if (leafletOptions.template) {
// Create the map of variables
if (options.variables) context.variables = _.reduce(options.variables,
(result, variable) => Object.assign(result, { [variable.name]: variable }), {})
leafletOptions.template.forEach(entry => {
// Perform templating, set using simple spec mapping first then raw if property not found
_.set(style, _.get(LeafletStyleMappings, entry.property, entry.property), entry.compiler(context))
})
}
// We manage panes for z-index, so we need to forward it to marker options (only if not already defined)
if (leafletOptions.pane && !style.pane) style.pane = leafletOptions.pane
if (leafletOptions.shadowPane && !style.shadowPane) style.shadowPane = leafletOptions.shadowPane
return (latlng ? createLeafletMarkerFromStyle(latlng, style) : style)
}

export function getDefaultStyle (feature, options) {
const properties = feature.properties
const leafletOptions = options.leaflet || options
const style = Object.assign({},
_.get(this, 'activityOptions.engine.featureStyle'),
leafletOptions.layerStyle,
convertToLeafletFromSimpleStyleSpec(feature.style || feature.properties))

// We allow to template style properties according to feature,
// because it can be slow you have to specify a subset of properties
const context = { properties, feature, chroma, moment, Units, Time }
if (leafletOptions.template) {
// Create the map of variables
if (options.variables) context.variables = _.reduce(options.variables,
(result, variable) => Object.assign(result, { [variable.name]: variable }), {})
leafletOptions.template.forEach(entry => {
// Perform templating, set using simple spec mapping first then raw if property not found
_.set(style, _.get(LeafletStyleMappings, entry.property, entry.property), entry.compiler(context))
})
}
// We manage panes for z-index, so we need to forward it to marker options (only if not already defined)
if (leafletOptions.pane && !style.pane) style.pane = leafletOptions.pane
if (leafletOptions.shadowPane && !style.shadowPane) style.shadowPane = leafletOptions.shadowPane
return style
}
7 changes: 4 additions & 3 deletions map/client/mixins/globe/mixin.geojson-layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import _ from 'lodash'
import logger from 'loglevel'
import sift from 'sift'
import { Time } from '../../../../core/client/time.js'
import { convertToLeafletFromSimpleStyleSpec } from '../../leaflet/utils/index.js'
import { fetchGeoJson, getFeatureId, isInMemoryLayer } from '../../utils.js'

export const geojsonLayers = {
methods: {
convertFromSimpleStyleSpecOrDefaults (properties) {
let { stroke, strokeWidth, fill } = this.convertFromSimpleStyleSpec(properties)
let { stroke, strokeWidth, fill } = convertToLeafletFromSimpleStyleSpec(properties)
if (!stroke) stroke = Cesium.GeoJsonDataSource.stroke
if (!strokeWidth) strokeWidth = Cesium.GeoJsonDataSource.strokeWidth
if (!fill) fill = Cesium.GeoJsonDataSource.fill
Expand Down Expand Up @@ -191,7 +192,7 @@ export const geojsonLayers = {
if (tooltipTemplate) {
cesiumOptions.tooltip.compiler = _.template(tooltipTemplate)
}
this.convertFromSimpleStyleSpec(cesiumOptions, 'update-in-place')
convertToLeafletFromSimpleStyleSpec(cesiumOptions, 'update-in-place')
// Perform required conversion from JSON to Cesium objects
// If templating occurs we need to wait until it is performed to convert to Cesium objects
if (cesiumOptions.entityStyle && !entityStyleTemplate) cesiumOptions.entityStyle = this.convertToCesiumObjects(cesiumOptions.entityStyle)
Expand Down Expand Up @@ -305,7 +306,7 @@ export const geojsonLayers = {
// Perform required conversion from JSON to Cesium objects
if (_.has(this, 'activityOptions.engine.featureStyle')) {
Object.assign(Cesium.GeoJsonDataSource,
this.convertFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.featureStyle'), 'update-in-place'))
convertToLeafletFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.featureStyle'), 'update-in-place'))
}
this.$events.on('time-current-time-changed', this.onCurrentTimeChangedGeoJsonLayers)
this.$engineEvents.on('layer-shown', this.onLayerShownGeoJsonLayers)
Expand Down
8 changes: 4 additions & 4 deletions map/client/mixins/map/mixin.edit-layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import _ from 'lodash'
import L from 'leaflet'
import { getType, getGeom } from '@turf/invariant'
import { Dialog, uid } from 'quasar'
import { bindLeafletEvents, unbindLeafletEvents } from '../../utils.map.js'
import { bindLeafletEvents, unbindLeafletEvents, convertToLeafletFromSimpleStyleSpec, createLeafletMarkerFromStyle } from '../../utils.map.js'

// Events we listen while layer is in edition mode
const mapEditEvents = ['pm:create']
Expand Down Expand Up @@ -72,7 +72,7 @@ export const editLayers = {
_.get(this, 'activityOptions.engine.editFeatureStyle', _.get(this, 'activityOptions.engine.featureStyle')))
},
pointToLayer: (feature, latlng) => {
return this.createMarkerFromStyle(latlng, Object.assign({ pmIgnore: false }, // Allow geoman edition
return createLeafletMarkerFromStyle(latlng, Object.assign({ pmIgnore: false }, // Allow geoman edition
_.get(this, 'activityOptions.engine.editPointStyle', _.get(this, 'activityOptions.engine.pointStyle'))))
}
}
Expand Down Expand Up @@ -484,10 +484,10 @@ export const editLayers = {
beforeMount () {
// Perform required conversion for default feature styling
if (_.has(this, 'activityOptions.engine.editFeatureStyle')) {
this.convertFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.editFeatureStyle'), 'update-in-place')
convertToLeafletFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.editFeatureStyle'), 'update-in-place')
}
if (_.has(this, 'activityOptions.engine.editPointStyle')) {
this.convertFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.editPointStyle'), 'update-in-place')
convertToLeafletFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.editPointStyle'), 'update-in-place')
}
}
}
4 changes: 2 additions & 2 deletions map/client/mixins/map/mixin.geojson-layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Time, utils as kdkCoreUtils } from '../../../../core.client.js'
import { GradientPath } from '../../leaflet/GradientPath.js'
import { MaskLayer } from '../../leaflet/MaskLayer.js'
import { TiledFeatureLayer } from '../../leaflet/TiledFeatureLayer.js'
import { fetchGeoJson, LeafletEvents, bindLeafletEvents, unbindLeafletEvents, getFeatureId, isInMemoryLayer } from '../../utils.map.js'
import { fetchGeoJson, LeafletEvents, bindLeafletEvents, unbindLeafletEvents, getFeatureId, isInMemoryLayer, convertToLeafletFromSimpleStyleSpec } from '../../utils.map.js'
import * as wfs from '../../../common/wfs-utils.js'

// Override default remove handler for leaflet-realtime due to
Expand Down Expand Up @@ -307,7 +307,7 @@ export const geojsonLayers = {
// If layer provided do not override
if (!_.has(leafletOptions, key)) _.set(leafletOptions, key, _.get(geoJsonOptions, key))
})
leafletOptions.layerStyle = this.convertFromSimpleStyleSpec(leafletOptions)
leafletOptions.layerStyle = convertToLeafletFromSimpleStyleSpec(leafletOptions)
let layer = this.createLeafletLayer(options)

// Specific case of realtime layer where the underlying container also need to be added to map
Expand Down
72 changes: 5 additions & 67 deletions map/client/mixins/map/mixin.style.js
Original file line number Diff line number Diff line change
@@ -1,81 +1,19 @@
import _ from 'lodash'
import chroma from 'chroma-js'
import moment from 'moment'
import { Time, Units } from '../../../../core/client/index.js'
import { createLeafletMarkerFromStyle, convertToLeafletFromSimpleStyleSpec, LeafletStyleMappings } from '../../utils.map.js'
import { getDefaultMarker, getDefaultStyle, convertToLeafletFromSimpleStyleSpec } from '../../utils.map.js'

export const style = {
methods: {
// Alias to ease development
createMarkerFromStyle (latlng, markerStyle, feature) {
return createLeafletMarkerFromStyle(latlng, markerStyle, feature)
},
// Alias to ease development
convertFromSimpleStyleSpec (style, inPlace) {
return convertToLeafletFromSimpleStyleSpec(style, inPlace)
},
getDefaultMarker (feature, latlng, options) {
const properties = feature.properties
const leafletOptions = options.leaflet || options
const style = Object.assign({},
_.get(this, 'activityOptions.engine.pointStyle'),
leafletOptions.layerStyle,
this.convertFromSimpleStyleSpec(feature.style || feature.properties))
// We allow to template style properties according to feature,
// because it can be slow you have to specify a subset of properties
const context = { properties, feature, chroma, moment, Units, Time }
if (leafletOptions.template) {
// Create the map of variables
if (options.variables) context.variables = _.reduce(options.variables,
(result, variable) => Object.assign(result, { [variable.name]: variable }), {})
leafletOptions.template.forEach(entry => {
// Perform templating, set using simple spec mapping first then raw if property not found
_.set(style, _.get(LeafletStyleMappings, entry.property, entry.property), entry.compiler(context))
})
}
// We manage panes for z-index, so we need to forward it to marker options (only if not already defined)
if (leafletOptions.pane && !style.pane) style.pane = leafletOptions.pane
if (leafletOptions.shadowPane && !style.shadowPane) style.shadowPane = leafletOptions.shadowPane
return (latlng ? this.createMarkerFromStyle(latlng, style) : style)
},
getDefaultStyle (feature, options) {
const properties = feature.properties
const leafletOptions = options.leaflet || options
const style = Object.assign({},
_.get(this, 'activityOptions.engine.featureStyle'),
leafletOptions.layerStyle,
this.convertFromSimpleStyleSpec(feature.style || feature.properties))

// We allow to template style properties according to feature,
// because it can be slow you have to specify a subset of properties
const context = { properties, feature, chroma, moment, Units, Time }
if (leafletOptions.template) {
// Create the map of variables
if (options.variables) context.variables = _.reduce(options.variables,
(result, variable) => Object.assign(result, { [variable.name]: variable }), {})
leafletOptions.template.forEach(entry => {
// Perform templating, set using simple spec mapping first then raw if property not found
_.set(style, _.get(LeafletStyleMappings, entry.property, entry.property), entry.compiler(context))
})
}
// We manage panes for z-index, so we need to forward it to marker options (only if not already defined)
if (leafletOptions.pane && !style.pane) style.pane = leafletOptions.pane
if (leafletOptions.shadowPane && !style.shadowPane) style.shadowPane = leafletOptions.shadowPane
return style
}
},
created () {
this.registerStyle('markerStyle', this.getDefaultMarker)
this.registerStyle('featureStyle', this.getDefaultStyle)
this.registerStyle('markerStyle', getDefaultMarker)
this.registerStyle('featureStyle',getDefaultStyle)
},
// Need to be done after created as the activity mixin initializes options in it
beforeMount () {
// Perform required conversion for default feature styling
if (_.has(this, 'activityOptions.engine.featureStyle')) {
this.convertFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.featureStyle'), 'update-in-place')
convertToLeafletFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.featureStyle'), 'update-in-place')
}
if (_.has(this, 'activityOptions.engine.pointStyle')) {
this.convertFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.pointStyle'), 'update-in-place')
convertToLeafletFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.pointStyle'), 'update-in-place')
}
}
}

0 comments on commit 8af3d28

Please sign in to comment.