2016-09-08 21:42:18 +02:00
|
|
|
import React from 'react';
|
2016-09-10 21:29:18 +02:00
|
|
|
import Immutable from 'immutable'
|
|
|
|
import spec from 'mapbox-gl-style-spec/reference/latest.min.js'
|
|
|
|
import diffJSONStyles from 'mapbox-gl-style-spec/lib/diff'
|
2016-09-09 18:53:57 +02:00
|
|
|
import randomColor from 'randomcolor'
|
|
|
|
|
2016-09-10 21:29:18 +02:00
|
|
|
// Standard JSON to Immutable conversion except layers
|
|
|
|
// are stored in an OrderedMap to make lookups id fast
|
|
|
|
// It also ensures that every style has an id and
|
|
|
|
// a created date for future reference
|
|
|
|
function fromJSON(jsonStyle) {
|
|
|
|
if (typeof jsonStyle === 'string' || jsonStyle instanceof String) {
|
|
|
|
jsonStyle = JSON.parse(jsonStyle)
|
|
|
|
}
|
|
|
|
|
2016-09-20 16:49:02 +02:00
|
|
|
return Immutable.Map(Object.keys(jsonStyle).map(key => {
|
2016-09-10 21:29:18 +02:00
|
|
|
const val = jsonStyle[key]
|
|
|
|
if(key === "layers") {
|
|
|
|
return [key, Immutable.OrderedMap(val.map(l => [l.id, Immutable.fromJS(l)]))]
|
|
|
|
} else if(key === "sources" || key === "metadata" || key === "transition") {
|
2016-09-10 22:08:26 +02:00
|
|
|
return [key, Immutable.fromJS(val)]
|
2016-09-10 21:29:18 +02:00
|
|
|
} else {
|
|
|
|
return [key, val]
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2016-09-20 16:49:02 +02:00
|
|
|
function ensureHasId(style) {
|
|
|
|
if(style.has('id')) return style
|
|
|
|
return style.set('id', Math.random().toString(36).substr(2, 9))
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureHasTimestamp(style) {
|
|
|
|
if(style.has('id')) return style
|
|
|
|
return style.set('created', new Date().toJSON())
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureMetadataExists(style) {
|
|
|
|
return ensureHasId(ensureHasTimestamp(style))
|
|
|
|
}
|
|
|
|
|
2016-09-10 21:29:18 +02:00
|
|
|
// Compare style with other style and return changes
|
|
|
|
//TODO: Write own diff algo that operates on immutable collections
|
|
|
|
// Should be able to improve performance since we can only compare
|
|
|
|
// by reference
|
|
|
|
function diffStyles(before, after) {
|
|
|
|
return diffJSONStyles(toJSON(before), toJSON(after))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Turns immutable style back into JSON with the original order of the
|
|
|
|
// layers preserved
|
|
|
|
function toJSON(mapStyle) {
|
|
|
|
const jsonStyle = {}
|
|
|
|
for(let [key, value] of mapStyle.entries()) {
|
|
|
|
if(key === "layers") {
|
|
|
|
jsonStyle[key] = value.toIndexedSeq().toJS()
|
|
|
|
} else if(key === 'sources' || key === "metadata" || key === "transition") {
|
|
|
|
jsonStyle[key] = value.toJS()
|
|
|
|
} else {
|
|
|
|
jsonStyle[key] = value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return jsonStyle
|
|
|
|
}
|
|
|
|
|
2016-09-09 23:25:06 +02:00
|
|
|
export function colorizeLayers(layers) {
|
2016-09-09 18:53:57 +02:00
|
|
|
return layers.map(layer => {
|
|
|
|
if(!layer.metadata) {
|
|
|
|
layer.metadata = {}
|
|
|
|
}
|
2016-09-20 13:51:54 +02:00
|
|
|
if(!"maputnik:color" in layer.metadata) {
|
|
|
|
layer.metadata["maputnik:color"] = randomColor()
|
2016-09-09 18:53:57 +02:00
|
|
|
}
|
|
|
|
return layer
|
|
|
|
})
|
|
|
|
}
|
2016-09-10 21:29:18 +02:00
|
|
|
|
|
|
|
export default {
|
|
|
|
colorizeLayers,
|
|
|
|
toJSON,
|
|
|
|
fromJSON,
|
|
|
|
diffStyles,
|
2016-09-20 16:49:02 +02:00
|
|
|
ensureMetadataExists,
|
2016-09-10 21:29:18 +02:00
|
|
|
}
|