diff --git a/docs/API.md b/docs/API.md index 79695e808..439c4541c 100644 --- a/docs/API.md +++ b/docs/API.md @@ -525,15 +525,11 @@ Draw uses a map style that adheres to the [Mapbox GL Style Spec](https://www.map **source** -The GL Style Spec requires each layer to have a source. However, **do not provide a `source`** when styling Draw. - -Draw moves features between sources in order to fine-tune performance. Because of this, **Draw will provide a `source` for you automatically**. - -The `source`s that Draw provides are named `mapbox-gl-draw-hot` and `mapbox-gl-draw-cold`. +The GL Style Spec requires each layer to have a source. However, **do not provide a `source`** when styling Draw. **Draw will provide a `source` for you automatically**. The `source` that Draw provides is named `mapbox-gl-draw`. **id** -The GL Style Spec also requires an id. **You must provide an id**. Draw will then add the suffixes `.hot` and `.cold` to your id. +The GL Style Spec also requires an id. **You must provide an id**. In your custom style, you will want to use the following feature properties: diff --git a/src/constants.js b/src/constants.js index 14cc3516f..08f268790 100644 --- a/src/constants.js +++ b/src/constants.js @@ -14,10 +14,7 @@ export const classes = { BOX_SELECT: 'mapbox-gl-draw_boxselect' }; -export const sources = { - HOT: 'mapbox-gl-draw-hot', - COLD: 'mapbox-gl-draw-cold' -}; +export const SOURCE = 'mapbox-gl-draw'; export const cursors = { ADD: 'add', diff --git a/src/options.js b/src/options.js index 720aa351a..89a056ca6 100644 --- a/src/options.js +++ b/src/options.js @@ -36,12 +36,12 @@ const hideControls = { uncombine_features: false }; -function addSources(styles, sourceBucket) { +function addSources(styles) { return styles.map((style) => { if (style.source) return style; return xtend(style, { - id: `${style.id}.${sourceBucket}`, - source: (sourceBucket === 'hot') ? Constants.sources.HOT : Constants.sources.COLD + id: `${style.id}`, + source: Constants.SOURCE }); }); } @@ -62,7 +62,7 @@ export default function(options = {}) { withDefaults = xtend(defaultOptions, withDefaults); // Layers with a shared source should be adjacent for performance reasons - withDefaults.styles = addSources(withDefaults.styles, 'cold').concat(addSources(withDefaults.styles, 'hot')); + withDefaults.styles = addSources(withDefaults.styles); return withDefaults; } diff --git a/src/render.js b/src/render.js index fffe0cdb3..3e9e87d84 100644 --- a/src/render.js +++ b/src/render.js @@ -3,54 +3,36 @@ import * as Constants from './constants'; export default function render() { // eslint-disable-next-line no-invalid-this const store = this; - const mapExists = store.ctx.map && store.ctx.map.getSource(Constants.sources.HOT) !== undefined; + const mapExists = store.ctx.map && store.ctx.map.getSource(Constants.SOURCE) !== undefined; if (!mapExists) return cleanup(); const mode = store.ctx.events.currentModeName(); store.ctx.ui.queueMapClasses({ mode }); - let newHotIds = []; - let newColdIds = []; + const newIds = store.getAllIds(); - if (store.isDirty) { - newColdIds = store.getAllIds(); - } else { - newHotIds = store.getChangedIds().filter(id => store.get(id) !== undefined); - newColdIds = store.sources.hot.filter(geojson => geojson.properties.id && newHotIds.indexOf(geojson.properties.id) === -1 && store.get(geojson.properties.id) !== undefined).map(geojson => geojson.properties.id); - } - - store.sources.hot = []; - const lastColdCount = store.sources.cold.length; - store.sources.cold = store.isDirty ? [] : store.sources.cold.filter((geojson) => { - const id = geojson.properties.id || geojson.properties.parent; - return newHotIds.indexOf(id) === -1; - }); + const lastCount = store.source.length; + store.source = []; - const coldChanged = lastColdCount !== store.sources.cold.length || newColdIds.length > 0; - newHotIds.forEach(id => renderFeature(id, 'hot')); - newColdIds.forEach(id => renderFeature(id, 'cold')); + const changed = lastCount !== store.source.length || newIds.length > 0; + newIds.forEach(id => renderFeature(id)); - function renderFeature(id, source) { + function renderFeature(id) { const feature = store.get(id); const featureInternal = feature.internal(mode); store.ctx.events.currentModeRender(featureInternal, (geojson) => { - store.sources[source].push(geojson); + store.source.push(geojson); }); } - if (coldChanged) { - store.ctx.map.getSource(Constants.sources.COLD).setData({ + if (changed) { + store.ctx.map.getSource(Constants.SOURCE).setData({ type: Constants.geojsonTypes.FEATURE_COLLECTION, - features: store.sources.cold + features: store.source }); } - store.ctx.map.getSource(Constants.sources.HOT).setData({ - type: Constants.geojsonTypes.FEATURE_COLLECTION, - features: store.sources.hot - }); - if (store._emitSelectionChange) { store.ctx.map.fire(Constants.events.SELECTION_CHANGE, { features: store.getSelected().map(feature => feature.toGeoJSON()), diff --git a/src/setup.js b/src/setup.js index be977b8be..d04afc08c 100644 --- a/src/setup.js +++ b/src/setup.js @@ -84,16 +84,7 @@ export default function(ctx) { }, addLayers() { // drawn features style - ctx.map.addSource(Constants.sources.COLD, { - data: { - type: Constants.geojsonTypes.FEATURE_COLLECTION, - features: [] - }, - type: 'geojson' - }); - - // hot features style - ctx.map.addSource(Constants.sources.HOT, { + ctx.map.addSource(Constants.SOURCE, { data: { type: Constants.geojsonTypes.FEATURE_COLLECTION, features: [] @@ -117,12 +108,8 @@ export default function(ctx) { } }); - if (ctx.map.getSource(Constants.sources.COLD)) { - ctx.map.removeSource(Constants.sources.COLD); - } - - if (ctx.map.getSource(Constants.sources.HOT)) { - ctx.map.removeSource(Constants.sources.HOT); + if (ctx.map.getSource(Constants.SOURCE)) { + ctx.map.removeSource(Constants.SOURCE); } } }; diff --git a/src/store.js b/src/store.js index c1106ed3b..ea93422ef 100644 --- a/src/store.js +++ b/src/store.js @@ -13,10 +13,7 @@ export default function Store(ctx) { this._emitSelectionChange = false; this._mapInitialConfig = {}; this.ctx = ctx; - this.sources = { - hot: [], - cold: [] - }; + this.source = []; // Deduplicate requests to render and tie them to animation frames. let renderRequest; diff --git a/test/fixtures/style_with_sources.json b/test/fixtures/style_with_sources.json index 91e88b0ad..00b857a95 100644 --- a/test/fixtures/style_with_sources.json +++ b/test/fixtures/style_with_sources.json @@ -1 +1 @@ -[{"id":"gl-draw-polygon-fill-inactive.cold","type":"fill","filter":["all",["==","active","false"],["==","$type","Polygon"],["!=","mode","static"]],"paint":{"fill-color":"#3bb2d0","fill-outline-color":"#3bb2d0","fill-opacity":0.1},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-polygon-fill-active.cold","type":"fill","filter":["all",["==","active","true"],["==","$type","Polygon"]],"paint":{"fill-color":"#fbb03b","fill-outline-color":"#fbb03b","fill-opacity":0.1},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-polygon-midpoint.cold","type":"circle","filter":["all",["==","$type","Point"],["==","meta","midpoint"]],"paint":{"circle-radius":3,"circle-color":"#fbb03b"},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-polygon-stroke-inactive.cold","type":"line","filter":["all",["==","active","false"],["==","$type","Polygon"],["!=","mode","static"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#3bb2d0","line-width":2},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-polygon-stroke-active.cold","type":"line","filter":["all",["==","active","true"],["==","$type","Polygon"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#fbb03b","line-dasharray":[0.2,2],"line-width":2},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-line-inactive.cold","type":"line","filter":["all",["==","active","false"],["==","$type","LineString"],["!=","mode","static"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#3bb2d0","line-width":2},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-line-active.cold","type":"line","filter":["all",["==","$type","LineString"],["==","active","true"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#fbb03b","line-dasharray":[0.2,2],"line-width":2},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-polygon-and-line-vertex-stroke-inactive.cold","type":"circle","filter":["all",["==","meta","vertex"],["==","$type","Point"],["!=","mode","static"]],"paint":{"circle-radius":5,"circle-color":"#fff"},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-polygon-and-line-vertex-inactive.cold","type":"circle","filter":["all",["==","meta","vertex"],["==","$type","Point"],["!=","mode","static"]],"paint":{"circle-radius":3,"circle-color":"#fbb03b"},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-point-point-stroke-inactive.cold","type":"circle","filter":["all",["==","active","false"],["==","$type","Point"],["==","meta","feature"],["!=","mode","static"]],"paint":{"circle-radius":5,"circle-opacity":1,"circle-color":"#fff"},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-point-inactive.cold","type":"circle","filter":["all",["==","active","false"],["==","$type","Point"],["==","meta","feature"],["!=","mode","static"]],"paint":{"circle-radius":3,"circle-color":"#3bb2d0"},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-point-stroke-active.cold","type":"circle","filter":["all",["==","$type","Point"],["==","active","true"],["!=","meta","midpoint"]],"paint":{"circle-radius":7,"circle-color":"#fff"},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-point-active.cold","type":"circle","filter":["all",["==","$type","Point"],["!=","meta","midpoint"],["==","active","true"]],"paint":{"circle-radius":5,"circle-color":"#fbb03b"},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-polygon-fill-static.cold","type":"fill","filter":["all",["==","mode","static"],["==","$type","Polygon"]],"paint":{"fill-color":"#404040","fill-outline-color":"#404040","fill-opacity":0.1},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-polygon-stroke-static.cold","type":"line","filter":["all",["==","mode","static"],["==","$type","Polygon"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#404040","line-width":2},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-line-static.cold","type":"line","filter":["all",["==","mode","static"],["==","$type","LineString"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#404040","line-width":2},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-point-static.cold","type":"circle","filter":["all",["==","mode","static"],["==","$type","Point"]],"paint":{"circle-radius":5,"circle-color":"#404040"},"source":"mapbox-gl-draw-cold"},{"id":"gl-draw-polygon-fill-inactive.hot","type":"fill","filter":["all",["==","active","false"],["==","$type","Polygon"],["!=","mode","static"]],"paint":{"fill-color":"#3bb2d0","fill-outline-color":"#3bb2d0","fill-opacity":0.1},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-polygon-fill-active.hot","type":"fill","filter":["all",["==","active","true"],["==","$type","Polygon"]],"paint":{"fill-color":"#fbb03b","fill-outline-color":"#fbb03b","fill-opacity":0.1},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-polygon-midpoint.hot","type":"circle","filter":["all",["==","$type","Point"],["==","meta","midpoint"]],"paint":{"circle-radius":3,"circle-color":"#fbb03b"},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-polygon-stroke-inactive.hot","type":"line","filter":["all",["==","active","false"],["==","$type","Polygon"],["!=","mode","static"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#3bb2d0","line-width":2},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-polygon-stroke-active.hot","type":"line","filter":["all",["==","active","true"],["==","$type","Polygon"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#fbb03b","line-dasharray":[0.2,2],"line-width":2},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-line-inactive.hot","type":"line","filter":["all",["==","active","false"],["==","$type","LineString"],["!=","mode","static"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#3bb2d0","line-width":2},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-line-active.hot","type":"line","filter":["all",["==","$type","LineString"],["==","active","true"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#fbb03b","line-dasharray":[0.2,2],"line-width":2},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-polygon-and-line-vertex-stroke-inactive.hot","type":"circle","filter":["all",["==","meta","vertex"],["==","$type","Point"],["!=","mode","static"]],"paint":{"circle-radius":5,"circle-color":"#fff"},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-polygon-and-line-vertex-inactive.hot","type":"circle","filter":["all",["==","meta","vertex"],["==","$type","Point"],["!=","mode","static"]],"paint":{"circle-radius":3,"circle-color":"#fbb03b"},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-point-point-stroke-inactive.hot","type":"circle","filter":["all",["==","active","false"],["==","$type","Point"],["==","meta","feature"],["!=","mode","static"]],"paint":{"circle-radius":5,"circle-opacity":1,"circle-color":"#fff"},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-point-inactive.hot","type":"circle","filter":["all",["==","active","false"],["==","$type","Point"],["==","meta","feature"],["!=","mode","static"]],"paint":{"circle-radius":3,"circle-color":"#3bb2d0"},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-point-stroke-active.hot","type":"circle","filter":["all",["==","$type","Point"],["==","active","true"],["!=","meta","midpoint"]],"paint":{"circle-radius":7,"circle-color":"#fff"},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-point-active.hot","type":"circle","filter":["all",["==","$type","Point"],["!=","meta","midpoint"],["==","active","true"]],"paint":{"circle-radius":5,"circle-color":"#fbb03b"},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-polygon-fill-static.hot","type":"fill","filter":["all",["==","mode","static"],["==","$type","Polygon"]],"paint":{"fill-color":"#404040","fill-outline-color":"#404040","fill-opacity":0.1},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-polygon-stroke-static.hot","type":"line","filter":["all",["==","mode","static"],["==","$type","Polygon"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#404040","line-width":2},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-line-static.hot","type":"line","filter":["all",["==","mode","static"],["==","$type","LineString"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#404040","line-width":2},"source":"mapbox-gl-draw-hot"},{"id":"gl-draw-point-static.hot","type":"circle","filter":["all",["==","mode","static"],["==","$type","Point"]],"paint":{"circle-radius":5,"circle-color":"#404040"},"source":"mapbox-gl-draw-hot"}] +[{"id":"gl-draw-polygon-fill-inactive","type":"fill","filter":["all",["==","active","false"],["==","$type","Polygon"],["!=","mode","static"]],"paint":{"fill-color":"#3bb2d0","fill-outline-color":"#3bb2d0","fill-opacity":0.1},"source":"mapbox-gl-draw"},{"id":"gl-draw-polygon-fill-active","type":"fill","filter":["all",["==","active","true"],["==","$type","Polygon"]],"paint":{"fill-color":"#fbb03b","fill-outline-color":"#fbb03b","fill-opacity":0.1},"source":"mapbox-gl-draw"},{"id":"gl-draw-polygon-midpoint","type":"circle","filter":["all",["==","$type","Point"],["==","meta","midpoint"]],"paint":{"circle-radius":3,"circle-color":"#fbb03b"},"source":"mapbox-gl-draw"},{"id":"gl-draw-polygon-stroke-inactive","type":"line","filter":["all",["==","active","false"],["==","$type","Polygon"],["!=","mode","static"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#3bb2d0","line-width":2},"source":"mapbox-gl-draw"},{"id":"gl-draw-polygon-stroke-active","type":"line","filter":["all",["==","active","true"],["==","$type","Polygon"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#fbb03b","line-dasharray":[0.2,2],"line-width":2},"source":"mapbox-gl-draw"},{"id":"gl-draw-line-inactive","type":"line","filter":["all",["==","active","false"],["==","$type","LineString"],["!=","mode","static"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#3bb2d0","line-width":2},"source":"mapbox-gl-draw"},{"id":"gl-draw-line-active","type":"line","filter":["all",["==","$type","LineString"],["==","active","true"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#fbb03b","line-dasharray":[0.2,2],"line-width":2},"source":"mapbox-gl-draw"},{"id":"gl-draw-polygon-and-line-vertex-stroke-inactive","type":"circle","filter":["all",["==","meta","vertex"],["==","$type","Point"],["!=","mode","static"]],"paint":{"circle-radius":5,"circle-color":"#fff"},"source":"mapbox-gl-draw"},{"id":"gl-draw-polygon-and-line-vertex-inactive","type":"circle","filter":["all",["==","meta","vertex"],["==","$type","Point"],["!=","mode","static"]],"paint":{"circle-radius":3,"circle-color":"#fbb03b"},"source":"mapbox-gl-draw"},{"id":"gl-draw-point-point-stroke-inactive","type":"circle","filter":["all",["==","active","false"],["==","$type","Point"],["==","meta","feature"],["!=","mode","static"]],"paint":{"circle-radius":5,"circle-opacity":1,"circle-color":"#fff"},"source":"mapbox-gl-draw"},{"id":"gl-draw-point-inactive","type":"circle","filter":["all",["==","active","false"],["==","$type","Point"],["==","meta","feature"],["!=","mode","static"]],"paint":{"circle-radius":3,"circle-color":"#3bb2d0"},"source":"mapbox-gl-draw"},{"id":"gl-draw-point-stroke-active","type":"circle","filter":["all",["==","$type","Point"],["==","active","true"],["!=","meta","midpoint"]],"paint":{"circle-radius":7,"circle-color":"#fff"},"source":"mapbox-gl-draw"},{"id":"gl-draw-point-active","type":"circle","filter":["all",["==","$type","Point"],["!=","meta","midpoint"],["==","active","true"]],"paint":{"circle-radius":5,"circle-color":"#fbb03b"},"source":"mapbox-gl-draw"},{"id":"gl-draw-polygon-fill-static","type":"fill","filter":["all",["==","mode","static"],["==","$type","Polygon"]],"paint":{"fill-color":"#404040","fill-outline-color":"#404040","fill-opacity":0.1},"source":"mapbox-gl-draw"},{"id":"gl-draw-polygon-stroke-static","type":"line","filter":["all",["==","mode","static"],["==","$type","Polygon"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#404040","line-width":2},"source":"mapbox-gl-draw"},{"id":"gl-draw-line-static","type":"line","filter":["all",["==","mode","static"],["==","$type","LineString"]],"layout":{"line-cap":"round","line-join":"round"},"paint":{"line-color":"#404040","line-width":2},"source":"mapbox-gl-draw"},{"id":"gl-draw-point-static","type":"circle","filter":["all",["==","mode","static"],["==","$type","Point"]],"paint":{"circle-radius":5,"circle-color":"#404040"},"source":"mapbox-gl-draw"}] diff --git a/test/options.test.js b/test/options.test.js index 42e94fcaa..8c81e30a3 100644 --- a/test/options.test.js +++ b/test/options.test.js @@ -185,8 +185,8 @@ test('Options test', (t) => { const styles = [ { - 'id': 'custom-polygon.cold', - 'source': 'mapbox-gl-draw-cold', + 'id': 'custom-polygon', + 'source': 'mapbox-gl-draw', 'type': 'fill', 'filter': ['all', ['==', '$type', 'Polygon']], 'paint': { @@ -194,26 +194,8 @@ test('Options test', (t) => { } }, { - 'id': 'custom-point.cold', - 'source': 'mapbox-gl-draw-cold', - 'type': 'circle', - 'filter': ['all', ['==', '$type', 'Point']], - 'paint': { - 'circle-color': '#fff' - } - }, - { - 'id': 'custom-polygon.hot', - 'source': 'mapbox-gl-draw-hot', - 'type': 'fill', - 'filter': ['all', ['==', '$type', 'Polygon']], - 'paint': { - 'fill-color': '#fff' - } - }, - { - 'id': 'custom-point.hot', - 'source': 'mapbox-gl-draw-hot', + 'id': 'custom-point', + 'source': 'mapbox-gl-draw', 'type': 'circle', 'filter': ['all', ['==', '$type', 'Point']], 'paint': { diff --git a/test/store.test.js b/test/store.test.js index 118564e76..3778b8d65 100644 --- a/test/store.test.js +++ b/test/store.test.js @@ -22,10 +22,7 @@ test('Store constructor and public API', (t) => { const store = new Store(ctx); // instance members - t.deepEqual(store.sources, { - hot: [], - cold: [] - }, 'exposes store.sources'); + t.deepEqual(store.source, [], 'exposes store.source'); t.equal(store.ctx, ctx, 'exposes store.ctx'); t.equal(store.ctx.map, map, 'exposes store.ctx.map'); t.equal(store.isDirty, false, 'exposes store.isDirty');