From 321f3b044603a5ad0da09b1252d934f44575c9c2 Mon Sep 17 00:00:00 2001 From: Une Rosi Date: Wed, 1 Mar 2017 07:49:23 -0800 Subject: [PATCH] initial S2 layer (#378) * Add S2Layer * Fix sample-layers build --- examples/main/package.json | 10 +- examples/main/src/app.js | 3 +- .../main/src/layer-examples/sample-layers.js | 32 +- examples/main/webpack.config.js | 3 + examples/main/yarn.lock | 47 +- examples/sample-layers/data/index.js | 2 + examples/sample-layers/data/sf.s2cells.json | 523 ++++++++++++++++++ examples/sample-layers/package.json | 6 + examples/sample-layers/s2-layer/s2-layer.js | 92 +++ examples/sample-layers/s2-layer/s2-utils.js | 54 ++ src/lib/composite-layer.js | 4 + 11 files changed, 762 insertions(+), 14 deletions(-) create mode 100644 examples/sample-layers/data/index.js create mode 100644 examples/sample-layers/data/sf.s2cells.json create mode 100644 examples/sample-layers/package.json create mode 100644 examples/sample-layers/s2-layer/s2-layer.js create mode 100644 examples/sample-layers/s2-layer/s2-utils.js diff --git a/examples/main/package.json b/examples/main/package.json index e15cc5ba342..be60c8b40ad 100644 --- a/examples/main/package.json +++ b/examples/main/package.json @@ -1,16 +1,20 @@ { "scripts": { "start": "webpack-dev-server --progress --hot --open", - "start-local": "webpack-dev-server --env.local --progress --hot --open" + "start-local": "webpack-dev-server --env.local --progress --hot --open", + "build": "webpack app bundle.js --env.local --display-error-details" }, "dependencies": { - "deck.gl": "^4.0.0-beta.1", + "deck.gl": "^4.0.0-beta.3", + "extrude-polyline": "^1.0.6", "immutable": "^3.8.1", "luma.gl": "3.0.0-beta.9", "react": "^15.4.1", + "react-autobind": "^1.0.6", "react-dom": "^15.4.1", "react-map-gl": "1.7.2", - "react-stats": "^0.0.5" + "react-stats": "^0.0.5", + "s2-geometry": "^1.2.9" }, "devDependencies": { "buble-loader": "^0.4.0", diff --git a/examples/main/src/app.js b/examples/main/src/app.js index 0c27eee960e..d3267c8fff3 100644 --- a/examples/main/src/app.js +++ b/examples/main/src/app.js @@ -1,10 +1,11 @@ /* global window, document */ -import DeckGL, {autobind} from 'deck.gl/react'; +import DeckGL from 'deck.gl'; import {experimental} from 'deck.gl'; const {ReflectionEffect} = experimental; import React, {PureComponent} from 'react'; import ReactDOM from 'react-dom'; +import autobind from 'react-autobind'; import MapboxGLMap from 'react-map-gl'; import {FPSStats} from 'react-stats'; diff --git a/examples/main/src/layer-examples/sample-layers.js b/examples/main/src/layer-examples/sample-layers.js index b6aa1c155f0..8ebbf3c23fb 100644 --- a/examples/main/src/layer-examples/sample-layers.js +++ b/examples/main/src/layer-examples/sample-layers.js @@ -1,9 +1,9 @@ -import { - EnhancedChoroplethLayer, - TripsLayer -} from '../../../sample-layers'; +/* eslint-disable max-len */ +import * as mainDataSamples from '../data-samples'; +import * as extraDataSamples from '../../../sample-layers/data'; +const dataSamples = Object.assign({}, mainDataSamples, extraDataSamples); -import * as dataSamples from '../data-samples'; +import EnhancedChoroplethLayer from '../../../sample-layers/enhanced-choropleth-layer/enhanced-choropleth-layer'; const EnhancedChoroplethLayerExample = { layer: EnhancedChoroplethLayer, @@ -15,10 +15,12 @@ const EnhancedChoroplethLayerExample = { } }; +import TripsLayer from '../../../sample-layers/trips-layer/trips-layer'; + const TripsLayerExample = { layer: TripsLayer, props: { - id: 'trips-layer', + id: 'trips-layer ', data: dataSamples.trips, getPath: trip => trip.map(d => [ d.begin_shape[0], @@ -32,10 +34,26 @@ const TripsLayerExample = { } }; +import S2Layer from '../../../sample-layers/s2-layer/s2-layer'; + +const S2LayerExample = { + layer: S2Layer, + props: { + data: dataSamples.s2cells, + opacity: 0.6, + getS2Token: f => f.token, + getPath: f => f.path, + getFillColor: f => [f.value * 256, (1 - f.value) * 256, (1 - f.value) * 128], + getStrokeWidth: f => 10, + pickable: true + } +}; + /* eslint-disable quote-props */ export default { 'Sample Layers': { 'EnhancedChoroplethLayer': EnhancedChoroplethLayerExample, - 'TripsLayer': TripsLayerExample + 'TripsLayer': TripsLayerExample, + 'S2Layer': S2LayerExample } }; diff --git a/examples/main/webpack.config.js b/examples/main/webpack.config.js index b051b5f6820..cbdc1c6ca7f 100644 --- a/examples/main/webpack.config.js +++ b/examples/main/webpack.config.js @@ -13,6 +13,9 @@ module.exports = { devtool: 'inline-source-map', resolve: { + // Make src files outside of this dir resolve modules in our node_modules folder + modules: [resolve(__dirname, '.'), resolve(__dirname, 'node_modules'), 'node_modules'], + alias: { // From mapbox-gl-js README. Required for non-browserify bundlers (e.g. webpack): 'mapbox-gl$': resolve('./node_modules/mapbox-gl/dist/mapbox-gl.js') diff --git a/examples/main/yarn.lock b/examples/main/yarn.lock index 49a5fee7d8e..b9460c0a682 100644 --- a/examples/main/yarn.lock +++ b/examples/main/yarn.lock @@ -126,6 +126,10 @@ arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" +as-number@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/as-number/-/as-number-1.0.0.tgz#acb27e34f8f9d8ab0da9e376f3b8959860f80a66" + asap@~2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" @@ -644,6 +648,10 @@ d3-geo@^1.2.4: dependencies: d3-array "1" +d3-hexbin@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/d3-hexbin/-/d3-hexbin-0.2.1.tgz#24459c47c933b67ed38aecde43d9248f6e3e2001" + d3-interpolate@1: version "1.1.3" resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.3.tgz#e119c91b6be4941e581675ca3e1279bb92bd2c9b" @@ -696,10 +704,11 @@ decamelize@^1.0.0, decamelize@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" -deck.gl@^4.0.0-beta.1: - version "4.0.0-beta.1" - resolved "https://registry.yarnpkg.com/deck.gl/-/deck.gl-4.0.0-beta.1.tgz#e40e026b1849ead970e5ec15d5294773b689c0ad" +deck.gl@^4.0.0-beta.3: + version "4.0.0-beta.3" + resolved "https://registry.yarnpkg.com/deck.gl/-/deck.gl-4.0.0-beta.3.tgz#571e5f63ccb645fd0ea299d4ee8b2f85b2a5a854" dependencies: + d3-hexbin "^0.2.1" earcut "^2.0.6" file-loader "^0.9.0" gl-matrix "^2.3.2" @@ -979,6 +988,14 @@ extglob@^0.3.1: dependencies: is-extglob "^1.0.0" +extrude-polyline@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/extrude-polyline/-/extrude-polyline-1.0.6.tgz#7e6afe1f349a4182fa3f61a00d93979b95f18b20" + dependencies: + as-number "^1.0.0" + gl-vec2 "^1.0.0" + polyline-miter-util "^1.0.1" + extsprintf@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" @@ -1186,6 +1203,10 @@ gl-matrix@^2.3.1, gl-matrix@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-2.3.2.tgz#aac808c74af7d5db05fe04cb60ca1a0fcb174d74" +gl-vec2@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gl-vec2/-/gl-vec2-1.0.0.tgz#77fce6ae9612856d6c8b621cd261cd8281b9c637" + glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -1681,6 +1702,10 @@ lodash@^4.14.0, lodash@^4.17.2: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +long@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" + longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" @@ -2148,6 +2173,12 @@ point-geometry@0.0.0, point-geometry@^0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/point-geometry/-/point-geometry-0.0.0.tgz#6fcbcad7a803b6418247dd6e49c2853c584daff7" +polyline-miter-util@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/polyline-miter-util/-/polyline-miter-util-1.0.1.tgz#b693f2389ea0ded36a6bcf5ecd2ece4b6917d957" + dependencies: + gl-vec2 "^1.0.0" + portfinder@^1.0.9: version "1.0.13" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" @@ -2284,6 +2315,10 @@ rc@~1.1.6: minimist "^1.2.0" strip-json-comments "~1.0.4" +react-autobind@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/react-autobind/-/react-autobind-1.0.6.tgz#936bb58edf6b89b619c50f82f0e617159fdfd4f1" + react-dom@^15.4.1: version "15.4.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.4.2.tgz#015363f05b0a1fd52ae9efdd3a0060d90695208f" @@ -2471,6 +2506,12 @@ rw@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/rw/-/rw-0.1.4.tgz#4903cbd80248ae0ede685bf58fd236a7a9b29a3e" +s2-geometry@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/s2-geometry/-/s2-geometry-1.2.9.tgz#20c2eadc621322c0f5ebc5098fa614525031f1e4" + dependencies: + long "^3.2.0" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" diff --git a/examples/sample-layers/data/index.js b/examples/sample-layers/data/index.js new file mode 100644 index 00000000000..acf080ba215 --- /dev/null +++ b/examples/sample-layers/data/index.js @@ -0,0 +1,2 @@ +// Additional data for new layers +export {default as s2cells} from './sf.s2cells.json'; diff --git a/examples/sample-layers/data/sf.s2cells.json b/examples/sample-layers/data/sf.s2cells.json new file mode 100644 index 00000000000..5df5ab8f49c --- /dev/null +++ b/examples/sample-layers/data/sf.s2cells.json @@ -0,0 +1,523 @@ +[{ + "token": "80858004", + "value": 0.5979242952642347 +}, { + "token": "8085800c", + "value": 0.5446256069712141 +}, { + "token": "80858014", + "value": 0.1187171597109975 +}, { + "token": "8085801c", + "value": 0.2859146314037557 +}, { + "token": "80858024", + "value": 0.19549012367504126 +}, { + "token": "80858034", + "value": 0.3373452974230604 +}, { + "token": "8085803c", + "value": 0.9218176408795662 +}, { + "token": "80858044", + "value": 0.23470692356446143 +}, { + "token": "8085804c", + "value": 0.1580509670379684 +}, { + "token": "80858054", + "value": 0.15992745628743954 +}, { + "token": "8085805c", + "value": 0.08396995862593659 +}, { + "token": "80858064", + "value": 0.8528624994099137 +}, { + "token": "8085806c", + "value": 0.644205644051216 +}, { + "token": "80858074", + "value": 0.7327824575390218 +}, { + "token": "8085807c", + "value": 0.03206116368501655 +}, { + "token": "80858084", + "value": 0.13521469550102694 +}, { + "token": "8085808c", + "value": 0.8535530864046055 +}, { + "token": "80858094", + "value": 0.3021071656292911 +}, { + "token": "8085809c", + "value": 0.3145135386133331 +}, { + "token": "808580a4", + "value": 0.22221972654594113 +}, { + "token": "808580ac", + "value": 0.2089824755550702 +}, { + "token": "808580b4", + "value": 0.21568217472680673 +}, { + "token": "808580bc", + "value": 0.9930882437101516 +}, { + "token": "808580c4", + "value": 0.6771468010341937 +}, { + "token": "808580cc", + "value": 0.06254546149649509 +}, { + "token": "808580d4", + "value": 0.0898475989412637 +}, { + "token": "808580dc", + "value": 0.49162678093756096 +}, { + "token": "808580e4", + "value": 0.051892796689529286 +}, { + "token": "808580ec", + "value": 0.7656423773539729 +}, { + "token": "808580f4", + "value": 0.4176961681646778 +}, { + "token": "808580fc", + "value": 0.4764575762690464 +}, { + "token": "80858104", + "value": 0.875560663474253 +}, { + "token": "8085811c", + "value": 0.3209959013941124 +}, { + "token": "80858124", + "value": 0.9676094014498655 +}, { + "token": "8085812c", + "value": 0.8003506574355166 +}, { + "token": "80858134", + "value": 0.034891461780171884 +}, { + "token": "80858644", + "value": 0.8488347081373842 +}, { + "token": "8085864c", + "value": 0.5411597765580489 +}, { + "token": "80858654", + "value": 0.3020505133285931 +}, { + "token": "8085865c", + "value": 0.44053851810796885 +}, { + "token": "80858664", + "value": 0.018102931578807713 +}, { + "token": "8085866c", + "value": 0.4708610883744251 +}, { + "token": "80858674", + "value": 0.8445041920035186 +}, { + "token": "8085867c", + "value": 0.7392562454515113 +}, { + "token": "8085868c", + "value": 0.39347130067527725 +}, { + "token": "80858694", + "value": 0.44498309263850944 +}, { + "token": "808586bc", + "value": 0.7950865956130442 +}, { + "token": "808586c4", + "value": 0.7385232599770808 +}, { + "token": "808586cc", + "value": 0.018430696365115518 +}, { + "token": "808586d4", + "value": 0.6976876914703944 +}, { + "token": "808586dc", + "value": 0.25548321522154827 +}, { + "token": "808586e4", + "value": 0.41907812568703373 +}, { + "token": "808586ec", + "value": 0.7290899222794696 +}, { + "token": "808586f4", + "value": 0.4876522132550285 +}, { + "token": "808586fc", + "value": 0.9791814942123487 +}, { + "token": "80858704", + "value": 0.1564051237695645 +}, { + "token": "8085870c", + "value": 0.744495038306515 +}, { + "token": "80858714", + "value": 0.5636255749919985 +}, { + "token": "8085871c", + "value": 0.7177669940621756 +}, { + "token": "80858724", + "value": 0.935541364441353 +}, { + "token": "8085872c", + "value": 0.23813259699989464 +}, { + "token": "80858734", + "value": 0.20646398267504473 +}, { + "token": "8085873c", + "value": 0.2302231506207013 +}, { + "token": "80858744", + "value": 0.8146528937322526 +}, { + "token": "8085874c", + "value": 0.16250640847801878 +}, { + "token": "80858754", + "value": 0.8559251431793231 +}, { + "token": "8085875c", + "value": 0.5518084918736605 +}, { + "token": "80858764", + "value": 0.3724154636273309 +}, { + "token": "8085876c", + "value": 0.012832647697721411 +}, { + "token": "80858774", + "value": 0.5610069108638975 +}, { + "token": "8085877c", + "value": 0.4776581643572013 +}, { + "token": "80858784", + "value": 0.12728544885717574 +}, { + "token": "8085878c", + "value": 0.47893591531516466 +}, { + "token": "80858794", + "value": 0.3063337875935812 +}, { + "token": "8085879c", + "value": 0.9073800330927748 +}, { + "token": "808587a4", + "value": 0.5379301824132303 +}, { + "token": "808587ac", + "value": 0.011113123736386621 +}, { + "token": "808587b4", + "value": 0.33081342331714514 +}, { + "token": "808587bc", + "value": 0.16191641631003306 +}, { + "token": "808f78ac", + "value": 0.5216683954302226 +}, { + "token": "808f78b4", + "value": 0.5285279357501274 +}, { + "token": "808f7c24", + "value": 0.24964281774378816 +}, { + "token": "808f7c2c", + "value": 0.5328015885099198 +}, { + "token": "808f7c34", + "value": 0.5819767316967777 +}, { + "token": "808f7c3c", + "value": 0.5896441351697632 +}, { + "token": "808f7c44", + "value": 0.5765363622666126 +}, { + "token": "808f7c4c", + "value": 0.8149459687907068 +}, { + "token": "808f7c54", + "value": 0.12107787886389243 +}, { + "token": "808f7cfc", + "value": 0.8526502486482175 +}, { + "token": "808f7d04", + "value": 0.28623779830815255 +}, { + "token": "808f7d0c", + "value": 0.10419603053055027 +}, { + "token": "808f7d14", + "value": 0.2520231652562299 +}, { + "token": "808f7d1c", + "value": 0.8877852826515231 +}, { + "token": "808f7d64", + "value": 0.2516990408971258 +}, { + "token": "808f7d6c", + "value": 0.7886336898433268 +}, { + "token": "808f7d74", + "value": 0.3308357482421824 +}, { + "token": "808f7d7c", + "value": 0.9954698798360961 +}, { + "token": "808f7d84", + "value": 0.28199844123382434 +}, { + "token": "808f7d8c", + "value": 0.32430099417470504 +}, { + "token": "808f7d94", + "value": 0.5984402085884064 +}, { + "token": "808f7d9c", + "value": 0.6793472057782628 +}, { + "token": "808f7da4", + "value": 0.033929426787699724 +}, { + "token": "808f7dac", + "value": 0.7678834799175067 +}, { + "token": "808f7db4", + "value": 0.9941391037002041 +}, { + "token": "808f7dbc", + "value": 0.36675213183092303 +}, { + "token": "808f7dc4", + "value": 0.40066088856840576 +}, { + "token": "808f7dcc", + "value": 0.7263378406177063 +}, { + "token": "808f7dd4", + "value": 0.04477271874976996 +}, { + "token": "808f7ddc", + "value": 0.7104685877059944 +}, { + "token": "808f7de4", + "value": 0.13419724684085477 +}, { + "token": "808f7dec", + "value": 0.7547222857615965 +}, { + "token": "808f7df4", + "value": 0.9280683006322386 +}, { + "token": "808f7dfc", + "value": 0.8220141360591591 +}, { + "token": "808f7e04", + "value": 0.9963272967038985 +}, { + "token": "808f7e0c", + "value": 0.1555577515936848 +}, { + "token": "808f7e14", + "value": 0.5631111145510213 +}, { + "token": "808f7e1c", + "value": 0.48498738652813933 +}, { + "token": "808f7e24", + "value": 0.6390846622343107 +}, { + "token": "808f7e2c", + "value": 0.7713411346164771 +}, { + "token": "808f7e34", + "value": 0.30300925574785986 +}, { + "token": "808f7e3c", + "value": 0.558699849050589 +}, { + "token": "808f7e44", + "value": 0.09988990383867447 +}, { + "token": "808f7e4c", + "value": 0.3069067328730657 +}, { + "token": "808f7e54", + "value": 0.43128853083719343 +}, { + "token": "808f7e5c", + "value": 0.5928264763933375 +}, { + "token": "808f7e64", + "value": 0.16117572767428334 +}, { + "token": "808f7e6c", + "value": 0.230861193468473 +}, { + "token": "808f7e74", + "value": 0.2536209599928523 +}, { + "token": "808f7e7c", + "value": 0.6134003809540043 +}, { + "token": "808f7e84", + "value": 0.7833849551129455 +}, { + "token": "808f7e8c", + "value": 0.45498849941513386 +}, { + "token": "808f7e94", + "value": 0.08962987759426433 +}, { + "token": "808f7e9c", + "value": 0.005011873959296365 +}, { + "token": "808f7ea4", + "value": 0.5784665723163016 +}, { + "token": "808f7ebc", + "value": 0.5191309233303725 +}, { + "token": "808f7ec4", + "value": 0.39905530113616816 +}, { + "token": "808f7ed4", + "value": 0.13825169595521447 +}, { + "token": "808f7edc", + "value": 0.8204175340623787 +}, { + "token": "808f7ee4", + "value": 0.622697450596031 +}, { + "token": "808f7eec", + "value": 0.9123428024448095 +}, { + "token": "808f7ef4", + "value": 0.7929627313491234 +}, { + "token": "808f7efc", + "value": 0.14057925336084875 +}, { + "token": "808f7f04", + "value": 0.03307304375084663 +}, { + "token": "808f7f0c", + "value": 0.5610326125073675 +}, { + "token": "808f7f14", + "value": 0.4322570558764176 +}, { + "token": "808f7f1c", + "value": 0.0503145116262389 +}, { + "token": "808f7f24", + "value": 0.16401887959047734 +}, { + "token": "808f7f2c", + "value": 0.4751520317382516 +}, { + "token": "808f7f34", + "value": 0.23500681721624983 +}, { + "token": "808f7f3c", + "value": 0.33015285910199244 +}, { + "token": "808f7f44", + "value": 0.45842014371901474 +}, { + "token": "808f7f4c", + "value": 0.06578565472002951 +}, { + "token": "808f7f54", + "value": 0.6186564073897249 +}, { + "token": "808f7f5c", + "value": 0.6773939262080393 +}, { + "token": "808f7f64", + "value": 0.11266112875578238 +}, { + "token": "808f7f6c", + "value": 0.24580063451598888 +}, { + "token": "808f7f74", + "value": 0.9769378264780044 +}, { + "token": "808f7f7c", + "value": 0.8704465762998475 +}, { + "token": "808f7f84", + "value": 0.3917742365841228 +}, { + "token": "808f7f8c", + "value": 0.9262572914676896 +}, { + "token": "808f7f94", + "value": 0.9053184108632224 +}, { + "token": "808f7f9c", + "value": 0.302183769904139 +}, { + "token": "808f7fa4", + "value": 0.29824837147682115 +}, { + "token": "808f7fac", + "value": 0.6758105057539954 +}, { + "token": "808f7fb4", + "value": 0.15327743161577612 +}, { + "token": "808f7fbc", + "value": 0.9308212467506611 +}, { + "token": "808f7fc4", + "value": 0.7937065369136609 +}, { + "token": "808f7fcc", + "value": 0.6043745575751156 +}, { + "token": "808f7fd4", + "value": 0.7455648234651862 +}, { + "token": "808f7fdc", + "value": 0.7621016332623176 +}, { + "token": "808f7fe4", + "value": 0.079259268233 +}, { + "token": "808f7fec", + "value": 0.42279838014027704 +}, { + "token": "808f7ff4", + "value": 0.9807399010025764 +}, { + "token": "808f7ffc", + "value": 0.3514178008689648 +}] \ No newline at end of file diff --git a/examples/sample-layers/package.json b/examples/sample-layers/package.json new file mode 100644 index 00000000000..0cbf0cdd2ce --- /dev/null +++ b/examples/sample-layers/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "extrude-polyline": "^1.0.6", + "s2-geometry": "^1.2.9" + } +} diff --git a/examples/sample-layers/s2-layer/s2-layer.js b/examples/sample-layers/s2-layer/s2-layer.js new file mode 100644 index 00000000000..c41ac493d20 --- /dev/null +++ b/examples/sample-layers/s2-layer/s2-layer.js @@ -0,0 +1,92 @@ +// Copyright (c) 2015 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import {Layer, PolygonLayer} from 'deck.gl'; + +import {getS2Polygon} from './s2-utils'; + +const defaultStrokeColor = [0x33, 0x33, 0x33, 0xFF]; +const defaultFillColor = [0xBD, 0xE2, 0x7A, 0xFF]; + +const defaultProps = { + drawCells: true, + fillCells: true, + + extrusion: false, + wireframe: false, + + // Cell geometry + getS2Token: x => x.token, + getHeight: x => 0, + + // Cell outline accessors + getStrokeColor: f => f.strokeColor || defaultStrokeColor, + getStrokeWidth: f => f.strokeWidth || 1, + + // Cell fill accessors + getFillColor: f => f.fillColor || defaultFillColor +}; + +export default class S2Layer extends Layer { + initializeState() { + } + + renderLayers() { + const {id, getS2Token, getFillColor, getHeight} = this.props; + const {extruded, wireframe} = this.props; + + // Filled Polygon Layer + // TODO - use a composite polygon layer that renders outlines etc + return new PolygonLayer(Object.assign({}, this.props, { + id: `${id}-polygon-fill`, + getPolygon: x => getS2Polygon(getS2Token(x)), + getHeight, + getColor: getFillColor, + extruded, + wireframe, + updateTriggers: Object.assign({}, this.props.updateTriggers, { + getColor: this.props.updateTriggers.getFillColor + }) + })); + } +} + +S2Layer.layerName = 'S2Layer'; +S2Layer.defaultProps = defaultProps; diff --git a/examples/sample-layers/s2-layer/s2-utils.js b/examples/sample-layers/s2-layer/s2-utils.js new file mode 100644 index 00000000000..ca24e2ecf22 --- /dev/null +++ b/examples/sample-layers/s2-layer/s2-utils.js @@ -0,0 +1,54 @@ +// s2-geometry is a pure JavaScript port of Google/Niantic's S2 Geometry library +// which is perfect since it works in the browser. +import {S2} from 's2-geometry'; + +// import {hexToDec} from 'hex2dec'; +function hexToDec(hexString) { + return String(parseInt(hexString, 16)); +} + +/** + * Given a S2 hex token this function returns cell level + * cells level is a number between 1 and 30 + * + * S2 cell id is a 64 bit number + * S2 token removed all trailing zeros from the 16 bit converted number + * */ +function getLevelFromToken(token) { + // leaf level token size is 16. Each 2 bit add a level + const lastHex = token.substr(token.length - 1); + // a) token = trailing-zero trimmed hex id + // b) 64 bit hex id - 3 face bit + 60 bits for 30 levels + 1 bit lsb marker + const level = 2 * (token.length - 1) - ((lastHex & 1) === 0); + // c) If lsb bit of last hex digit is zero, we have one more level less of + return level; +} + +/** + * Given an S2 token this function convert the token to 64 bit id + * */ +function getIdFromToken(token) { + // pad token with zeros to make the length 16 + const padding = 16 - token.length; + const paddedToken = token + new Array(padding + 1).join('0'); + return hexToDec(paddedToken); +} + +/** + * Get a polygon with corner coordinates for an s2 cell + * @param {*} cell - This can be an S2 key or token + * @return {Array} - a simple polygon in array format: [[lng, lat], ...] + * - each coordinate is an array [lng, lat] + * - the polygon is closed, i.e. last coordinate is a copy of the first coordinate + */ +export function getS2Polygon(token) { + const id = getIdFromToken(token); + const level = getLevelFromToken(token); + + const s2cell = S2.S2Cell.FromLatLng(S2.idToLatLng(id), level); + const corners = s2cell.getCornerLatLngs(); + const polygon = corners.map(corner => [corner.lng, corner.lat]); + // close the polygon: first and last position of the ring should be the same + polygon.push(polygon[0]); + return polygon; +} diff --git a/src/lib/composite-layer.js b/src/lib/composite-layer.js index 76a50bce3cd..3e289453635 100644 --- a/src/lib/composite-layer.js +++ b/src/lib/composite-layer.js @@ -5,6 +5,10 @@ export default class CompositeLayer extends Layer { super(props); } + // Initialize layer is usually not needed for composite layers + // Provide empty definition to disable check for missing definition + initializeLayer() {} + getPickingInfo(opts) { // do not call onHover/onClick on the container return null;