diff --git a/clouds/bigquery/Makefile b/clouds/bigquery/Makefile index 5310196a7..03d43e064 100644 --- a/clouds/bigquery/Makefile +++ b/clouds/bigquery/Makefile @@ -4,6 +4,7 @@ ROOT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) DIST_DIR ?= $(ROOT_DIR)/dist BUILD_DIR ?= $(ROOT_DIR)/build +MODULES_DIRS ?= $(ROOT_DIR)/modules ESLINTRC_DIR ?= $(ROOT_DIR)/../.. COMMON_DIR = $(ROOT_DIR)/common PACKAGE_VERSION ?= $(shell cat $(ROOT_DIR)/version) @@ -49,7 +50,10 @@ build: build-libraries: mkdir -p $(BUILD_DIR)/libs $(MAKE) -C libraries/javascript build - cp libraries/javascript/build/index.js $(BUILD_DIR)/libs/$(BQ_LIBRARY_DEFAULT).js + $(COMMON_DIR)/list_libraries.js $(MODULES_DIRS) --diff="$(diff)" --modules=$(modules) --functions=$(functions) --nodeps=$(nodeps) --makelib=$(MAKE_LIB) 1>/dev/null # Check errors + for f in `$(COMMON_DIR)/list_libraries.js $(MODULES_DIRS) --diff="$(diff)" --modules=$(modules) --functions=$(functions) --nodeps=$(nodeps) --makelib=$(MAKE_LIB)`; do \ + cp libraries/javascript/build/$${f}.js $(BUILD_DIR)/libs/$(BQ_LIBRARY_DEFAULT)_$${f}.js; \ + done ifdef MAKE_LIB cp libraries/javascript/build/index_$(MAKE_LIB).js $(BUILD_DIR)/libs/$(BQ_LIBRARY_DEFAULT)_$(MAKE_LIB).js endif diff --git a/clouds/bigquery/common/Makefile b/clouds/bigquery/common/Makefile index 57e536739..6cd71dfe4 100644 --- a/clouds/bigquery/common/Makefile +++ b/clouds/bigquery/common/Makefile @@ -10,11 +10,11 @@ BQ_DATASET_DEFAULT = carto BQ_LIBRARY_DEFAULT ?= carto_analytics_toolbox_core ifeq ($(production),1) -export BQ_LIBRARY_BUCKET = $(BQ_BUCKET)/$(BQ_DATASET_DEFAULT)/libs/$(BQ_LIBRARY_DEFAULT).js -export BQ_LIBRARY_TILER_BUCKET = $(BQ_BUCKET)/$(BQ_DATASET_DEFAULT)/libs/$(BQ_LIBRARY_DEFAULT)_tiler.js +export BQ_LIBRARY_BUCKET = $(BQ_BUCKET)/$(BQ_DATASET_DEFAULT)/libs/$(BQ_LIBRARY_DEFAULT) +export BQ_LIBRARY_TILER_BUCKET = $(BQ_LIBRARY_BUCKET)_tiler.js else -export BQ_LIBRARY_BUCKET = $(BQ_BUCKET)/$(BQ_PREFIX)$(BQ_DATASET_DEFAULT)/libs/$(BQ_LIBRARY_DEFAULT).js -export BQ_LIBRARY_TILER_BUCKET = $(BQ_BUCKET)/$(BQ_PREFIX)$(BQ_DATASET_DEFAULT)/libs/$(BQ_LIBRARY_DEFAULT)_tiler.js +export BQ_LIBRARY_BUCKET = $(BQ_BUCKET)/$(BQ_PREFIX)$(BQ_DATASET_DEFAULT)/libs/$(BQ_LIBRARY_DEFAULT) +export BQ_LIBRARY_TILER_BUCKET = $(BQ_LIBRARY_BUCKET)_tiler.js endif diff --git a/clouds/bigquery/common/build_modules.js b/clouds/bigquery/common/build_modules.js index e98af1770..41f6c3bc7 100755 --- a/clouds/bigquery/common/build_modules.js +++ b/clouds/bigquery/common/build_modules.js @@ -14,8 +14,11 @@ const argv = require('minimist')(process.argv.slice(2)); const inputDirs = argv._[0] && argv._[0].split(','); const outputDir = argv.output || 'build'; +const libsBuildDir = argv.libs_build_dir || '../libraries/javascript/build'; const diff = argv.diff || []; const nodeps = argv.nodeps; +const libraryBucket = argv.librarybucket; +const makelib = argv.makelib; let modulesFilter = (argv.modules && argv.modules.split(',')) || []; let functionsFilter = (argv.functions && argv.functions.split(',')) || []; let all = !(diff.length || modulesFilter.length || functionsFilter.length); @@ -156,6 +159,23 @@ if (argv.production) { let content = output.map(f => f.content).join(separator); function apply_replacements (text) { + const libraries = [... new Set(text.match(new RegExp('@@BQ_LIBRARY_.*_BUCKET@@', 'g')))]; + for (let library of libraries) { + let libraryName = library.replace('@@BQ_LIBRARY_', '').replace('_BUCKET@@', '').toLowerCase(); + if (makelib == libraryName) { + continue; + } + libraryName += '.js'; + const libraryPath = path.join(libsBuildDir, libraryName); + if (fs.existsSync(libraryPath)) { + const libraryBucketPath = libraryBucket + '_' + libraryName; + text = text.replace(new RegExp(library, 'g'), libraryBucketPath); + } + else { + console.log(`Warning: library "${libraryName}" does not exist. Run "make build-libraries" with the same filters.`); + process.exit(1); + } + } const replacements = process.env.REPLACEMENTS.split(' '); for (let replacement of replacements) { if (replacement) { diff --git a/clouds/bigquery/common/list_libraries.js b/clouds/bigquery/common/list_libraries.js new file mode 100755 index 000000000..878c35e17 --- /dev/null +++ b/clouds/bigquery/common/list_libraries.js @@ -0,0 +1,145 @@ +#!/usr/bin/env node + +// List the JavaScript libraries based on the input filters to the SQL functions + + +// ./build_modules.js modules --output=build --diff="clouds/bigquery/modules/sql/quadbin/QUADBIN_TOZXY.sql" +// ./build_modules.js modules --output=build --functions=ST_TILEENVELOPE +// ./build_modules.js modules --output=build --modules=quadbin +// ./build_modules.js modules --output=build --production --dropfirst + +const fs = require('fs'); +const path = require('path'); +const argv = require('minimist')(process.argv.slice(2)); + +const inputDirs = argv._[0] && argv._[0].split(','); +const diff = argv.diff || []; +const nodeps = argv.nodeps; +const makelib = argv.makelib; +let modulesFilter = (argv.modules && argv.modules.split(',')) || []; +let functionsFilter = (argv.functions && argv.functions.split(',')) || []; +let all = !(diff.length || modulesFilter.length || functionsFilter.length); + +// Convert diff to modules/functions +if (diff.length) { + const patternsAll = [ + /\.github\/workflows\/bigquery\.yml/, + /clouds\/bigquery\/common\/.+/, + /clouds\/bigquery\/libraries\/.+/, + /clouds\/bigquery\/.*Makefile/, + /clouds\/bigquery\/version/ + ]; + const patternModulesSql = /clouds\/bigquery\/modules\/sql\/([^\s]*?)\//g; + const patternModulesTest = /clouds\/bigquery\/modules\/test\/([^\s]*?)\//g; + const diffAll = patternsAll.some(p => diff.match(p)); + if (diffAll) { + all = diffAll; + } else { + const modulesSql = [...diff.matchAll(patternModulesSql)].map(m => m[1]); + const modulesTest = [...diff.matchAll(patternModulesTest)].map(m => m[1]); + const diffModulesFilter = [...new Set(modulesSql.concat(modulesTest))]; + if (diffModulesFilter) { + modulesFilter = diffModulesFilter; + } + } +} + +// Extract functions +const functions = []; +for (let inputDir of inputDirs) { + const sqldir = path.join(inputDir, 'sql'); + const modules = fs.readdirSync(sqldir); + modules.forEach(module => { + const moduledir = path.join(sqldir, module); + if (fs.statSync(moduledir).isDirectory()) { + const files = fs.readdirSync(moduledir); + files.forEach(file => { + if (file.endsWith('.sql')) { + const name = path.parse(file).name; + const content = fs.readFileSync(path.join(moduledir, file)).toString().replace(/--.*\n/g, ''); + functions.push({ + name, + module, + content, + dependencies: [] + }); + } + }); + } + }); +} + +// Check filters +modulesFilter.forEach(m => { + if (!functions.map(fn => fn.module).includes(m)) { + process.stderr.write(`ERROR: Module not found ${m}\n`); + process.exit(1); + } +}); +functionsFilter.forEach(f => { + if (!functions.map(fn => fn.name).includes(f)) { + process.stderr.write(`ERROR: Function not found ${f}`); + process.exit(1); + } +}); + +// Extract function dependencies +if (!nodeps) { + functions.forEach(mainFunction => { + functions.forEach(depFunction => { + if (mainFunction.name != depFunction.name) { + const depFunctionMatches = []; + depFunctionMatches.push(...depFunction.content.replace(/(\r\n|\n|\r)/gm,' ').matchAll(new RegExp('(?<=(? { + let qualifiedDepFunctName = depFunctionMatch[0].replace(/[ \p{Diacritic}]/gu, '').split('(')[0]; + qualifiedDepFunctName = qualifiedDepFunctName.split('.'); + depFunctionNames.push(qualifiedDepFunctName[qualifiedDepFunctName.length - 1]); + }) + if (depFunctionNames.some((depFunctionName) => mainFunction.content.includes(`DATASET@@.${depFunctionName}\`(`))) { + mainFunction.dependencies.push(depFunction.name); + } + } + }); + }); +} + +// Check circular dependencies +functions.forEach(mainFunction => { + functions.forEach(depFunction => { + if (mainFunction.dependencies.includes(depFunction.name) && + depFunction.dependencies.includes(mainFunction.name)) { + process.stderr.write(`ERROR: Circular dependency between ${mainFunction.name} and ${depFunction.name}`); + process.exit(1); + } + }); +}); + + +// Filter functions +const output = []; +function add (f, include) { + include = include || all || functionsFilter.includes(f.name) || modulesFilter.includes(f.module); + for (const dependency of f.dependencies) { + add(functions.find(f => f.name === dependency), include); + } + if (!output.map(f => f.name).includes(f.name) && include) { + output.push({ + name: f.name, + content: f.content + }); + } +} +functions.forEach(f => add(f)); + +const content = output.map(f => f.content).join('\n'); +let libraries = [... new Set(content.match(new RegExp('@@BQ_LIBRARY_.*_BUCKET@@', 'g')))] + .map(l => l.replace('@@BQ_LIBRARY_', '').replace('_BUCKET@@', '').toLowerCase()); + +// Exclude libraries pointed by makelib as they are deployed separately +if (makelib) { + libraries = libraries.filter(l => l !== makelib); +} + +process.stdout.write(libraries.join(' ')); \ No newline at end of file diff --git a/clouds/bigquery/common/rollup.config.js b/clouds/bigquery/common/rollup.config.js index a0af9d73e..d23eb64df 100644 --- a/clouds/bigquery/common/rollup.config.js +++ b/clouds/bigquery/common/rollup.config.js @@ -18,6 +18,11 @@ for (let dir of dirs) { } } +if (!input && filename) { + console.log(`Error: library "${filename}" does not exist. Add it or revisit the replacement "@@BQ_LIBRARY_${path.parse(filename).name.toUpperCase()}@@" in one of your sql files.`); + process.exit(1); +} + // Format library name to camel case const name = process.env.NAME.replace(/(_\w)/g, k => k[1].toUpperCase()); diff --git a/clouds/bigquery/libraries/javascript/Makefile b/clouds/bigquery/libraries/javascript/Makefile index f39502fca..5dad8f37b 100644 --- a/clouds/bigquery/libraries/javascript/Makefile +++ b/clouds/bigquery/libraries/javascript/Makefile @@ -45,12 +45,27 @@ ifdef MAKE_LIB endif build-libs: build-install $(NODE_MODULES_DEV) - NAME=lib \ - PATH="$(NODE_MODULES_DEV)/.bin/:$(PATH)" \ - DIRS=$(LIBS_DIR) \ - FILENAME=index.js \ - OUTPUT=$(BUILD_DIR)/index.js \ - rollup --config $(COMMON_DIR)/rollup.config.js $(BUILD_PARAMS); \ +ifdef UNIT_TEST + $(COMMON_DIR)/list_libraries.js $(MODULES_DIR) --all --makelib=$(MAKE_LIB) 1>/dev/null # Check errors + for f in `$(COMMON_DIR)/list_libraries.js $(MODULES_DIR) --all --makelib=$(MAKE_LIB)`; do \ + NAME=$${f}Lib \ + PATH="$(NODE_MODULES_DEV)/.bin/:$(PATH)" \ + DIRS=$(LIBS_DIR) \ + FILENAME=$${f}.js \ + OUTPUT=$(BUILD_DIR)/$${f}.js \ + rollup --config $(COMMON_DIR)/rollup.config.js $(BUILD_PARAMS); \ + done +else + $(COMMON_DIR)/list_libraries.js $(MODULES_DIRS) --diff="$(diff)" --modules=$(modules) --functions=$(functions) --nodeps=$(nodeps) --makelib=$(MAKE_LIB) 1>/dev/null # Check errors + for f in `$(COMMON_DIR)/list_libraries.js $(MODULES_DIRS) --diff="$(diff)" --modules=$(modules) --functions=$(functions) --nodeps=$(nodeps) --makelib=$(MAKE_LIB)`; do \ + NAME=$${f}Lib \ + PATH="$(NODE_MODULES_DEV)/.bin/:$(PATH)" \ + DIRS=$(LIBS_DIRS) \ + FILENAME=$${f}.js \ + OUTPUT=$(BUILD_DIR)/$${f}.js \ + rollup --config $(COMMON_DIR)/rollup.config.js $(BUILD_PARAMS); \ + done +endif build-install: for d in $(shell echo $(LIBS_DIRS) | tr "," "\n"); do \ @@ -59,7 +74,10 @@ build-install: deploy: check build echo "Deploying libraries..." - $(GSUTIL) cp -r $(BUILD_DIR)/index.js $(BQ_LIBRARY_BUCKET) + $(COMMON_DIR)/list_libraries.js $(MODULES_DIRS) --diff="$(diff)" --modules=$(modules) --functions=$(functions) --nodeps=$(nodeps) --makelib=$(MAKE_LIB) 1>/dev/null # Check errors + for f in `$(COMMON_DIR)/list_libraries.js $(MODULES_DIRS) --diff="$(diff)" --modules=$(modules) --functions=$(functions) --nodeps=$(nodeps) --makelib=$(MAKE_LIB)`; do \ + $(GSUTIL) cp -r $(BUILD_DIR)/$${f}.js $(BQ_LIBRARY_BUCKET)_$${f}.js; \ + done # Provisional for WASM version of tiler ifdef MAKE_LIB echo "Deploying tiler library..." diff --git a/clouds/bigquery/libraries/javascript/src/accessors.js b/clouds/bigquery/libraries/javascript/libs/accessors.js similarity index 100% rename from clouds/bigquery/libraries/javascript/src/accessors.js rename to clouds/bigquery/libraries/javascript/libs/accessors.js diff --git a/clouds/bigquery/libraries/javascript/src/clustering.js b/clouds/bigquery/libraries/javascript/libs/clustering.js similarity index 100% rename from clouds/bigquery/libraries/javascript/src/clustering.js rename to clouds/bigquery/libraries/javascript/libs/clustering.js diff --git a/clouds/bigquery/libraries/javascript/src/constructors.js b/clouds/bigquery/libraries/javascript/libs/constructors.js similarity index 100% rename from clouds/bigquery/libraries/javascript/src/constructors.js rename to clouds/bigquery/libraries/javascript/libs/constructors.js diff --git a/clouds/bigquery/libraries/javascript/src/h3.js b/clouds/bigquery/libraries/javascript/libs/h3.js similarity index 100% rename from clouds/bigquery/libraries/javascript/src/h3.js rename to clouds/bigquery/libraries/javascript/libs/h3.js diff --git a/clouds/bigquery/libraries/javascript/libs/index.js b/clouds/bigquery/libraries/javascript/libs/index.js deleted file mode 100644 index e96a72888..000000000 --- a/clouds/bigquery/libraries/javascript/libs/index.js +++ /dev/null @@ -1,25 +0,0 @@ -import accessors from '../src/accessors'; -import constructors from '../src/constructors'; -import measurements from '../src/measurements'; -import quadkey from '../src/quadkey'; -import s2 from '../src/s2'; -import processing from '../src/processing'; -import transformations from '../src/transformations'; -import h3 from '../src/h3'; -import placekey from '../src/placekey'; -import clustering from '../src/clustering'; -import random from '../src/random'; - -export default { - accessors, - constructors, - measurements, - quadkey, - s2, - processing, - transformations, - h3, - placekey, - clustering, - random -}; \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/src/measurements.js b/clouds/bigquery/libraries/javascript/libs/measurements.js similarity index 100% rename from clouds/bigquery/libraries/javascript/src/measurements.js rename to clouds/bigquery/libraries/javascript/libs/measurements.js diff --git a/clouds/bigquery/libraries/javascript/src/placekey.js b/clouds/bigquery/libraries/javascript/libs/placekey.js similarity index 100% rename from clouds/bigquery/libraries/javascript/src/placekey.js rename to clouds/bigquery/libraries/javascript/libs/placekey.js diff --git a/clouds/bigquery/libraries/javascript/src/processing.js b/clouds/bigquery/libraries/javascript/libs/processing.js similarity index 100% rename from clouds/bigquery/libraries/javascript/src/processing.js rename to clouds/bigquery/libraries/javascript/libs/processing.js diff --git a/clouds/bigquery/libraries/javascript/libs/quadkey.js b/clouds/bigquery/libraries/javascript/libs/quadkey.js new file mode 100644 index 000000000..51eb55b18 --- /dev/null +++ b/clouds/bigquery/libraries/javascript/libs/quadkey.js @@ -0,0 +1,25 @@ +import { + bbox, + toParent, + toChildren, + quadkeyFromQuadint, + quadintFromQuadkey, + quadintFromLocation, + quadintToGeoJSON, + quadintFromZXY, + geojsonToQuadints, + ZXYFromQuadint +} from '../src/quadkey'; + +export default { + bbox, + toParent, + toChildren, + quadkeyFromQuadint, + quadintFromQuadkey, + quadintFromLocation, + quadintToGeoJSON, + quadintFromZXY, + geojsonToQuadints, + ZXYFromQuadint +}; \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/libs/random.js b/clouds/bigquery/libraries/javascript/libs/random.js new file mode 100644 index 000000000..70dcd1cc6 --- /dev/null +++ b/clouds/bigquery/libraries/javascript/libs/random.js @@ -0,0 +1,8 @@ +import { + generateRandomPointsInPolygon + +} from '../src/random'; + +export default { + generateRandomPointsInPolygon +}; \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/libs/s2.js b/clouds/bigquery/libraries/javascript/libs/s2.js new file mode 100644 index 000000000..229bb13f1 --- /dev/null +++ b/clouds/bigquery/libraries/javascript/libs/s2.js @@ -0,0 +1,9 @@ +import { S2 } from '../src/s2'; + +export default { + keyToId: S2.keyToId, + idToKey: S2.idToKey, + latLngToKey: S2.latLngToKey, + FromHilbertQuadKey: S2.S2Cell.FromHilbertQuadKey, + idToLatLng: S2.idToLatLng +}; \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/src/transformations.js b/clouds/bigquery/libraries/javascript/libs/transformations.js similarity index 100% rename from clouds/bigquery/libraries/javascript/src/transformations.js rename to clouds/bigquery/libraries/javascript/libs/transformations.js diff --git a/clouds/bigquery/libraries/javascript/src/quadkey.js b/clouds/bigquery/libraries/javascript/src/quadkey.js index f74df5b5c..8ea5e5d7e 100644 --- a/clouds/bigquery/libraries/javascript/src/quadkey.js +++ b/clouds/bigquery/libraries/javascript/src/quadkey.js @@ -1,25 +1,310 @@ -import { - bbox, - toParent, - toChildren, - quadkeyFromQuadint, - quadintFromQuadkey, - quadintFromLocation, - quadintToGeoJSON, - quadintFromZXY, - geojsonToQuadints, - ZXYFromQuadint -} from './quadkey/index'; - -export default { - bbox, - toParent, - toChildren, - quadkeyFromQuadint, - quadintFromQuadkey, - quadintFromLocation, - quadintToGeoJSON, - quadintFromZXY, - geojsonToQuadints, - ZXYFromQuadint -}; \ No newline at end of file +// ---------------------------- +// -- Copyright (C) 2021 CARTO +// ---------------------------- + +import tilebelt from '@mapbox/tilebelt'; +import tilecover from '@mapbox/tile-cover'; + +/** + * convert tile coordinates to quadint at specific zoom level + * @param {zxycoord} zxy zoom and tile coordinates + * @return {int} quadint for input tile coordinates at input zoom level + */ +export function quadintFromZXY (z, x, y) { + if (z < 0 || z > 29) { + throw new Error('Wrong zoom'); + } + const zI = z; + if (zI <= 13) { + let quadint = y; + quadint <<= zI; + quadint |= x; + quadint <<= 5; + quadint |= zI; + return quadint; + } + let quadint = BigInt(y); + quadint <<= BigInt(z); + quadint |= BigInt(x); + quadint <<= BigInt(5); + quadint |= BigInt(z); + return quadint; +} + +/** + * convert quadint to tile coordinates and level of zoom + * @param {int} quadint quadint to be converted + * @return {zxycoord} level of zoom and tile coordinates + */ +export function ZXYFromQuadint (quadint) { + const quadintBig = BigInt(quadint); + const z = quadintBig & BigInt(0x1F); + if (z <= 13n) { + const zNumber = Number(z); + const x = (quadint >> 5) & ((1 << zNumber) - 1); + const y = quadint >> (zNumber + 5); + return { z: zNumber, x: x, y: y }; + } + const x = (quadintBig >> (5n)) & ((1n << z) - 1n); + const y = quadintBig >> (5n + z); + return { z: Number(z), x: Number(x), y: Number(y) }; +} + +/** + * get quadint for location at specific zoom level + * @param {geocoord} location location coordinates to convert to quadint + * @param {number} zoom map zoom level of quadint to return + * @return {string} quadint the input location resides in for the input zoom level + */ +export function quadintFromLocation (long, lat, zoom) { + if (zoom < 0 || zoom > 29) { + throw new Error('Wrong zoom'); + } + lat = clipNumber(lat, -85.05, 85.05); + const tile = tilebelt.pointToTile(long, lat, zoom); + return quadintFromZXY(zoom, tile[0], tile[1]); +} + +/** + * convert quadkey into a quadint + * @param {string} quadkey quadkey to be converted + * @return {int} quadint + */ +export function quadintFromQuadkey (quadkey) { + const z = quadkey.length; + const tile = tilebelt.quadkeyToTile(quadkey); + return quadintFromZXY(z, tile[0], tile[1]); +} + +/** + * convert quadint into a quadkey + * @param {int} quadint quadint to be converted + * @return {string} quadkey + */ +export function quadkeyFromQuadint (quadint) { + const tile = ZXYFromQuadint(quadint); + return tilebelt.tileToQuadkey([tile.x, tile.y, tile.z]); +} + +/** + * get the bounding box for a quadint in location coordinates + * @param {int} quadint quadint to get bounding box from + * @return {bbox} bounding box for the input quadint + */ +export function bbox (quadint) { + const tile = ZXYFromQuadint(quadint); + return tilebelt.tileToBBOX([tile.x, tile.y, tile.z]); +} + +/** + * get the GeoJSON with the bounding box for a quadint in location coordinates + * @param {int} quadint quadint to get bounding box from + * @return {GeoJSON} GeoJSON with the bounding box for the input quadint + */ +export function quadintToGeoJSON (quadint) { + const tile = ZXYFromQuadint(quadint); + return tilebelt.tileToGeoJSON([tile.x, tile.y, tile.z]); +} + +/** + * returns the sibling of the given quadint and will wrap + * @param {int} quadint key to get sibling of + * @param {string} direction direction of sibling from key + * @return {int} sibling key + */ +export function sibling (quadint, direction) { + direction = direction.toLowerCase(); + if (direction !== 'left' && direction !== 'right' && direction !== 'up' && direction !== 'down') { + throw new Error('Wrong direction argument passed to sibling'); + } + if (direction === 'left') { + return siblingLeft(quadint); + } + if (direction === 'right') { + return siblingRight(quadint); + } + if (direction === 'up') { + return siblingUp(quadint); + } + if (direction === 'down') { + return siblingDown(quadint); + } +} + +/** + * returns the sibling of the given quadint and will wrap + * @param {int} quadint key to get sibling of + * @param {string} direction direction of sibling from key + * @return {int} sibling key + */ +export function siblingLeft (quadint) { + const tile = ZXYFromQuadint(quadint); + const tilesPerLevel = 2 << (tile.z - 1); + const x = tile.x > 0 ? tile.x - 1 : tilesPerLevel - 1; + return quadintFromZXY(tile.z, x, tile.y); +} + +/** + * returns the sibling of the given quadint and will wrap + * @param {int} quadint key to get sibling of + * @param {string} direction direction of sibling from key + * @return {int} sibling key + */ +export function siblingRight (quadint) { + const tile = ZXYFromQuadint(quadint); + const tilesPerLevel = 2 << (tile.z - 1); + const x = tile.x < tilesPerLevel - 1 ? tile.x + 1 : 0; + return quadintFromZXY(tile.z, x, tile.y); +} + +/** + * returns the sibling of the given quadint and will wrap + * @param {int} quadint key to get sibling of + * @param {string} direction direction of sibling from key + * @return {int} sibling key + */ +export function siblingUp (quadint) { + const tile = ZXYFromQuadint(quadint); + const tilesPerLevel = 2 << (tile.z - 1); + const y = tile.y > 0 ? tile.y - 1 : tilesPerLevel - 1; + return quadintFromZXY(tile.z, tile.x, y); +} + +/** + * returns the sibling of the given quadint and will wrap + * @param {int} quadint key to get sibling of + * @param {string} direction direction of sibling from key + * @return {int} sibling key + */ +export function siblingDown (quadint) { + const tile = ZXYFromQuadint(quadint); + const tilesPerLevel = 2 << (tile.z - 1); + const y = tile.y < tilesPerLevel - 1 ? tile.y + 1 : 0; + return quadintFromZXY(tile.z, tile.x, y); +} + +/** + * get all the children quadints of a quadint + * @param {int} quadint quadint to get the children of + * @param {int} resolution resolution of the desired children + * @return {array} array of quadints representing the children of the input quadint + */ +export function toChildren (quadint, resolution) { + const zxy = ZXYFromQuadint(quadint); + if (zxy.z < 0 || zxy.z > 28) { + throw new Error('Wrong quadint zoom'); + } + + if (resolution < 0 || resolution <= zxy.z) { + throw new Error('Wrong resolution'); + } + const diffZ = resolution - zxy.z; + const mask = (1 << diffZ) - 1; + const minTileX = zxy.x << diffZ; + const maxTileX = minTileX | mask; + const minTileY = zxy.y << diffZ; + const maxTileY = minTileY | mask; + const children = []; + let x, y; + for (x = minTileX; x <= maxTileX; x++) { + for (y = minTileY; y <= maxTileY; y++) { + children.push(quadintFromZXY(resolution, x, y)); + } + } + return children; +} + +/** + * get the parent of a quadint + * @param {int} quadint quadint to get the parent of + * @param {int} resolution resolution of the desired parent + * @return {int} parent of the input quadint + */ +export function toParent (quadint, resolution) { + const zxy = ZXYFromQuadint(quadint); + if (zxy.z < 1 || zxy.z > 29) { + throw new Error('Wrong quadint zoom'); + } + if (resolution < 0 || resolution >= zxy.z) { + throw new Error('Wrong resolution'); + } + return quadintFromZXY(resolution, zxy.x >> (zxy.z - resolution), zxy.y >> (zxy.z - resolution)); +} + +/** + * get the kring of a quadint + * @param {int} origin quadint to get the kring of + * @param {int} size in tiles of the desired kring + * @return {int} kring of the input quadint + */ +export function kRing (origin, size) { + if (size === 0) { + return [origin.toString()]; + } + + let i, j; + let cornerQuadint = origin; + // Traverse to top left corner + for (i = 0; i < size; i++) { + cornerQuadint = siblingLeft(cornerQuadint); + cornerQuadint = siblingUp(cornerQuadint) + } + + const neighbors = []; + let traversalQuadint; + for (j = 0; j < size * 2 + 1; j++) { + traversalQuadint = cornerQuadint; + for (i = 0; i < size * 2 + 1; i++) { + neighbors.push(traversalQuadint.toString()); + traversalQuadint = siblingRight(traversalQuadint); + } + cornerQuadint = siblingDown(cornerQuadint) + } + return neighbors; +} + +/** + * get the kring distances of a quadint + * @param {int} origin quadint to get the kring of + * @param {int} size in tiles of the desired kring + * @return {int} kring distances of the input quadint + */ +export function kRingDistances (origin, size) { + if (size === 0) { + return [{ index: origin.toString(), distance: 0 }]; + } + + let cornerQuadint = origin; + // Traverse to top left corner + for (let i = 0; i < size; i++) { + cornerQuadint = siblingLeft(cornerQuadint); + cornerQuadint = siblingUp(cornerQuadint) + } + + const neighbors = []; + let traversalQuadint; + for (let j = -size; j <= size; j++) { + traversalQuadint = cornerQuadint; + for (let i = -size; i <= size; i++) { + neighbors.push({ + index: traversalQuadint.toString(), + distance: Math.max(Math.abs(i), Math.abs(j)) // Chebychev distance + }); + traversalQuadint = siblingRight(traversalQuadint); + } + cornerQuadint = siblingDown(cornerQuadint) + } + return neighbors.sort((a, b) => (a['distance'] > b['distance']) ? 1 : -1); +} + +/** + * get an array of quadints containing a geography for given zooms + * @param {object} poly geography we want to extract the quadints from + * @param {struct} limits struct containing the range of zooms + * @return {array} array of quadints containing a geography + */ +export function geojsonToQuadints (poly, limits) { + return tilecover.tiles(poly, limits).map(tile => quadintFromZXY(tile[2], tile[0], tile[1])); +} + +const clipNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b)); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/src/quadkey/index.js b/clouds/bigquery/libraries/javascript/src/quadkey/index.js deleted file mode 100644 index 8ea5e5d7e..000000000 --- a/clouds/bigquery/libraries/javascript/src/quadkey/index.js +++ /dev/null @@ -1,310 +0,0 @@ -// ---------------------------- -// -- Copyright (C) 2021 CARTO -// ---------------------------- - -import tilebelt from '@mapbox/tilebelt'; -import tilecover from '@mapbox/tile-cover'; - -/** - * convert tile coordinates to quadint at specific zoom level - * @param {zxycoord} zxy zoom and tile coordinates - * @return {int} quadint for input tile coordinates at input zoom level - */ -export function quadintFromZXY (z, x, y) { - if (z < 0 || z > 29) { - throw new Error('Wrong zoom'); - } - const zI = z; - if (zI <= 13) { - let quadint = y; - quadint <<= zI; - quadint |= x; - quadint <<= 5; - quadint |= zI; - return quadint; - } - let quadint = BigInt(y); - quadint <<= BigInt(z); - quadint |= BigInt(x); - quadint <<= BigInt(5); - quadint |= BigInt(z); - return quadint; -} - -/** - * convert quadint to tile coordinates and level of zoom - * @param {int} quadint quadint to be converted - * @return {zxycoord} level of zoom and tile coordinates - */ -export function ZXYFromQuadint (quadint) { - const quadintBig = BigInt(quadint); - const z = quadintBig & BigInt(0x1F); - if (z <= 13n) { - const zNumber = Number(z); - const x = (quadint >> 5) & ((1 << zNumber) - 1); - const y = quadint >> (zNumber + 5); - return { z: zNumber, x: x, y: y }; - } - const x = (quadintBig >> (5n)) & ((1n << z) - 1n); - const y = quadintBig >> (5n + z); - return { z: Number(z), x: Number(x), y: Number(y) }; -} - -/** - * get quadint for location at specific zoom level - * @param {geocoord} location location coordinates to convert to quadint - * @param {number} zoom map zoom level of quadint to return - * @return {string} quadint the input location resides in for the input zoom level - */ -export function quadintFromLocation (long, lat, zoom) { - if (zoom < 0 || zoom > 29) { - throw new Error('Wrong zoom'); - } - lat = clipNumber(lat, -85.05, 85.05); - const tile = tilebelt.pointToTile(long, lat, zoom); - return quadintFromZXY(zoom, tile[0], tile[1]); -} - -/** - * convert quadkey into a quadint - * @param {string} quadkey quadkey to be converted - * @return {int} quadint - */ -export function quadintFromQuadkey (quadkey) { - const z = quadkey.length; - const tile = tilebelt.quadkeyToTile(quadkey); - return quadintFromZXY(z, tile[0], tile[1]); -} - -/** - * convert quadint into a quadkey - * @param {int} quadint quadint to be converted - * @return {string} quadkey - */ -export function quadkeyFromQuadint (quadint) { - const tile = ZXYFromQuadint(quadint); - return tilebelt.tileToQuadkey([tile.x, tile.y, tile.z]); -} - -/** - * get the bounding box for a quadint in location coordinates - * @param {int} quadint quadint to get bounding box from - * @return {bbox} bounding box for the input quadint - */ -export function bbox (quadint) { - const tile = ZXYFromQuadint(quadint); - return tilebelt.tileToBBOX([tile.x, tile.y, tile.z]); -} - -/** - * get the GeoJSON with the bounding box for a quadint in location coordinates - * @param {int} quadint quadint to get bounding box from - * @return {GeoJSON} GeoJSON with the bounding box for the input quadint - */ -export function quadintToGeoJSON (quadint) { - const tile = ZXYFromQuadint(quadint); - return tilebelt.tileToGeoJSON([tile.x, tile.y, tile.z]); -} - -/** - * returns the sibling of the given quadint and will wrap - * @param {int} quadint key to get sibling of - * @param {string} direction direction of sibling from key - * @return {int} sibling key - */ -export function sibling (quadint, direction) { - direction = direction.toLowerCase(); - if (direction !== 'left' && direction !== 'right' && direction !== 'up' && direction !== 'down') { - throw new Error('Wrong direction argument passed to sibling'); - } - if (direction === 'left') { - return siblingLeft(quadint); - } - if (direction === 'right') { - return siblingRight(quadint); - } - if (direction === 'up') { - return siblingUp(quadint); - } - if (direction === 'down') { - return siblingDown(quadint); - } -} - -/** - * returns the sibling of the given quadint and will wrap - * @param {int} quadint key to get sibling of - * @param {string} direction direction of sibling from key - * @return {int} sibling key - */ -export function siblingLeft (quadint) { - const tile = ZXYFromQuadint(quadint); - const tilesPerLevel = 2 << (tile.z - 1); - const x = tile.x > 0 ? tile.x - 1 : tilesPerLevel - 1; - return quadintFromZXY(tile.z, x, tile.y); -} - -/** - * returns the sibling of the given quadint and will wrap - * @param {int} quadint key to get sibling of - * @param {string} direction direction of sibling from key - * @return {int} sibling key - */ -export function siblingRight (quadint) { - const tile = ZXYFromQuadint(quadint); - const tilesPerLevel = 2 << (tile.z - 1); - const x = tile.x < tilesPerLevel - 1 ? tile.x + 1 : 0; - return quadintFromZXY(tile.z, x, tile.y); -} - -/** - * returns the sibling of the given quadint and will wrap - * @param {int} quadint key to get sibling of - * @param {string} direction direction of sibling from key - * @return {int} sibling key - */ -export function siblingUp (quadint) { - const tile = ZXYFromQuadint(quadint); - const tilesPerLevel = 2 << (tile.z - 1); - const y = tile.y > 0 ? tile.y - 1 : tilesPerLevel - 1; - return quadintFromZXY(tile.z, tile.x, y); -} - -/** - * returns the sibling of the given quadint and will wrap - * @param {int} quadint key to get sibling of - * @param {string} direction direction of sibling from key - * @return {int} sibling key - */ -export function siblingDown (quadint) { - const tile = ZXYFromQuadint(quadint); - const tilesPerLevel = 2 << (tile.z - 1); - const y = tile.y < tilesPerLevel - 1 ? tile.y + 1 : 0; - return quadintFromZXY(tile.z, tile.x, y); -} - -/** - * get all the children quadints of a quadint - * @param {int} quadint quadint to get the children of - * @param {int} resolution resolution of the desired children - * @return {array} array of quadints representing the children of the input quadint - */ -export function toChildren (quadint, resolution) { - const zxy = ZXYFromQuadint(quadint); - if (zxy.z < 0 || zxy.z > 28) { - throw new Error('Wrong quadint zoom'); - } - - if (resolution < 0 || resolution <= zxy.z) { - throw new Error('Wrong resolution'); - } - const diffZ = resolution - zxy.z; - const mask = (1 << diffZ) - 1; - const minTileX = zxy.x << diffZ; - const maxTileX = minTileX | mask; - const minTileY = zxy.y << diffZ; - const maxTileY = minTileY | mask; - const children = []; - let x, y; - for (x = minTileX; x <= maxTileX; x++) { - for (y = minTileY; y <= maxTileY; y++) { - children.push(quadintFromZXY(resolution, x, y)); - } - } - return children; -} - -/** - * get the parent of a quadint - * @param {int} quadint quadint to get the parent of - * @param {int} resolution resolution of the desired parent - * @return {int} parent of the input quadint - */ -export function toParent (quadint, resolution) { - const zxy = ZXYFromQuadint(quadint); - if (zxy.z < 1 || zxy.z > 29) { - throw new Error('Wrong quadint zoom'); - } - if (resolution < 0 || resolution >= zxy.z) { - throw new Error('Wrong resolution'); - } - return quadintFromZXY(resolution, zxy.x >> (zxy.z - resolution), zxy.y >> (zxy.z - resolution)); -} - -/** - * get the kring of a quadint - * @param {int} origin quadint to get the kring of - * @param {int} size in tiles of the desired kring - * @return {int} kring of the input quadint - */ -export function kRing (origin, size) { - if (size === 0) { - return [origin.toString()]; - } - - let i, j; - let cornerQuadint = origin; - // Traverse to top left corner - for (i = 0; i < size; i++) { - cornerQuadint = siblingLeft(cornerQuadint); - cornerQuadint = siblingUp(cornerQuadint) - } - - const neighbors = []; - let traversalQuadint; - for (j = 0; j < size * 2 + 1; j++) { - traversalQuadint = cornerQuadint; - for (i = 0; i < size * 2 + 1; i++) { - neighbors.push(traversalQuadint.toString()); - traversalQuadint = siblingRight(traversalQuadint); - } - cornerQuadint = siblingDown(cornerQuadint) - } - return neighbors; -} - -/** - * get the kring distances of a quadint - * @param {int} origin quadint to get the kring of - * @param {int} size in tiles of the desired kring - * @return {int} kring distances of the input quadint - */ -export function kRingDistances (origin, size) { - if (size === 0) { - return [{ index: origin.toString(), distance: 0 }]; - } - - let cornerQuadint = origin; - // Traverse to top left corner - for (let i = 0; i < size; i++) { - cornerQuadint = siblingLeft(cornerQuadint); - cornerQuadint = siblingUp(cornerQuadint) - } - - const neighbors = []; - let traversalQuadint; - for (let j = -size; j <= size; j++) { - traversalQuadint = cornerQuadint; - for (let i = -size; i <= size; i++) { - neighbors.push({ - index: traversalQuadint.toString(), - distance: Math.max(Math.abs(i), Math.abs(j)) // Chebychev distance - }); - traversalQuadint = siblingRight(traversalQuadint); - } - cornerQuadint = siblingDown(cornerQuadint) - } - return neighbors.sort((a, b) => (a['distance'] > b['distance']) ? 1 : -1); -} - -/** - * get an array of quadints containing a geography for given zooms - * @param {object} poly geography we want to extract the quadints from - * @param {struct} limits struct containing the range of zooms - * @return {array} array of quadints containing a geography - */ -export function geojsonToQuadints (poly, limits) { - return tilecover.tiles(poly, limits).map(tile => quadintFromZXY(tile[2], tile[0], tile[1])); -} - -const clipNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b)); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/src/random.js b/clouds/bigquery/libraries/javascript/src/random.js index fde5772e1..4326c343b 100644 --- a/clouds/bigquery/libraries/javascript/src/random.js +++ b/clouds/bigquery/libraries/javascript/src/random.js @@ -1,6 +1,6 @@ import { bbox, booleanPointInPolygon, randomPoint } from '@turf/turf'; -function generateRandomPointsInPolygon (polygon, numPoints) { +export function generateRandomPointsInPolygon (polygon, numPoints) { const randomPoints = []; while (randomPoints.length < numPoints) { const point = randomPoint(1, { bbox: bbox(polygon) }).features[0]; @@ -9,16 +9,4 @@ function generateRandomPointsInPolygon (polygon, numPoints) { } } return randomPoints; -} - -function generateRandomPointInPolygon (polygon) { - let point - do { - point = randomPoint(1, { bbox: bbox(polygon) }).features[0]; - } while (!booleanPointInPolygon(point, polygon)) - return JSON.stringify(point.geometry); -} - -export default { - generateRandomPointsInPolygon -}; \ No newline at end of file +} \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/src/s2.js b/clouds/bigquery/libraries/javascript/src/s2.js index a4590d8eb..3b28bd5cb 100644 --- a/clouds/bigquery/libraries/javascript/src/s2.js +++ b/clouds/bigquery/libraries/javascript/src/s2.js @@ -1,9 +1,596 @@ -import { S2 } from './s2/index'; - -export default { - keyToId: S2.keyToId, - idToKey: S2.idToKey, - latLngToKey: S2.latLngToKey, - FromHilbertQuadKey: S2.S2Cell.FromHilbertQuadKey, - idToLatLng: S2.idToLatLng -}; \ No newline at end of file +/* eslint-disable */ +/// S2 Geometry functions +// the regional scoreboard is based on a level 6 S2 Cell +// - https://docs.google.com/presentation/d/1Hl4KapfAENAOf4gv-pSngKwvS_jwNVHRPZTTDzXXn6Q/view?pli=1#slide=id.i22 +// at the time of writing there's no actual API for the intel map to retrieve scoreboard data, +// but it's still useful to plot the score cells on the intel map + + +// the S2 geometry is based on projecting the earth sphere onto a cube, with some scaling of face coordinates to +// keep things close to approximate equal area for adjacent cells +// to convert a lat,lng into a cell id: +// - convert lat,lng to x,y,z +// - convert x,y,z into face,u,v +// - u,v scaled to s,t with quadratic formula +// - s,t converted to integer i,j offsets +// - i,j converted to a position along a Hubbert space-filling curve +// - combine face,position to get the cell id + +//NOTE: compared to the google S2 geometry library, we vary from their code in the following ways +// - cell IDs: they combine face and the hilbert curve position into a single 64 bit number. this gives efficient space +// and speed. javascript doesn't have appropriate data types, and speed is not cricical, so we use +// as [face,[bitpair,bitpair,...]] instead +// - i,j: they always use 30 bits, adjusting as needed. we use 0 to (1< temp[1]) { + if (temp[0] > temp[2]) { + return 0; + } else { + return 2; + } + } else { + if (temp[1] > temp[2]) { + return 1; + } else { + return 2; + } + } + +}; + +var faceXYZToUV = function(face,xyz) { + var u,v; + + switch (face) { + case 0: u = xyz[1]/xyz[0]; v = xyz[2]/xyz[0]; break; + case 1: u = -xyz[0]/xyz[1]; v = xyz[2]/xyz[1]; break; + case 2: u = -xyz[0]/xyz[2]; v = -xyz[1]/xyz[2]; break; + case 3: u = xyz[2]/xyz[0]; v = xyz[1]/xyz[0]; break; + case 4: u = xyz[2]/xyz[1]; v = -xyz[0]/xyz[1]; break; + case 5: u = -xyz[1]/xyz[2]; v = -xyz[0]/xyz[2]; break; + default: throw {error: 'Invalid face'}; + } + + return [u,v]; +}; + + + + +S2.XYZToFaceUV = function(xyz) { + var face = largestAbsComponent(xyz); + + if (xyz[face] < 0) { + face += 3; + } + + var uv = faceXYZToUV (face,xyz); + + return [face, uv]; +}; + +S2.FaceUVToXYZ = function(face,uv) { + var u = uv[0]; + var v = uv[1]; + + switch (face) { + case 0: return [ 1, u, v]; + case 1: return [-u, 1, v]; + case 2: return [-u,-v, 1]; + case 3: return [-1,-v,-u]; + case 4: return [ v,-1,-u]; + case 5: return [ v, u,-1]; + default: throw {error: 'Invalid face'}; + } +}; + +var singleSTtoUV = function(st) { + if (st >= 0.5) { + return (1/3.0) * (4*st*st - 1); + } else { + return (1/3.0) * (1 - (4*(1-st)*(1-st))); + } +}; + +S2.STToUV = function(st) { + return [singleSTtoUV(st[0]), singleSTtoUV(st[1])]; +}; + + +var singleUVtoST = function(uv) { + if (uv >= 0) { + return 0.5 * Math.sqrt (1 + 3*uv); + } else { + return 1 - 0.5 * Math.sqrt (1 - 3*uv); + } +}; +S2.UVToST = function(uv) { + return [singleUVtoST(uv[0]), singleUVtoST(uv[1])]; +}; + + +S2.STToIJ = function(st,order) { + var maxSize = (1<=0; i--) { + + var mask = 1<= 0; i--) { + + level = maxLevel - i; + bit = position[i]; + rx = 0; + ry = 0; + if (bit === '1') { + ry = 1; + } + else if (bit === '2') { + rx = 1; + ry = 1; + } + else if (bit === '3') { + rx = 1; + } + + val = Math.pow(2, level - 1); + rotateAndFlipQuadrant(val, point, rx, ry); + + point.x += val * rx; + point.y += val * ry; + + } + + if (face % 2 === 1) { + var t = point.x; + point.x = point.y; + point.y = t; + } + + + return S2.S2Cell.FromFaceIJ(parseInt(face), [point.x, point.y], level); +}; + +//static method to construct +S2.S2Cell.FromLatLng = function(latLng, level) { + if ((!latLng.lat && latLng.lat !== 0) || (!latLng.lng && latLng.lng !== 0)) { + throw new Error("Pass { lat: lat, lng: lng } to S2.S2Cell.FromLatLng"); + } + var xyz = S2.LatLngToXYZ(latLng); + + var faceuv = S2.XYZToFaceUV(xyz); + var st = S2.UVToST(faceuv[1]); + + var ij = S2.STToIJ(st,level); + + return S2.S2Cell.FromFaceIJ (faceuv[0], ij, level); +}; + +/* +S2.faceIjLevelToXyz = function (face, ij, level) { + var st = S2.IJToST(ij, level, [0.5, 0.5]); + var uv = S2.STToUV(st); + var xyz = S2.FaceUVToXYZ(face, uv); + + return S2.XYZToLatLng(xyz); + return xyz; +}; +*/ + +S2.S2Cell.FromFaceIJ = function(face,ij,level) { + var cell = new S2.S2Cell(); + cell.face = face; + cell.ij = ij; + cell.level = level; + + return cell; +}; + + +S2.S2Cell.prototype.toString = function() { + return 'F'+this.face+'ij['+this.ij[0]+','+this.ij[1]+']@'+this.level; +}; + +S2.S2Cell.prototype.getLatLng = function() { + var st = S2.IJToST(this.ij,this.level, [0.5,0.5]); + var uv = S2.STToUV(st); + var xyz = S2.FaceUVToXYZ(this.face, uv); + + return S2.XYZToLatLng(xyz); +}; + +S2.S2Cell.prototype.getCornerLatLngs = function() { + var result = []; + var offsets = [ + [ 0.0, 0.0 ], + [ 0.0, 1.0 ], + [ 1.0, 1.0 ], + [ 1.0, 0.0 ] + ]; + + for (var i=0; i<4; i++) { + var st = S2.IJToST(this.ij, this.level, offsets[i]); + var uv = S2.STToUV(st); + var xyz = S2.FaceUVToXYZ(this.face, uv); + + result.push ( S2.XYZToLatLng(xyz) ); + } + return result; +}; + + +S2.S2Cell.prototype.getFaceAndQuads = function () { + var quads = pointToHilbertQuadList(this.ij[0], this.ij[1], this.level, this.face); + + return [this.face,quads]; +}; +S2.S2Cell.prototype.toHilbertQuadkey = function () { + var quads = pointToHilbertQuadList(this.ij[0], this.ij[1], this.level, this.face); + + return this.face.toString(10) + '/' + quads.join(''); +}; + +S2.latLngToNeighborKeys = S2.S2Cell.latLngToNeighborKeys = function (lat, lng, level) { + return S2.S2Cell.FromLatLng({ lat: lat, lng: lng }, level).getNeighbors().map(function (cell) { + return cell.toHilbertQuadkey(); + }); +}; +S2.S2Cell.prototype.getNeighbors = function() { + + var fromFaceIJWrap = function(face,ij,level) { + var maxSize = (1<=0 && ij[1]>=0 && ij[0] levelN) { + posS = posS.substr(0, levelN); + } + + // 3-bit face value + faceB = Long.fromString(faceN.toString(10), true, 10).toString(2); + while (faceB.length < S2.FACE_BITS) { + faceB = '0' + faceB; + } + + // 60-bit position value + posB = Long.fromString(posS, true, 4).toString(2); + while (posB.length < (2 * levelN)) { + posB = '0' + posB; + } + + bin = faceB + posB; + // 1-bit lsb marker + bin += '1'; + // n-bit padding to 64-bits + while (bin.length < (S2.FACE_BITS + S2.POS_BITS)) { + bin += '0'; + } + + return Long.fromString(bin, true, 2).toSigned().toString(10); +}; + +S2.keyToId = S2.S2Cell.keyToId += S2.toId = S2.toCellId = S2.fromKey += function (key) { + var parts = key.split('/'); + + return S2.fromFacePosLevel(parts[0], parts[1], parts[1].length); +}; + +S2.idToKey = S2.S2Cell.idToKey += S2.S2Cell.toKey = S2.toKey += S2.fromId = S2.fromCellId += S2.S2Cell.toHilbertQuadkey = S2.toHilbertQuadkey += function (idS) { + var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long'); + var bin = Long.fromString(idS, true, 10).toString(2); + + while (bin.length < (S2.FACE_BITS + S2.POS_BITS)) { + bin = '0' + bin; + } + + // MUST come AFTER binstr has been left-padded with '0's + var lsbIndex = bin.lastIndexOf('1'); + // substr(start, len) + // substring(start, end) // includes start, does not include end + var faceB = bin.substring(0, 3); + // posB will always be a multiple of 2 (or it's invalid) + var posB = bin.substring(3, lsbIndex); + var levelN = posB.length / 2; + + var faceS = Long.fromString(faceB, true, 2).toString(10); + var posS = Long.fromString(posB, true, 2).toString(4); + + while (posS.length < levelN) { + posS = '0' + posS; + } + + return faceS + '/' + posS; +}; + +S2.keyToLatLng = S2.S2Cell.keyToLatLng = function (key) { + var cell2 = S2.S2Cell.FromHilbertQuadKey(key); + return cell2.getLatLng(); +}; + +S2.idToLatLng = S2.S2Cell.idToLatLng = function (id) { + var key = S2.idToKey(id); + return S2.keyToLatLng(key); +}; + +S2.S2Cell.latLngToKey = S2.latLngToKey += S2.latLngToQuadkey = function (lat, lng, level) { + if (isNaN(level) || level < 1 || level > 30) { + throw new Error("'level' is not a number between 1 and 30 (but it should be)"); + } + // TODO + // + // S2.idToLatLng(id) + // S2.keyToLatLng(key) + // S2.nextFace(key) // prevent wrapping on nextKey + // S2.prevFace(key) // prevent wrapping on prevKey + // + // .toKeyArray(id) // face,quadtree + // .toKey(id) // hilbert + // .toPoint(id) // ij + // .toId(key) // uint64 (as string) + // .toLong(key) // long.js + // .toLatLng(id) // object? or array?, or string (with comma)? + // + // maybe S2.HQ.x, S2.GPS.x, S2.CI.x? + return S2.S2Cell.FromLatLng({ lat: lat, lng: lng }, level).toHilbertQuadkey(); +}; + +S2.stepKey = function (key, num) { + var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long'); + var parts = key.split('/'); + + var faceS = parts[0]; + var posS = parts[1]; + var level = parts[1].length; + + var posL = Long.fromString(posS, true, 4); + // TODO handle wrapping (0 === pos + 1) + // (only on the 12 edges of the globe) + var otherL; + if (num > 0) { + otherL = posL.add(Math.abs(num)); + } + else if (num < 0) { + otherL = posL.subtract(Math.abs(num)); + } + var otherS = otherL.toString(4); + + if ('0' === otherS) { + console.warning(new Error("face/position wrapping is not yet supported")); + } + + while (otherS.length < level) { + otherS = '0' + otherS; + } + + return faceS + '/' + otherS; +}; + +S2.S2Cell.prevKey = S2.prevKey = function (key) { + return S2.stepKey(key, -1); +}; + +S2.S2Cell.nextKey = S2.nextKey = function (key) { + return S2.stepKey(key, 1); +}; + +})('undefined' !== typeof module ? module.exports : window); +/* eslint-enable */ \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/src/s2/index.js b/clouds/bigquery/libraries/javascript/src/s2/index.js deleted file mode 100644 index 3b28bd5cb..000000000 --- a/clouds/bigquery/libraries/javascript/src/s2/index.js +++ /dev/null @@ -1,596 +0,0 @@ -/* eslint-disable */ -/// S2 Geometry functions -// the regional scoreboard is based on a level 6 S2 Cell -// - https://docs.google.com/presentation/d/1Hl4KapfAENAOf4gv-pSngKwvS_jwNVHRPZTTDzXXn6Q/view?pli=1#slide=id.i22 -// at the time of writing there's no actual API for the intel map to retrieve scoreboard data, -// but it's still useful to plot the score cells on the intel map - - -// the S2 geometry is based on projecting the earth sphere onto a cube, with some scaling of face coordinates to -// keep things close to approximate equal area for adjacent cells -// to convert a lat,lng into a cell id: -// - convert lat,lng to x,y,z -// - convert x,y,z into face,u,v -// - u,v scaled to s,t with quadratic formula -// - s,t converted to integer i,j offsets -// - i,j converted to a position along a Hubbert space-filling curve -// - combine face,position to get the cell id - -//NOTE: compared to the google S2 geometry library, we vary from their code in the following ways -// - cell IDs: they combine face and the hilbert curve position into a single 64 bit number. this gives efficient space -// and speed. javascript doesn't have appropriate data types, and speed is not cricical, so we use -// as [face,[bitpair,bitpair,...]] instead -// - i,j: they always use 30 bits, adjusting as needed. we use 0 to (1< temp[1]) { - if (temp[0] > temp[2]) { - return 0; - } else { - return 2; - } - } else { - if (temp[1] > temp[2]) { - return 1; - } else { - return 2; - } - } - -}; - -var faceXYZToUV = function(face,xyz) { - var u,v; - - switch (face) { - case 0: u = xyz[1]/xyz[0]; v = xyz[2]/xyz[0]; break; - case 1: u = -xyz[0]/xyz[1]; v = xyz[2]/xyz[1]; break; - case 2: u = -xyz[0]/xyz[2]; v = -xyz[1]/xyz[2]; break; - case 3: u = xyz[2]/xyz[0]; v = xyz[1]/xyz[0]; break; - case 4: u = xyz[2]/xyz[1]; v = -xyz[0]/xyz[1]; break; - case 5: u = -xyz[1]/xyz[2]; v = -xyz[0]/xyz[2]; break; - default: throw {error: 'Invalid face'}; - } - - return [u,v]; -}; - - - - -S2.XYZToFaceUV = function(xyz) { - var face = largestAbsComponent(xyz); - - if (xyz[face] < 0) { - face += 3; - } - - var uv = faceXYZToUV (face,xyz); - - return [face, uv]; -}; - -S2.FaceUVToXYZ = function(face,uv) { - var u = uv[0]; - var v = uv[1]; - - switch (face) { - case 0: return [ 1, u, v]; - case 1: return [-u, 1, v]; - case 2: return [-u,-v, 1]; - case 3: return [-1,-v,-u]; - case 4: return [ v,-1,-u]; - case 5: return [ v, u,-1]; - default: throw {error: 'Invalid face'}; - } -}; - -var singleSTtoUV = function(st) { - if (st >= 0.5) { - return (1/3.0) * (4*st*st - 1); - } else { - return (1/3.0) * (1 - (4*(1-st)*(1-st))); - } -}; - -S2.STToUV = function(st) { - return [singleSTtoUV(st[0]), singleSTtoUV(st[1])]; -}; - - -var singleUVtoST = function(uv) { - if (uv >= 0) { - return 0.5 * Math.sqrt (1 + 3*uv); - } else { - return 1 - 0.5 * Math.sqrt (1 - 3*uv); - } -}; -S2.UVToST = function(uv) { - return [singleUVtoST(uv[0]), singleUVtoST(uv[1])]; -}; - - -S2.STToIJ = function(st,order) { - var maxSize = (1<=0; i--) { - - var mask = 1<= 0; i--) { - - level = maxLevel - i; - bit = position[i]; - rx = 0; - ry = 0; - if (bit === '1') { - ry = 1; - } - else if (bit === '2') { - rx = 1; - ry = 1; - } - else if (bit === '3') { - rx = 1; - } - - val = Math.pow(2, level - 1); - rotateAndFlipQuadrant(val, point, rx, ry); - - point.x += val * rx; - point.y += val * ry; - - } - - if (face % 2 === 1) { - var t = point.x; - point.x = point.y; - point.y = t; - } - - - return S2.S2Cell.FromFaceIJ(parseInt(face), [point.x, point.y], level); -}; - -//static method to construct -S2.S2Cell.FromLatLng = function(latLng, level) { - if ((!latLng.lat && latLng.lat !== 0) || (!latLng.lng && latLng.lng !== 0)) { - throw new Error("Pass { lat: lat, lng: lng } to S2.S2Cell.FromLatLng"); - } - var xyz = S2.LatLngToXYZ(latLng); - - var faceuv = S2.XYZToFaceUV(xyz); - var st = S2.UVToST(faceuv[1]); - - var ij = S2.STToIJ(st,level); - - return S2.S2Cell.FromFaceIJ (faceuv[0], ij, level); -}; - -/* -S2.faceIjLevelToXyz = function (face, ij, level) { - var st = S2.IJToST(ij, level, [0.5, 0.5]); - var uv = S2.STToUV(st); - var xyz = S2.FaceUVToXYZ(face, uv); - - return S2.XYZToLatLng(xyz); - return xyz; -}; -*/ - -S2.S2Cell.FromFaceIJ = function(face,ij,level) { - var cell = new S2.S2Cell(); - cell.face = face; - cell.ij = ij; - cell.level = level; - - return cell; -}; - - -S2.S2Cell.prototype.toString = function() { - return 'F'+this.face+'ij['+this.ij[0]+','+this.ij[1]+']@'+this.level; -}; - -S2.S2Cell.prototype.getLatLng = function() { - var st = S2.IJToST(this.ij,this.level, [0.5,0.5]); - var uv = S2.STToUV(st); - var xyz = S2.FaceUVToXYZ(this.face, uv); - - return S2.XYZToLatLng(xyz); -}; - -S2.S2Cell.prototype.getCornerLatLngs = function() { - var result = []; - var offsets = [ - [ 0.0, 0.0 ], - [ 0.0, 1.0 ], - [ 1.0, 1.0 ], - [ 1.0, 0.0 ] - ]; - - for (var i=0; i<4; i++) { - var st = S2.IJToST(this.ij, this.level, offsets[i]); - var uv = S2.STToUV(st); - var xyz = S2.FaceUVToXYZ(this.face, uv); - - result.push ( S2.XYZToLatLng(xyz) ); - } - return result; -}; - - -S2.S2Cell.prototype.getFaceAndQuads = function () { - var quads = pointToHilbertQuadList(this.ij[0], this.ij[1], this.level, this.face); - - return [this.face,quads]; -}; -S2.S2Cell.prototype.toHilbertQuadkey = function () { - var quads = pointToHilbertQuadList(this.ij[0], this.ij[1], this.level, this.face); - - return this.face.toString(10) + '/' + quads.join(''); -}; - -S2.latLngToNeighborKeys = S2.S2Cell.latLngToNeighborKeys = function (lat, lng, level) { - return S2.S2Cell.FromLatLng({ lat: lat, lng: lng }, level).getNeighbors().map(function (cell) { - return cell.toHilbertQuadkey(); - }); -}; -S2.S2Cell.prototype.getNeighbors = function() { - - var fromFaceIJWrap = function(face,ij,level) { - var maxSize = (1<=0 && ij[1]>=0 && ij[0] levelN) { - posS = posS.substr(0, levelN); - } - - // 3-bit face value - faceB = Long.fromString(faceN.toString(10), true, 10).toString(2); - while (faceB.length < S2.FACE_BITS) { - faceB = '0' + faceB; - } - - // 60-bit position value - posB = Long.fromString(posS, true, 4).toString(2); - while (posB.length < (2 * levelN)) { - posB = '0' + posB; - } - - bin = faceB + posB; - // 1-bit lsb marker - bin += '1'; - // n-bit padding to 64-bits - while (bin.length < (S2.FACE_BITS + S2.POS_BITS)) { - bin += '0'; - } - - return Long.fromString(bin, true, 2).toSigned().toString(10); -}; - -S2.keyToId = S2.S2Cell.keyToId -= S2.toId = S2.toCellId = S2.fromKey -= function (key) { - var parts = key.split('/'); - - return S2.fromFacePosLevel(parts[0], parts[1], parts[1].length); -}; - -S2.idToKey = S2.S2Cell.idToKey -= S2.S2Cell.toKey = S2.toKey -= S2.fromId = S2.fromCellId -= S2.S2Cell.toHilbertQuadkey = S2.toHilbertQuadkey -= function (idS) { - var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long'); - var bin = Long.fromString(idS, true, 10).toString(2); - - while (bin.length < (S2.FACE_BITS + S2.POS_BITS)) { - bin = '0' + bin; - } - - // MUST come AFTER binstr has been left-padded with '0's - var lsbIndex = bin.lastIndexOf('1'); - // substr(start, len) - // substring(start, end) // includes start, does not include end - var faceB = bin.substring(0, 3); - // posB will always be a multiple of 2 (or it's invalid) - var posB = bin.substring(3, lsbIndex); - var levelN = posB.length / 2; - - var faceS = Long.fromString(faceB, true, 2).toString(10); - var posS = Long.fromString(posB, true, 2).toString(4); - - while (posS.length < levelN) { - posS = '0' + posS; - } - - return faceS + '/' + posS; -}; - -S2.keyToLatLng = S2.S2Cell.keyToLatLng = function (key) { - var cell2 = S2.S2Cell.FromHilbertQuadKey(key); - return cell2.getLatLng(); -}; - -S2.idToLatLng = S2.S2Cell.idToLatLng = function (id) { - var key = S2.idToKey(id); - return S2.keyToLatLng(key); -}; - -S2.S2Cell.latLngToKey = S2.latLngToKey -= S2.latLngToQuadkey = function (lat, lng, level) { - if (isNaN(level) || level < 1 || level > 30) { - throw new Error("'level' is not a number between 1 and 30 (but it should be)"); - } - // TODO - // - // S2.idToLatLng(id) - // S2.keyToLatLng(key) - // S2.nextFace(key) // prevent wrapping on nextKey - // S2.prevFace(key) // prevent wrapping on prevKey - // - // .toKeyArray(id) // face,quadtree - // .toKey(id) // hilbert - // .toPoint(id) // ij - // .toId(key) // uint64 (as string) - // .toLong(key) // long.js - // .toLatLng(id) // object? or array?, or string (with comma)? - // - // maybe S2.HQ.x, S2.GPS.x, S2.CI.x? - return S2.S2Cell.FromLatLng({ lat: lat, lng: lng }, level).toHilbertQuadkey(); -}; - -S2.stepKey = function (key, num) { - var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long'); - var parts = key.split('/'); - - var faceS = parts[0]; - var posS = parts[1]; - var level = parts[1].length; - - var posL = Long.fromString(posS, true, 4); - // TODO handle wrapping (0 === pos + 1) - // (only on the 12 edges of the globe) - var otherL; - if (num > 0) { - otherL = posL.add(Math.abs(num)); - } - else if (num < 0) { - otherL = posL.subtract(Math.abs(num)); - } - var otherS = otherL.toString(4); - - if ('0' === otherS) { - console.warning(new Error("face/position wrapping is not yet supported")); - } - - while (otherS.length < level) { - otherS = '0' + otherS; - } - - return faceS + '/' + otherS; -}; - -S2.S2Cell.prevKey = S2.prevKey = function (key) { - return S2.stepKey(key, -1); -}; - -S2.S2Cell.nextKey = S2.nextKey = function (key) { - return S2.stepKey(key, 1); -}; - -})('undefined' !== typeof module ? module.exports : window); -/* eslint-enable */ \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/accessors.test.js b/clouds/bigquery/libraries/javascript/test/accessors.test.js new file mode 100644 index 000000000..c233f5ac3 --- /dev/null +++ b/clouds/bigquery/libraries/javascript/test/accessors.test.js @@ -0,0 +1,7 @@ +const accessorsLib = require('../build/accessors'); + +test('accessors library defined', () => { + expect(accessorsLib.featureCollection).toBeDefined(); + expect(accessorsLib.feature).toBeDefined(); + expect(accessorsLib.envelope).toBeDefined(); +}); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/clustering.test.js b/clouds/bigquery/libraries/javascript/test/clustering.test.js index 0441d1608..4a2166d60 100644 --- a/clouds/bigquery/libraries/javascript/test/clustering.test.js +++ b/clouds/bigquery/libraries/javascript/test/clustering.test.js @@ -1,8 +1,8 @@ -const lib = require('../build/index'); +const clusteringLib = require('../build/clustering'); test('clustering library defined', () => { - expect(lib.clustering.featureCollection).toBeDefined(); - expect(lib.clustering.feature).toBeDefined(); - expect(lib.clustering.clustersKmeans).toBeDefined(); - expect(lib.clustering.prioritizeDistinctSort).toBeDefined(); + expect(clusteringLib.featureCollection).toBeDefined(); + expect(clusteringLib.feature).toBeDefined(); + expect(clusteringLib.clustersKmeans).toBeDefined(); + expect(clusteringLib.prioritizeDistinctSort).toBeDefined(); }); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/constructors.test.js b/clouds/bigquery/libraries/javascript/test/constructors.test.js new file mode 100644 index 000000000..3efd5d989 --- /dev/null +++ b/clouds/bigquery/libraries/javascript/test/constructors.test.js @@ -0,0 +1,6 @@ +const constructorsLib = require('../build/constructors'); + +test('constructors library defined', () => { + expect(constructorsLib.bezierSpline).toBeDefined(); + expect(constructorsLib.ellipse).toBeDefined(); +}); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/h3.test.js b/clouds/bigquery/libraries/javascript/test/h3.test.js new file mode 100644 index 000000000..80d1aedf3 --- /dev/null +++ b/clouds/bigquery/libraries/javascript/test/h3.test.js @@ -0,0 +1,17 @@ +const h3Lib = require('../build/h3'); + +test('h3 library defined', () => { + expect(h3Lib.geoToH3).toBeDefined(); + expect(h3Lib.compact).toBeDefined(); + expect(h3Lib.h3Distance).toBeDefined(); + expect(h3Lib.h3IsValid).toBeDefined(); + expect(h3Lib.hexRing).toBeDefined(); + expect(h3Lib.h3IsPentagon).toBeDefined(); + expect(h3Lib.kRing).toBeDefined(); + expect(h3Lib.kRingDistances).toBeDefined(); + expect(h3Lib.polyfill).toBeDefined(); + expect(h3Lib.h3ToGeoBoundary).toBeDefined(); + expect(h3Lib.h3ToChildren).toBeDefined(); + expect(h3Lib.h3ToParent).toBeDefined(); + expect(h3Lib.uncompact).toBeDefined(); +}); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/index.test.js b/clouds/bigquery/libraries/javascript/test/index.test.js deleted file mode 100644 index 23d66323c..000000000 --- a/clouds/bigquery/libraries/javascript/test/index.test.js +++ /dev/null @@ -1,81 +0,0 @@ -const lib = require('../build/index'); - -test('accessors library defined', () => { - expect(lib.accessors.featureCollection).toBeDefined(); - expect(lib.accessors.feature).toBeDefined(); - expect(lib.accessors.envelope).toBeDefined(); -}); - -test('constructors library defined', () => { - expect(lib.constructors.bezierSpline).toBeDefined(); - expect(lib.constructors.ellipse).toBeDefined(); -}); - -test('h3 library defined', () => { - expect(lib.h3.geoToH3).toBeDefined(); - expect(lib.h3.compact).toBeDefined(); - expect(lib.h3.h3Distance).toBeDefined(); - expect(lib.h3.h3IsValid).toBeDefined(); - expect(lib.h3.hexRing).toBeDefined(); - expect(lib.h3.h3IsPentagon).toBeDefined(); - expect(lib.h3.kRing).toBeDefined(); - expect(lib.h3.kRingDistances).toBeDefined(); - expect(lib.h3.polyfill).toBeDefined(); - expect(lib.h3.h3ToGeoBoundary).toBeDefined(); - expect(lib.h3.h3ToChildren).toBeDefined(); - expect(lib.h3.h3ToParent).toBeDefined(); - expect(lib.h3.uncompact).toBeDefined(); -}); - -test('measurements library defined', () => { - expect(lib.measurements.angle).toBeDefined(); - expect(lib.measurements.bearing).toBeDefined(); - expect(lib.measurements.featureCollection).toBeDefined(); - expect(lib.measurements.feature).toBeDefined(); - expect(lib.measurements.distanceWeight).toBeDefined(); -}); - -test('placekey library defined', () => { - expect(lib.placekey.placekeyIsValid).toBeDefined(); - expect(lib.placekey.h3ToPlacekey).toBeDefined(); - expect(lib.placekey.placekeyToH3).toBeDefined(); -}); - -test('processing library defined', () => { - expect(lib.processing.featureCollection).toBeDefined(); - expect(lib.processing.feature).toBeDefined(); - expect(lib.processing.voronoi).toBeDefined(); - expect(lib.processing.polygonToLine).toBeDefined(); -}); - -test('quadkey library defined', () => { - expect(lib.quadkey.bbox).toBeDefined(); - expect(lib.quadkey.toChildren).toBeDefined(); - expect(lib.quadkey.quadkeyFromQuadint).toBeDefined(); - expect(lib.quadkey.quadintFromQuadkey).toBeDefined(); - expect(lib.quadkey.quadintFromLocation).toBeDefined(); - expect(lib.quadkey.quadintToGeoJSON).toBeDefined(); - expect(lib.quadkey.geojsonToQuadints).toBeDefined(); - expect(lib.quadkey.ZXYFromQuadint).toBeDefined(); -}); - -test('s2 library defined', () => { - expect(lib.s2.keyToId).toBeDefined(); - expect(lib.s2.idToKey).toBeDefined(); - expect(lib.s2.latLngToKey).toBeDefined(); - expect(lib.s2.FromHilbertQuadKey).toBeDefined(); - expect(lib.s2.idToLatLng).toBeDefined(); -}); - -test('transformations library defined', () => { - expect(lib.transformations.featureCollection).toBeDefined(); - expect(lib.transformations.feature).toBeDefined(); - expect(lib.transformations.buffer).toBeDefined(); - expect(lib.transformations.centerMean).toBeDefined(); - expect(lib.transformations.centerMedian).toBeDefined(); - expect(lib.transformations.centerOfMass).toBeDefined(); - expect(lib.transformations.concave).toBeDefined(); - expect(lib.transformations.destination).toBeDefined(); - expect(lib.transformations.greatCircle).toBeDefined(); - expect(lib.transformations.along).toBeDefined(); -}); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/measurements.test.js b/clouds/bigquery/libraries/javascript/test/measurements.test.js new file mode 100644 index 000000000..e626382da --- /dev/null +++ b/clouds/bigquery/libraries/javascript/test/measurements.test.js @@ -0,0 +1,9 @@ +const measurementsLib = require('../build/measurements'); + +test('measurements library defined', () => { + expect(measurementsLib.angle).toBeDefined(); + expect(measurementsLib.bearing).toBeDefined(); + expect(measurementsLib.featureCollection).toBeDefined(); + expect(measurementsLib.feature).toBeDefined(); + expect(measurementsLib.distanceWeight).toBeDefined(); +}); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/placekey.test.js b/clouds/bigquery/libraries/javascript/test/placekey.test.js new file mode 100644 index 000000000..11b71f57d --- /dev/null +++ b/clouds/bigquery/libraries/javascript/test/placekey.test.js @@ -0,0 +1,7 @@ +const placekeyLib = require('../build/placekey'); + +test('placekey library defined', () => { + expect(placekeyLib.placekeyIsValid).toBeDefined(); + expect(placekeyLib.h3ToPlacekey).toBeDefined(); + expect(placekeyLib.placekeyToH3).toBeDefined(); +}); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/processing.test.js b/clouds/bigquery/libraries/javascript/test/processing.test.js new file mode 100644 index 000000000..07c5eb9ea --- /dev/null +++ b/clouds/bigquery/libraries/javascript/test/processing.test.js @@ -0,0 +1,8 @@ +const processingLib = require('../build/processing'); + +test('processing library defined', () => { + expect(processingLib.featureCollection).toBeDefined(); + expect(processingLib.feature).toBeDefined(); + expect(processingLib.voronoi).toBeDefined(); + expect(processingLib.polygonToLine).toBeDefined(); +}); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/quadkey.test.js b/clouds/bigquery/libraries/javascript/test/quadkey.test.js index 942731ce3..a97ab67df 100644 --- a/clouds/bigquery/libraries/javascript/test/quadkey.test.js +++ b/clouds/bigquery/libraries/javascript/test/quadkey.test.js @@ -1,12 +1,23 @@ -const lib = require('../build/index'); +const quadkeyLib = require('../build/quadkey'); // TODO: refactor tests +test('quadkey library defined', () => { + expect(quadkeyLib.bbox).toBeDefined(); + expect(quadkeyLib.toChildren).toBeDefined(); + expect(quadkeyLib.quadkeyFromQuadint).toBeDefined(); + expect(quadkeyLib.quadintFromQuadkey).toBeDefined(); + expect(quadkeyLib.quadintFromLocation).toBeDefined(); + expect(quadkeyLib.quadintToGeoJSON).toBeDefined(); + expect(quadkeyLib.geojsonToQuadints).toBeDefined(); + expect(quadkeyLib.ZXYFromQuadint).toBeDefined(); +}); + test('bbox should work', () => { - expect(lib.quadkey.bbox(162)).toEqual([-90, 0, 0, 66.51326044311186]); - expect(lib.quadkey.bbox(12070922)).toEqual([-45, 44.840290651397986, -44.6484375, 45.08903556483103]); - expect(lib.quadkey.bbox(791040491538)).toEqual([-45, 44.99976701918129, -44.998626708984375, 45.00073807829068]); - expect(lib.quadkey.bbox(12960460429066265n)).toEqual([-45, 44.999994612636684, -44.99998927116394, 45.00000219906962]); + expect(quadkeyLib.bbox(162)).toEqual([-90, 0, 0, 66.51326044311186]); + expect(quadkeyLib.bbox(12070922)).toEqual([-45, 44.840290651397986, -44.6484375, 45.08903556483103]); + expect(quadkeyLib.bbox(791040491538)).toEqual([-45, 44.99976701918129, -44.998626708984375, 45.00073807829068]); + expect(quadkeyLib.bbox(12960460429066265n)).toEqual([-45, 44.999994612636684, -44.99998927116394, 45.00000219906962]); }); test('toParent should work at any level of zoom', () => { @@ -14,27 +25,27 @@ test('toParent should work at any level of zoom', () => { for (z = 1; z < 30; ++z) { for (lat = -90; lat <= 90; lat = lat + 15) { for (lng = -180; lng <= 180; lng = lng + 15) { - const quadint = lib.quadkey.quadintFromLocation(lng, lat, z); - const currentParent = lib.quadkey.quadintFromLocation(lng, lat, z - 1); - expect(currentParent).toEqual(lib.quadkey.toParent(quadint, z - 1)); + const quadint = quadkeyLib.quadintFromLocation(lng, lat, z); + const currentParent = quadkeyLib.quadintFromLocation(lng, lat, z - 1); + expect(currentParent).toEqual(quadkeyLib.toParent(quadint, z - 1)); } } } for (z = 5; z < 30; ++z) { for (lat = -90; lat <= 90; lat = lat + 15) { for (lng = -180; lng <= 180; lng = lng + 15) { - const quadint = lib.quadkey.quadintFromLocation(lng, lat, z); - const currentParent = lib.quadkey.quadintFromLocation(lng, lat, z - 5); - expect(currentParent).toEqual(lib.quadkey.toParent(quadint, z - 5)); + const quadint = quadkeyLib.quadintFromLocation(lng, lat, z); + const currentParent = quadkeyLib.quadintFromLocation(lng, lat, z - 5); + expect(currentParent).toEqual(quadkeyLib.toParent(quadint, z - 5)); } } } for (z = 10; z < 30; ++z) { for (lat = -90; lat <= 90; lat = lat + 15) { for (lng = -180; lng <= 180; lng = lng + 15) { - const quadint = lib.quadkey.quadintFromLocation(lng, lat, z); - const currentParent = lib.quadkey.quadintFromLocation(lng, lat, z - 10); - expect(currentParent).toEqual(lib.quadkey.toParent(quadint, z - 10)); + const quadint = quadkeyLib.quadintFromLocation(lng, lat, z); + const currentParent = quadkeyLib.quadintFromLocation(lng, lat, z - 10); + expect(currentParent).toEqual(quadkeyLib.toParent(quadint, z - 10)); } } } @@ -45,10 +56,10 @@ test('toChildren should work at any level of zoom', () => { for (z = 0; z < 29; ++z) { for (lat = 90; lat <= 90; lat = lat + 15) { for (lng = -180; lng <= 180; lng = lng + 15) { - const quadint = lib.quadkey.quadintFromLocation(lng, lat, z); - const childs = lib.quadkey.toChildren(quadint, z + 1); + const quadint = quadkeyLib.quadintFromLocation(lng, lat, z); + const childs = quadkeyLib.toChildren(quadint, z + 1); childs.forEach((element) => { - expect(lib.quadkey.toParent(element, z)).toEqual(quadint); + expect(quadkeyLib.toParent(element, z)).toEqual(quadint); }); } } @@ -57,10 +68,10 @@ test('toChildren should work at any level of zoom', () => { for (z = 0; z < 25; ++z) { for (lat = 90; lat <= 90; lat = lat + 15) { for (lng = -180; lng <= 180; lng = lng + 15) { - const quadint = lib.quadkey.quadintFromLocation(lng, lat, z); - const childs = lib.quadkey.toChildren(quadint, z + 5); + const quadint = quadkeyLib.quadintFromLocation(lng, lat, z); + const childs = quadkeyLib.toChildren(quadint, z + 5); childs.forEach((element) => { - expect(lib.quadkey.toParent(element, z)).toEqual(quadint); + expect(quadkeyLib.toParent(element, z)).toEqual(quadint); }); } } @@ -78,7 +89,7 @@ test('Should be able to encode/decode between quadint and quadkey at any level o x = 0; y = 0; - let zxyDecoded = lib.quadkey.ZXYFromQuadint(lib.quadkey.quadintFromQuadkey(lib.quadkey.quadkeyFromQuadint(lib.quadkey.quadintFromZXY(z, x, y)))); + let zxyDecoded = quadkeyLib.ZXYFromQuadint(quadkeyLib.quadintFromQuadkey(quadkeyLib.quadkeyFromQuadint(quadkeyLib.quadintFromZXY(z, x, y)))); zDecoded = zxyDecoded.z; xDecoded = zxyDecoded.x; yDecoded = zxyDecoded.y; @@ -87,7 +98,7 @@ test('Should be able to encode/decode between quadint and quadkey at any level o if (z > 0) { x = tilesPerLevel / 2; y = tilesPerLevel / 2; - zxyDecoded = lib.quadkey.ZXYFromQuadint(lib.quadkey.quadintFromQuadkey(lib.quadkey.quadkeyFromQuadint(lib.quadkey.quadintFromZXY(z, x, y)))); + zxyDecoded = quadkeyLib.ZXYFromQuadint(quadkeyLib.quadintFromQuadkey(quadkeyLib.quadkeyFromQuadint(quadkeyLib.quadintFromZXY(z, x, y)))); zDecoded = zxyDecoded.z; xDecoded = zxyDecoded.x; yDecoded = zxyDecoded.y; @@ -95,7 +106,7 @@ test('Should be able to encode/decode between quadint and quadkey at any level o x = tilesPerLevel - 1; y = tilesPerLevel - 1; - zxyDecoded = lib.quadkey.ZXYFromQuadint(lib.quadkey.quadintFromQuadkey(lib.quadkey.quadkeyFromQuadint(lib.quadkey.quadintFromZXY(z, x, y)))); + zxyDecoded = quadkeyLib.ZXYFromQuadint(quadkeyLib.quadintFromQuadkey(quadkeyLib.quadkeyFromQuadint(quadkeyLib.quadintFromZXY(z, x, y)))); zDecoded = zxyDecoded.z; xDecoded = zxyDecoded.x; yDecoded = zxyDecoded.y; @@ -115,7 +126,7 @@ test('Should be able to encode/decode tiles at any level of zoom', async () => { x = 0; y = 0; - let zxyDecoded = lib.quadkey.ZXYFromQuadint(lib.quadkey.quadintFromZXY(z, x, y)); + let zxyDecoded = quadkeyLib.ZXYFromQuadint(quadkeyLib.quadintFromZXY(z, x, y)); zDecoded = zxyDecoded.z; xDecoded = zxyDecoded.x; yDecoded = zxyDecoded.y; @@ -124,7 +135,7 @@ test('Should be able to encode/decode tiles at any level of zoom', async () => { if (z > 0) { x = tilesPerLevel / 2; y = tilesPerLevel / 2; - zxyDecoded = lib.quadkey.ZXYFromQuadint(lib.quadkey.quadintFromZXY(z, x, y)); + zxyDecoded = quadkeyLib.ZXYFromQuadint(quadkeyLib.quadintFromZXY(z, x, y)); zDecoded = zxyDecoded.z; xDecoded = zxyDecoded.x; yDecoded = zxyDecoded.y; @@ -132,7 +143,7 @@ test('Should be able to encode/decode tiles at any level of zoom', async () => { x = tilesPerLevel - 1; y = tilesPerLevel - 1; - zxyDecoded = lib.quadkey.ZXYFromQuadint(lib.quadkey.quadintFromZXY(z, x, y)); + zxyDecoded = quadkeyLib.ZXYFromQuadint(quadkeyLib.quadintFromZXY(z, x, y)); zDecoded = zxyDecoded.z; xDecoded = zxyDecoded.x; yDecoded = zxyDecoded.y; diff --git a/clouds/bigquery/libraries/javascript/test/random.test.js b/clouds/bigquery/libraries/javascript/test/random.test.js index f21b4dd35..4a02d3648 100644 --- a/clouds/bigquery/libraries/javascript/test/random.test.js +++ b/clouds/bigquery/libraries/javascript/test/random.test.js @@ -1,5 +1,5 @@ -const lib = require('../build/index'); +const randomLib = require('../build/random'); test('random library defined', () => { - expect(lib.random.generateRandomPointsInPolygon).toBeDefined(); + expect(randomLib.generateRandomPointsInPolygon).toBeDefined(); }); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/s2.test.js b/clouds/bigquery/libraries/javascript/test/s2.test.js new file mode 100644 index 000000000..e5381e717 --- /dev/null +++ b/clouds/bigquery/libraries/javascript/test/s2.test.js @@ -0,0 +1,9 @@ +const s2Lib = require('../build/s2'); + +test('s2 library defined', () => { + expect(s2Lib.keyToId).toBeDefined(); + expect(s2Lib.idToKey).toBeDefined(); + expect(s2Lib.latLngToKey).toBeDefined(); + expect(s2Lib.FromHilbertQuadKey).toBeDefined(); + expect(s2Lib.idToLatLng).toBeDefined(); +}); \ No newline at end of file diff --git a/clouds/bigquery/libraries/javascript/test/transformations.test.js b/clouds/bigquery/libraries/javascript/test/transformations.test.js new file mode 100644 index 000000000..7a9ee511e --- /dev/null +++ b/clouds/bigquery/libraries/javascript/test/transformations.test.js @@ -0,0 +1,14 @@ +const transformationsLib = require('../build/transformations'); + +test('transformations library defined', () => { + expect(transformationsLib.featureCollection).toBeDefined(); + expect(transformationsLib.feature).toBeDefined(); + expect(transformationsLib.buffer).toBeDefined(); + expect(transformationsLib.centerMean).toBeDefined(); + expect(transformationsLib.centerMedian).toBeDefined(); + expect(transformationsLib.centerOfMass).toBeDefined(); + expect(transformationsLib.concave).toBeDefined(); + expect(transformationsLib.destination).toBeDefined(); + expect(transformationsLib.greatCircle).toBeDefined(); + expect(transformationsLib.along).toBeDefined(); +}); \ No newline at end of file diff --git a/clouds/bigquery/modules/Makefile b/clouds/bigquery/modules/Makefile index 61892d7b8..877caaa64 100644 --- a/clouds/bigquery/modules/Makefile +++ b/clouds/bigquery/modules/Makefile @@ -28,7 +28,7 @@ endif BQ_MODULE_LABEL ?= spatial_extension_module:core MODULE_PERMISSIONS_BASH ?= set_module_permissions.sh -REPLACEMENTS = "BQ_DATASET BQ_VERSION_FUNCTION BQ_PACKAGE_VERSION BQ_LIBRARY_BUCKET BQ_PROJECT BQ_REGION" +REPLACEMENTS = "BQ_DATASET BQ_VERSION_FUNCTION BQ_PACKAGE_VERSION BQ_PROJECT BQ_REGION" include $(COMMON_DIR)/Makefile @@ -57,7 +57,7 @@ build: $(NODE_MODULES_DEV) REPLACEMENTS=$(REPLACEMENTS)" "$(REPLACEMENTS_EXTRA) \ $(COMMON_DIR)/build_modules.js $(MODULES_DIRS) \ --output=$(BUILD_DIR) --libs_build_dir=$(LIBS_BUILD_DIR) --diff="$(diff)" \ - --modules=$(modules) --functions=$(functions) --production=$(production) --nodeps=$(nodeps) --dropfirst=$(dropfirst) + --modules=$(modules) --functions=$(functions) --production=$(production) --nodeps=$(nodeps) --dropfirst=$(dropfirst) --librarybucket=$(BQ_LIBRARY_BUCKET) --makelib=$(MAKE_LIB) deploy: check build echo "Deploying modules..." diff --git a/clouds/bigquery/modules/sql/accessors/ST_ENVELOPE.sql b/clouds/bigquery/modules/sql/accessors/ST_ENVELOPE.sql index 21426549e..149d5009b 100644 --- a/clouds/bigquery/modules/sql/accessors/ST_ENVELOPE.sql +++ b/clouds/bigquery/modules/sql/accessors/ST_ENVELOPE.sql @@ -8,15 +8,15 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_ACCESSORS_BUCKET@@"] ) AS """ if (!geojson) { return null; } - const featuresCollection = lib.accessors.featureCollection(geojson.map(x => lib.accessors.feature(JSON.parse(x)))); - const enveloped = lib.accessors.envelope(featuresCollection); + const featuresCollection = accessorsLib.featureCollection(geojson.map(x => accessorsLib.feature(JSON.parse(x)))); + const enveloped = accessorsLib.envelope(featuresCollection); return JSON.stringify(enveloped.geometry); """; diff --git a/clouds/bigquery/modules/sql/clustering/ST_CLUSTERKMEANS.sql b/clouds/bigquery/modules/sql/clustering/ST_CLUSTERKMEANS.sql index 3a84db951..109b67a51 100644 --- a/clouds/bigquery/modules/sql/clustering/ST_CLUSTERKMEANS.sql +++ b/clouds/bigquery/modules/sql/clustering/ST_CLUSTERKMEANS.sql @@ -7,7 +7,7 @@ CREATE OR REPLACE FUNCTION `@@BQ_DATASET@@.__CLUSTERKMEANS` RETURNS ARRAY> DETERMINISTIC LANGUAGE js -OPTIONS (library = ["@@BQ_LIBRARY_BUCKET@@"]) +OPTIONS (library = ["@@BQ_LIBRARY_CLUSTERING_BUCKET@@"]) AS """ if (!geojson) { return null; @@ -19,8 +19,8 @@ AS """ options.numberOfClusters = parseInt(Math.sqrt(geojson.length/2)) } options.mutate = true; - const featuresCollection = lib.clustering.featureCollection(lib.clustering.prioritizeDistinctSort(geojson).map(x => lib.clustering.feature(JSON.parse(x)))); - lib.clustering.clustersKmeans(featuresCollection, options); + const featuresCollection = clusteringLib.featureCollection(clusteringLib.prioritizeDistinctSort(geojson).map(x => clusteringLib.feature(JSON.parse(x)))); + clusteringLib.clustersKmeans(featuresCollection, options); const cluster = []; featuresCollection.features.forEach(function(item, index, array) { cluster.push({cluster: item.properties.cluster, geom: JSON.stringify(item.geometry)}); diff --git a/clouds/bigquery/modules/sql/constructors/ST_BEZIERSPLINE.sql b/clouds/bigquery/modules/sql/constructors/ST_BEZIERSPLINE.sql index 91898fcce..f50e2ee45 100644 --- a/clouds/bigquery/modules/sql/constructors/ST_BEZIERSPLINE.sql +++ b/clouds/bigquery/modules/sql/constructors/ST_BEZIERSPLINE.sql @@ -8,7 +8,7 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_CONSTRUCTORS_BUCKET@@"] ) AS """ if (!geojson) { @@ -21,7 +21,7 @@ AS """ if (sharpness != null) { options.sharpness = Number(sharpness); } - const curved = lib.constructors.bezierSpline(JSON.parse(geojson), options); + const curved = constructorsLib.bezierSpline(JSON.parse(geojson), options); return JSON.stringify(curved.geometry); """; diff --git a/clouds/bigquery/modules/sql/constructors/ST_MAKEELLIPSE.sql b/clouds/bigquery/modules/sql/constructors/ST_MAKEELLIPSE.sql index b72e5d255..62bab28c6 100644 --- a/clouds/bigquery/modules/sql/constructors/ST_MAKEELLIPSE.sql +++ b/clouds/bigquery/modules/sql/constructors/ST_MAKEELLIPSE.sql @@ -15,7 +15,7 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_CONSTRUCTORS_BUCKET@@"] ) AS """ if (!geojson || xSemiAxis == null || ySemiAxis == null) { @@ -31,7 +31,7 @@ AS """ if (steps != null) { options.steps = Number(steps); } - const ellipse = lib.constructors.ellipse(JSON.parse(geojson), Number(xSemiAxis), Number(ySemiAxis), options); + const ellipse = constructorsLib.ellipse(JSON.parse(geojson), Number(xSemiAxis), Number(ySemiAxis), options); return JSON.stringify(ellipse.geometry); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_BOUNDARY.sql b/clouds/bigquery/modules/sql/h3/H3_BOUNDARY.sql index 81d6c7841..7de740d5b 100644 --- a/clouds/bigquery/modules/sql/h3/H3_BOUNDARY.sql +++ b/clouds/bigquery/modules/sql/h3/H3_BOUNDARY.sql @@ -8,18 +8,18 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (!index) { return null; } - if (!lib.h3.h3IsValid(index)) { + if (!h3Lib.h3IsValid(index)) { return null; } - const coords = lib.h3.h3ToGeoBoundary(index, true); + const coords = h3Lib.h3ToGeoBoundary(index, true); let output = `POLYGON((`; for (let i = 0; i < coords.length - 1; i++) { output += coords[i][0] + ` ` + coords[i][1] + `,`; diff --git a/clouds/bigquery/modules/sql/h3/H3_CENTER.sql b/clouds/bigquery/modules/sql/h3/H3_CENTER.sql index 7c6ec43c3..072de1509 100644 --- a/clouds/bigquery/modules/sql/h3/H3_CENTER.sql +++ b/clouds/bigquery/modules/sql/h3/H3_CENTER.sql @@ -8,18 +8,18 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (!index) { return null; } - if (!lib.h3.h3IsValid(index)) { + if (!h3Lib.h3IsValid(index)) { return null; } - const center = lib.h3.h3ToGeo(index); + const center = h3Lib.h3ToGeo(index); return `POINT(`+center[1] + ` ` + center[0] + `)`; """; diff --git a/clouds/bigquery/modules/sql/h3/H3_COMPACT.sql b/clouds/bigquery/modules/sql/h3/H3_COMPACT.sql index f7e51887c..77c3755e3 100644 --- a/clouds/bigquery/modules/sql/h3/H3_COMPACT.sql +++ b/clouds/bigquery/modules/sql/h3/H3_COMPACT.sql @@ -8,11 +8,11 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (h3Array === null) { return null; } - return lib.h3.compact(h3Array); + return h3Lib.compact(h3Array); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_DISTANCE.sql b/clouds/bigquery/modules/sql/h3/H3_DISTANCE.sql index c775a3648..635d237b9 100644 --- a/clouds/bigquery/modules/sql/h3/H3_DISTANCE.sql +++ b/clouds/bigquery/modules/sql/h3/H3_DISTANCE.sql @@ -8,13 +8,13 @@ RETURNS INT64 DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (!index1 || !index2) { return null; } - let dist = lib.h3.h3Distance(index1, index2); + let dist = h3Lib.h3Distance(index1, index2); if (dist < 0) { dist = null; } diff --git a/clouds/bigquery/modules/sql/h3/H3_FROMLONGLAT.sql b/clouds/bigquery/modules/sql/h3/H3_FROMLONGLAT.sql index 66e1007fa..0e3ae58b9 100644 --- a/clouds/bigquery/modules/sql/h3/H3_FROMLONGLAT.sql +++ b/clouds/bigquery/modules/sql/h3/H3_FROMLONGLAT.sql @@ -8,11 +8,11 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (longitude === null || latitude === null || resolution === null) { return null; } - return lib.h3.geoToH3(Number(latitude), Number(longitude), Number(resolution)); + return h3Lib.geoToH3(Number(latitude), Number(longitude), Number(resolution)); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_HEXRING.sql b/clouds/bigquery/modules/sql/h3/H3_HEXRING.sql index fd3d0ea7b..85bf8a951 100644 --- a/clouds/bigquery/modules/sql/h3/H3_HEXRING.sql +++ b/clouds/bigquery/modules/sql/h3/H3_HEXRING.sql @@ -8,14 +8,14 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ - if (!lib.h3.h3IsValid(origin)) { + if (!h3Lib.h3IsValid(origin)) { throw new Error('Invalid input origin') } if (size == null || size < 0) { throw new Error('Invalid input size') } - return lib.h3.hexRing(origin, parseInt(size)); + return h3Lib.hexRing(origin, parseInt(size)); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_ISPENTAGON.sql b/clouds/bigquery/modules/sql/h3/H3_ISPENTAGON.sql index 87a506799..e3eb67c82 100644 --- a/clouds/bigquery/modules/sql/h3/H3_ISPENTAGON.sql +++ b/clouds/bigquery/modules/sql/h3/H3_ISPENTAGON.sql @@ -8,11 +8,11 @@ RETURNS BOOLEAN DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (!index) { return false; } - return lib.h3.h3IsPentagon(index); + return h3Lib.h3IsPentagon(index); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_ISVALID.sql b/clouds/bigquery/modules/sql/h3/H3_ISVALID.sql index f7a5feecf..596ccc659 100644 --- a/clouds/bigquery/modules/sql/h3/H3_ISVALID.sql +++ b/clouds/bigquery/modules/sql/h3/H3_ISVALID.sql @@ -8,11 +8,11 @@ RETURNS BOOLEAN DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (!index) { return false; } - return lib.h3.h3IsValid(index); + return h3Lib.h3IsValid(index); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_KRING.sql b/clouds/bigquery/modules/sql/h3/H3_KRING.sql index cc759286e..edf8a2f22 100644 --- a/clouds/bigquery/modules/sql/h3/H3_KRING.sql +++ b/clouds/bigquery/modules/sql/h3/H3_KRING.sql @@ -8,14 +8,14 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ - if (!lib.h3.h3IsValid(origin)) { + if (!h3Lib.h3IsValid(origin)) { throw new Error('Invalid input origin') } if (size == null || size < 0) { throw new Error('Invalid input size') } - return lib.h3.kRing(origin, parseInt(size)); + return h3Lib.kRing(origin, parseInt(size)); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_KRING_DISTANCES.sql b/clouds/bigquery/modules/sql/h3/H3_KRING_DISTANCES.sql index 3ba661433..60c03a6ae 100644 --- a/clouds/bigquery/modules/sql/h3/H3_KRING_DISTANCES.sql +++ b/clouds/bigquery/modules/sql/h3/H3_KRING_DISTANCES.sql @@ -8,16 +8,16 @@ RETURNS ARRAY> DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ - if (!lib.h3.h3IsValid(origin)) { + if (!h3Lib.h3IsValid(origin)) { throw new Error('Invalid input origin') } if (size == null || size < 0) { throw new Error('Invalid input size') } - const kringDistances = lib.h3.kRingDistances(origin, size); + const kringDistances = h3Lib.kRingDistances(origin, size); const output = []; for (let distance = 0; distance <= size; distance++) { const indexes = kringDistances[distance]; diff --git a/clouds/bigquery/modules/sql/h3/H3_POLYFILL.sql b/clouds/bigquery/modules/sql/h3/H3_POLYFILL.sql index 581d39bc7..c37b2e6ee 100644 --- a/clouds/bigquery/modules/sql/h3/H3_POLYFILL.sql +++ b/clouds/bigquery/modules/sql/h3/H3_POLYFILL.sql @@ -8,7 +8,7 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ const resolution = Number(_resolution) @@ -21,28 +21,28 @@ AS """ case 'GeometryCollection': featureGeometry.geometries.forEach(function (geom) { if (geom.type === 'MultiPolygon') { - var clippedGeometryA = lib.h3.bboxClip(geom, bboxA).geometry + var clippedGeometryA = h3Lib.bboxClip(geom, bboxA).geometry polygonCoordinatesA = polygonCoordinatesA.concat(clippedGeometryA.coordinates) - var clippedGeometryB = lib.h3.bboxClip(geom, bboxB).geometry + var clippedGeometryB = h3Lib.bboxClip(geom, bboxB).geometry polygonCoordinatesB = polygonCoordinatesB.concat(clippedGeometryB.coordinates) } else if (geom.type === 'Polygon') { - var clippedGeometryA = lib.h3.bboxClip(geom, bboxA).geometry + var clippedGeometryA = h3Lib.bboxClip(geom, bboxA).geometry polygonCoordinatesA = polygonCoordinatesA.concat([clippedGeometryA.coordinates]) - var clippedGeometryB = lib.h3.bboxClip(geom, bboxB).geometry + var clippedGeometryB = h3Lib.bboxClip(geom, bboxB).geometry polygonCoordinatesB = polygonCoordinatesB.concat([clippedGeometryB.coordinates]) } }) break case 'MultiPolygon': - var clippedGeometryA = lib.h3.bboxClip(featureGeometry, bboxA).geometry + var clippedGeometryA = h3Lib.bboxClip(featureGeometry, bboxA).geometry polygonCoordinatesA = clippedGeometryA.coordinates - var clippedGeometryB = lib.h3.bboxClip(featureGeometry, bboxB).geometry + var clippedGeometryB = h3Lib.bboxClip(featureGeometry, bboxB).geometry polygonCoordinatesB = clippedGeometryB.coordinates break case 'Polygon': - var clippedGeometryA = lib.h3.bboxClip(featureGeometry, bboxA).geometry + var clippedGeometryA = h3Lib.bboxClip(featureGeometry, bboxA).geometry polygonCoordinatesA = [clippedGeometryA.coordinates] - var clippedGeometryB = lib.h3.bboxClip(featureGeometry, bboxB).geometry + var clippedGeometryB = h3Lib.bboxClip(featureGeometry, bboxB).geometry polygonCoordinatesB = [clippedGeometryB.coordinates] break default: @@ -54,11 +54,11 @@ AS """ } let hexesA = polygonCoordinatesA.reduce( - (acc, coordinates) => acc.concat(lib.h3.polyfill(coordinates, resolution, true)), + (acc, coordinates) => acc.concat(h3Lib.polyfill(coordinates, resolution, true)), [] ).filter(h => h != null) let hexesB = polygonCoordinatesB.reduce( - (acc, coordinates) => acc.concat(lib.h3.polyfill(coordinates, resolution, true)), + (acc, coordinates) => acc.concat(h3Lib.polyfill(coordinates, resolution, true)), [] ).filter(h => h != null) hexes = [...hexesA, ...hexesB] diff --git a/clouds/bigquery/modules/sql/h3/H3_RESOLUTION.sql b/clouds/bigquery/modules/sql/h3/H3_RESOLUTION.sql index d296809c2..dd5ee3e8b 100644 --- a/clouds/bigquery/modules/sql/h3/H3_RESOLUTION.sql +++ b/clouds/bigquery/modules/sql/h3/H3_RESOLUTION.sql @@ -8,16 +8,16 @@ RETURNS INT64 DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (!index) { return null; } - if (!lib.h3.h3IsValid(index)) { + if (!h3Lib.h3IsValid(index)) { return null; } - return lib.h3.h3GetResolution(index); + return h3Lib.h3GetResolution(index); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_TOCHILDREN.sql b/clouds/bigquery/modules/sql/h3/H3_TOCHILDREN.sql index 7ad375f91..ecc9a0956 100644 --- a/clouds/bigquery/modules/sql/h3/H3_TOCHILDREN.sql +++ b/clouds/bigquery/modules/sql/h3/H3_TOCHILDREN.sql @@ -8,14 +8,14 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (!index) { return null; } - if (!lib.h3.h3IsValid(index)) { + if (!h3Lib.h3IsValid(index)) { return null; } - return lib.h3.h3ToChildren(index, Number(resolution)); + return h3Lib.h3ToChildren(index, Number(resolution)); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_TOPARENT.sql b/clouds/bigquery/modules/sql/h3/H3_TOPARENT.sql index f1a0252c3..2ecb09379 100644 --- a/clouds/bigquery/modules/sql/h3/H3_TOPARENT.sql +++ b/clouds/bigquery/modules/sql/h3/H3_TOPARENT.sql @@ -8,14 +8,14 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (!index) { return null; } - if (!lib.h3.h3IsValid(index)) { + if (!h3Lib.h3IsValid(index)) { return null; } - return lib.h3.h3ToParent(index, Number(resolution)); + return h3Lib.h3ToParent(index, Number(resolution)); """; diff --git a/clouds/bigquery/modules/sql/h3/H3_UNCOMPACT.sql b/clouds/bigquery/modules/sql/h3/H3_UNCOMPACT.sql index 6ef711b99..e560dd468 100644 --- a/clouds/bigquery/modules/sql/h3/H3_UNCOMPACT.sql +++ b/clouds/bigquery/modules/sql/h3/H3_UNCOMPACT.sql @@ -8,11 +8,11 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_H3_BUCKET@@"] ) AS """ if (h3Array === null || resolution === null || resolution < 0 || resolution > 15) { return null; } - return lib.h3.uncompact(h3Array, Number(resolution)); + return h3Lib.uncompact(h3Array, Number(resolution)); """; diff --git a/clouds/bigquery/modules/sql/measurements/ST_ANGLE.sql b/clouds/bigquery/modules/sql/measurements/ST_ANGLE.sql index 97fd17e8a..e4059b1a0 100644 --- a/clouds/bigquery/modules/sql/measurements/ST_ANGLE.sql +++ b/clouds/bigquery/modules/sql/measurements/ST_ANGLE.sql @@ -8,7 +8,7 @@ RETURNS FLOAT64 DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_MEASUREMENTS_BUCKET@@"] ) AS """ if (!geojsonStart || !geojsonMid || !geojsonEnd) { @@ -18,7 +18,7 @@ AS """ if(mercator != null) { options.mercator = mercator; } - return lib.measurements.angle(JSON.parse(geojsonStart), JSON.parse(geojsonMid), JSON.parse(geojsonEnd), options); + return measurementsLib.angle(JSON.parse(geojsonStart), JSON.parse(geojsonMid), JSON.parse(geojsonEnd), options); """; CREATE OR REPLACE FUNCTION `@@BQ_DATASET@@.ST_ANGLE` diff --git a/clouds/bigquery/modules/sql/measurements/ST_MINKOWSKIDISTANCE.sql b/clouds/bigquery/modules/sql/measurements/ST_MINKOWSKIDISTANCE.sql index 5a0c7d826..2e448e14e 100644 --- a/clouds/bigquery/modules/sql/measurements/ST_MINKOWSKIDISTANCE.sql +++ b/clouds/bigquery/modules/sql/measurements/ST_MINKOWSKIDISTANCE.sql @@ -8,7 +8,7 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_MEASUREMENTS_BUCKET@@"] ) AS """ if (!geojson) { @@ -18,8 +18,8 @@ AS """ if(p != null) { options.p = Number(p); } - const features = lib.measurements.featureCollection(geojson.map(x => lib.measurements.feature(JSON.parse(x)))); - const distance = lib.measurements.distanceWeight(features, options); + const features = measurementsLib.featureCollection(geojson.map(x => measurementsLib.feature(JSON.parse(x)))); + const distance = measurementsLib.distanceWeight(features, options); return distance; """; diff --git a/clouds/bigquery/modules/sql/placekey/PLACEKEY_FROMH3.sql b/clouds/bigquery/modules/sql/placekey/PLACEKEY_FROMH3.sql index ea1857052..913af2afb 100644 --- a/clouds/bigquery/modules/sql/placekey/PLACEKEY_FROMH3.sql +++ b/clouds/bigquery/modules/sql/placekey/PLACEKEY_FROMH3.sql @@ -9,10 +9,10 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_PLACEKEY_BUCKET@@"] ) AS """ - return lib.placekey.h3ToPlacekey(h3Index); + return placekeyLib.h3ToPlacekey(h3Index); """; CREATE OR REPLACE FUNCTION `@@BQ_DATASET@@.PLACEKEY_FROMH3` diff --git a/clouds/bigquery/modules/sql/placekey/PLACEKEY_ISVALID.sql b/clouds/bigquery/modules/sql/placekey/PLACEKEY_ISVALID.sql index d6f59e7ae..4af181cf3 100644 --- a/clouds/bigquery/modules/sql/placekey/PLACEKEY_ISVALID.sql +++ b/clouds/bigquery/modules/sql/placekey/PLACEKEY_ISVALID.sql @@ -8,8 +8,8 @@ RETURNS BOOLEAN DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_PLACEKEY_BUCKET@@"] ) AS """ - return lib.placekey.placekeyIsValid(placekey); + return placekeyLib.placekeyIsValid(placekey); """; diff --git a/clouds/bigquery/modules/sql/placekey/PLACEKEY_TOH3.sql b/clouds/bigquery/modules/sql/placekey/PLACEKEY_TOH3.sql index de43d1d69..b333246ad 100644 --- a/clouds/bigquery/modules/sql/placekey/PLACEKEY_TOH3.sql +++ b/clouds/bigquery/modules/sql/placekey/PLACEKEY_TOH3.sql @@ -8,11 +8,11 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_PLACEKEY_BUCKET@@"] ) AS """ - if (!lib.placekey.placekeyIsValid(placekey)) { + if (!placekeyLib.placekeyIsValid(placekey)) { return null; } - return lib.placekey.placekeyToH3(placekey); + return placekeyLib.placekeyToH3(placekey); """; diff --git a/clouds/bigquery/modules/sql/processing/__VORONOIHELPER.sql b/clouds/bigquery/modules/sql/processing/__VORONOIHELPER.sql index 92c4dc72f..9d672f1ba 100644 --- a/clouds/bigquery/modules/sql/processing/__VORONOIHELPER.sql +++ b/clouds/bigquery/modules/sql/processing/__VORONOIHELPER.sql @@ -8,7 +8,7 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_PROCESSING_BUCKET@@"] ) AS """ if (!geojson) { @@ -26,8 +26,8 @@ AS """ options.bbox = bbox; } - const featuresCollection = lib.processing.featureCollection(geojson.map(x => lib.processing.feature(JSON.parse(x)))); - const voronoiPolygons = lib.processing.voronoi(featuresCollection, options); + const featuresCollection = processingLib.featureCollection(geojson.map(x => processingLib.feature(JSON.parse(x)))); + const voronoiPolygons = processingLib.voronoi(featuresCollection, options); const returnArray = []; @@ -39,7 +39,7 @@ AS """ if (typeOfVoronoi === 'lines') { voronoiPolygons.features.forEach( function(item) { - let lineFeature = lib.processing.polygonToLine(item.geometry); + let lineFeature = processingLib.polygonToLine(item.geometry); returnArray.push(JSON.stringify(lineFeature.geometry)); }); } diff --git a/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMLONGLAT.sql b/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMLONGLAT.sql index 4974b734c..8a880405b 100644 --- a/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMLONGLAT.sql +++ b/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMLONGLAT.sql @@ -8,11 +8,11 @@ RETURNS INT64 DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_QUADKEY_BUCKET@@"] ) AS """ if (longitude == null || latitude == null || resolution == null) { throw new Error('NULL argument passed to UDF'); } - return lib.quadkey.quadintFromLocation(Number(longitude), Number(latitude), Number(resolution)).toString(); + return quadkeyLib.quadintFromLocation(Number(longitude), Number(latitude), Number(resolution)).toString(); """; diff --git a/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMLONGLAT_ZOOMRANGE.sql b/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMLONGLAT_ZOOMRANGE.sql index aec3b762d..f47398494 100644 --- a/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMLONGLAT_ZOOMRANGE.sql +++ b/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMLONGLAT_ZOOMRANGE.sql @@ -15,7 +15,7 @@ RETURNS ARRAY> DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_QUADKEY_BUCKET@@"] ) AS """ if (longitude === undefined || longitude === null || latitude === undefined || latitude === null) { @@ -28,8 +28,8 @@ AS """ const qintIdx = []; for (let i = zoomMin; i <= zoomMax; i += zoomStep) { - const key = lib.quadkey.quadintFromLocation(longitude, latitude, i + intResolution); - const zxy = lib.quadkey.ZXYFromQuadint(key); + const key = quadkeyLib.quadintFromLocation(longitude, latitude, i + intResolution); + const zxy = quadkeyLib.ZXYFromQuadint(key); qintIdx.push({ id : key.toString(), z : i, x : zxy.x >>> intResolution, y : zxy.y >>> intResolution}); } return qintIdx; diff --git a/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMQUADKEY.sql b/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMQUADKEY.sql index 0b1d1d113..092889d5d 100644 --- a/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMQUADKEY.sql +++ b/clouds/bigquery/modules/sql/quadkey/QUADINT_FROMQUADKEY.sql @@ -8,8 +8,8 @@ RETURNS INT64 DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_QUADKEY_BUCKET@@"] ) AS """ - return lib.quadkey.quadintFromQuadkey(quadkey).toString(); + return quadkeyLib.quadintFromQuadkey(quadkey).toString(); """; diff --git a/clouds/bigquery/modules/sql/quadkey/QUADINT_POLYFILL.sql b/clouds/bigquery/modules/sql/quadkey/QUADINT_POLYFILL.sql index 2c91f7f95..aeee59ea6 100644 --- a/clouds/bigquery/modules/sql/quadkey/QUADINT_POLYFILL.sql +++ b/clouds/bigquery/modules/sql/quadkey/QUADINT_POLYFILL.sql @@ -8,7 +8,7 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_QUADKEY_BUCKET@@"] ) AS """ if (!geojson || resolution == null) { @@ -18,13 +18,13 @@ AS """ let quadints = []; if (pol.type == 'GeometryCollection') { pol.geometries.forEach(function (geom) { - quadints = quadints.concat(lib.quadkey.geojsonToQuadints(geom, {min_zoom: Number(resolution), max_zoom: Number(resolution)})); + quadints = quadints.concat(quadkeyLib.geojsonToQuadints(geom, {min_zoom: Number(resolution), max_zoom: Number(resolution)})); }); quadints = Array.from(new Set(quadints)); } else { - quadints = lib.quadkey.geojsonToQuadints(pol, {min_zoom: Number(resolution), max_zoom: Number(resolution)}); + quadints = quadkeyLib.geojsonToQuadints(pol, {min_zoom: Number(resolution), max_zoom: Number(resolution)}); } return quadints.map(String); """; diff --git a/clouds/bigquery/modules/sql/quadkey/QUADINT_TOCHILDREN.sql b/clouds/bigquery/modules/sql/quadkey/QUADINT_TOCHILDREN.sql index c710f92f8..45f1459b6 100644 --- a/clouds/bigquery/modules/sql/quadkey/QUADINT_TOCHILDREN.sql +++ b/clouds/bigquery/modules/sql/quadkey/QUADINT_TOCHILDREN.sql @@ -8,12 +8,12 @@ RETURNS ARRAY DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_QUADKEY_BUCKET@@"] ) AS """ if (quadint == null || resolution == null) { throw new Error('NULL argument passed to UDF'); } - const quadints = lib.quadkey.toChildren(quadint, Number(resolution)); + const quadints = quadkeyLib.toChildren(quadint, Number(resolution)); return quadints.map(String); """; diff --git a/clouds/bigquery/modules/sql/quadkey/QUADINT_TOQUADKEY.sql b/clouds/bigquery/modules/sql/quadkey/QUADINT_TOQUADKEY.sql index ff8e599d1..df2589eb3 100644 --- a/clouds/bigquery/modules/sql/quadkey/QUADINT_TOQUADKEY.sql +++ b/clouds/bigquery/modules/sql/quadkey/QUADINT_TOQUADKEY.sql @@ -8,11 +8,11 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_QUADKEY_BUCKET@@"] ) AS """ if (quadint == null) { throw new Error('NULL argument passed to UDF'); } - return lib.quadkey.quadkeyFromQuadint(quadint); + return quadkeyLib.quadkeyFromQuadint(quadint); """; diff --git a/clouds/bigquery/modules/sql/random/ST_GENERATEPOINTS.sql b/clouds/bigquery/modules/sql/random/ST_GENERATEPOINTS.sql index e63946a21..adff4a6de 100644 --- a/clouds/bigquery/modules/sql/random/ST_GENERATEPOINTS.sql +++ b/clouds/bigquery/modules/sql/random/ST_GENERATEPOINTS.sql @@ -7,9 +7,9 @@ CREATE OR REPLACE FUNCTION `@@BQ_DATASET@@.__ST_GENERATEPOINTS` RETURNS ARRAY DETERMINISTIC LANGUAGE js -OPTIONS (library = ["@@BQ_LIBRARY_BUCKET@@"]) +OPTIONS (library = ["@@BQ_LIBRARY_RANDOM_BUCKET@@"]) AS """ - return lib.random.generateRandomPointsInPolygon(JSON.parse(geojson), npoints); + return randomLib.generateRandomPointsInPolygon(JSON.parse(geojson), npoints); """; CREATE OR REPLACE FUNCTION `@@BQ_DATASET@@.ST_GENERATEPOINTS` diff --git a/clouds/bigquery/modules/sql/s2/S2_BOUNDARY.sql b/clouds/bigquery/modules/sql/s2/S2_BOUNDARY.sql index 2c362fc7d..4b6d0b65e 100644 --- a/clouds/bigquery/modules/sql/s2/S2_BOUNDARY.sql +++ b/clouds/bigquery/modules/sql/s2/S2_BOUNDARY.sql @@ -8,14 +8,14 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_S2_BUCKET@@"] ) AS """ if (id == null) { throw new Error('NULL argument passed to UDF'); } - const cornerLongLat = lib.s2.FromHilbertQuadKey(lib.s2.idToKey(id)).getCornerLatLngs(); + const cornerLongLat = s2Lib.FromHilbertQuadKey(s2Lib.idToKey(id)).getCornerLatLngs(); const wkt = `POLYGON((` + cornerLongLat[0]['lng'] + ` ` + cornerLongLat[0]['lat'] + `, ` + diff --git a/clouds/bigquery/modules/sql/s2/S2_CENTER.sql b/clouds/bigquery/modules/sql/s2/S2_CENTER.sql index 74faab5eb..779be266d 100644 --- a/clouds/bigquery/modules/sql/s2/S2_CENTER.sql +++ b/clouds/bigquery/modules/sql/s2/S2_CENTER.sql @@ -6,12 +6,12 @@ CREATE OR REPLACE FUNCTION `@@BQ_DATASET@@.__S2_CENTER`(id INT64) RETURNS STRUCT DETERMINISTIC LANGUAGE js -OPTIONS (library = ["@@BQ_LIBRARY_BUCKET@@"]) +OPTIONS (library = ["@@BQ_LIBRARY_S2_BUCKET@@"]) AS """ if (id == null) { throw new Error('NULL argument passed to UDF'); } - return lib.s2.idToLatLng(String(id)); + return s2Lib.idToLatLng(String(id)); """; CREATE OR REPLACE FUNCTION `@@BQ_DATASET@@.S2_CENTER` diff --git a/clouds/bigquery/modules/sql/s2/S2_FROMHILBERTQUADKEY.sql b/clouds/bigquery/modules/sql/s2/S2_FROMHILBERTQUADKEY.sql index 1ed1734ef..073f621f9 100644 --- a/clouds/bigquery/modules/sql/s2/S2_FROMHILBERTQUADKEY.sql +++ b/clouds/bigquery/modules/sql/s2/S2_FROMHILBERTQUADKEY.sql @@ -8,11 +8,11 @@ RETURNS INT64 DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_S2_BUCKET@@"] ) AS """ if (!quadkey) { throw new Error('NULL argument passed to UDF'); } - return lib.s2.keyToId(quadkey); + return s2Lib.keyToId(quadkey); """; diff --git a/clouds/bigquery/modules/sql/s2/S2_FROMLONGLAT.sql b/clouds/bigquery/modules/sql/s2/S2_FROMLONGLAT.sql index ca9f9ef4f..b1d8108d2 100644 --- a/clouds/bigquery/modules/sql/s2/S2_FROMLONGLAT.sql +++ b/clouds/bigquery/modules/sql/s2/S2_FROMLONGLAT.sql @@ -8,12 +8,12 @@ RETURNS INT64 DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_S2_BUCKET@@"] ) AS """ if (latitude == null || longitude == null || resolution == null) { throw new Error('NULL argument passed to UDF'); } - const key = lib.s2.latLngToKey(Number(latitude), Number(longitude), Number(resolution)); - return lib.s2.keyToId(key); + const key = s2Lib.latLngToKey(Number(latitude), Number(longitude), Number(resolution)); + return s2Lib.keyToId(key); """; diff --git a/clouds/bigquery/modules/sql/s2/S2_TOHILBERTQUADKEY.sql b/clouds/bigquery/modules/sql/s2/S2_TOHILBERTQUADKEY.sql index a9b7824c4..cb60f3776 100644 --- a/clouds/bigquery/modules/sql/s2/S2_TOHILBERTQUADKEY.sql +++ b/clouds/bigquery/modules/sql/s2/S2_TOHILBERTQUADKEY.sql @@ -8,11 +8,11 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_S2_BUCKET@@"] ) AS """ if (id == null) { throw new Error('NULL argument passed to UDF'); } - return lib.s2.idToKey(id); + return s2Lib.idToKey(id); """; diff --git a/clouds/bigquery/modules/sql/transformations/ST_BUFFER.sql b/clouds/bigquery/modules/sql/transformations/ST_BUFFER.sql index 14227cc33..c5d8b89a1 100644 --- a/clouds/bigquery/modules/sql/transformations/ST_BUFFER.sql +++ b/clouds/bigquery/modules/sql/transformations/ST_BUFFER.sql @@ -8,7 +8,7 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_TRANSFORMATIONS_BUCKET@@"] ) AS """ if (!geojson || radius == null) { @@ -21,7 +21,7 @@ AS """ if (steps != null) { options.steps = Number(steps); } - const buffer = lib.transformations.buffer(JSON.parse(geojson), Number(radius), options); + const buffer = transformationsLib.buffer(JSON.parse(geojson), Number(radius), options); return JSON.stringify(buffer.geometry); """; diff --git a/clouds/bigquery/modules/sql/transformations/ST_CENTERMEAN.sql b/clouds/bigquery/modules/sql/transformations/ST_CENTERMEAN.sql index 40b0db2b2..bc0780ae2 100644 --- a/clouds/bigquery/modules/sql/transformations/ST_CENTERMEAN.sql +++ b/clouds/bigquery/modules/sql/transformations/ST_CENTERMEAN.sql @@ -8,13 +8,13 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_TRANSFORMATIONS_BUCKET@@"] ) AS """ if (!geojson) { return null; } - const center = lib.transformations.centerMean(JSON.parse(geojson)); + const center = transformationsLib.centerMean(JSON.parse(geojson)); return JSON.stringify(center.geometry); """; diff --git a/clouds/bigquery/modules/sql/transformations/ST_CENTERMEDIAN.sql b/clouds/bigquery/modules/sql/transformations/ST_CENTERMEDIAN.sql index 413ca93d6..aba6acad3 100644 --- a/clouds/bigquery/modules/sql/transformations/ST_CENTERMEDIAN.sql +++ b/clouds/bigquery/modules/sql/transformations/ST_CENTERMEDIAN.sql @@ -8,13 +8,13 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_TRANSFORMATIONS_BUCKET@@"] ) AS """ if (!geojson) { return null; } - const medianCenter = lib.transformations.centerMedian(lib.transformations.feature(JSON.parse(geojson))); + const medianCenter = transformationsLib.centerMedian(transformationsLib.feature(JSON.parse(geojson))); return JSON.stringify(medianCenter.geometry); """; diff --git a/clouds/bigquery/modules/sql/transformations/ST_CENTEROFMASS.sql b/clouds/bigquery/modules/sql/transformations/ST_CENTEROFMASS.sql index 2f811310e..f7c362409 100644 --- a/clouds/bigquery/modules/sql/transformations/ST_CENTEROFMASS.sql +++ b/clouds/bigquery/modules/sql/transformations/ST_CENTEROFMASS.sql @@ -8,13 +8,13 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_TRANSFORMATIONS_BUCKET@@"] ) AS """ if (!geojson) { return null; } - const center = lib.transformations.centerOfMass(JSON.parse(geojson)); + const center = transformationsLib.centerOfMass(JSON.parse(geojson)); return JSON.stringify(center.geometry); """; diff --git a/clouds/bigquery/modules/sql/transformations/ST_CONCAVEHULL.sql b/clouds/bigquery/modules/sql/transformations/ST_CONCAVEHULL.sql index 3792b2223..d639b2148 100644 --- a/clouds/bigquery/modules/sql/transformations/ST_CONCAVEHULL.sql +++ b/clouds/bigquery/modules/sql/transformations/ST_CONCAVEHULL.sql @@ -8,7 +8,7 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_TRANSFORMATIONS_BUCKET@@"] ) AS """ if (!geojson) { @@ -22,25 +22,25 @@ AS """ options.units = units; } - const multiPoints = lib.transformations.multiPoint(geojson.map(x => JSON.parse(x).coordinates)); - const nonDuplicates = lib.transformations.cleanCoords(multiPoints).geometry; + const multiPoints = transformationsLib.multiPoint(geojson.map(x => JSON.parse(x).coordinates)); + const nonDuplicates = transformationsLib.cleanCoords(multiPoints).geometry; const arrayCoordinates = nonDuplicates.coordinates; // Point if (arrayCoordinates.length == 1) { - return JSON.stringify(lib.transformations.point(arrayCoordinates[0]).geometry); + return JSON.stringify(transformationsLib.point(arrayCoordinates[0]).geometry); } // Segment if (arrayCoordinates.length == 2) { const start = arrayCoordinates[0]; const end = arrayCoordinates[1]; - const lineString = lib.transformations.lineString([start, end]); + const lineString = transformationsLib.lineString([start, end]); return JSON.stringify(lineString.geometry); } - const featuresCollection = lib.transformations.featureCollection(arrayCoordinates.map(x => lib.transformations.point(x))); - const hull = lib.transformations.concave(featuresCollection, options); + const featuresCollection = transformationsLib.featureCollection(arrayCoordinates.map(x => transformationsLib.point(x))); + const hull = transformationsLib.concave(featuresCollection, options); return JSON.stringify(hull.geometry); """; diff --git a/clouds/bigquery/modules/sql/transformations/ST_DESTINATION.sql b/clouds/bigquery/modules/sql/transformations/ST_DESTINATION.sql index 7ec9fa75a..1da7e427e 100644 --- a/clouds/bigquery/modules/sql/transformations/ST_DESTINATION.sql +++ b/clouds/bigquery/modules/sql/transformations/ST_DESTINATION.sql @@ -8,7 +8,7 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_TRANSFORMATIONS_BUCKET@@"] ) AS """ if (!geojsonStart || distance == null || bearing == null) { @@ -18,7 +18,7 @@ AS """ if (units) { options.units = units; } - const destination = lib.transformations.destination(JSON.parse(geojsonStart), Number(distance), Number(bearing), options); + const destination = transformationsLib.destination(JSON.parse(geojsonStart), Number(distance), Number(bearing), options); return JSON.stringify(destination.geometry); """; diff --git a/clouds/bigquery/modules/sql/transformations/ST_GREATCIRCLE.sql b/clouds/bigquery/modules/sql/transformations/ST_GREATCIRCLE.sql index 9605e2a79..fbf9f0ce9 100644 --- a/clouds/bigquery/modules/sql/transformations/ST_GREATCIRCLE.sql +++ b/clouds/bigquery/modules/sql/transformations/ST_GREATCIRCLE.sql @@ -8,7 +8,7 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_TRANSFORMATIONS_BUCKET@@"] ) AS """ if (!geojsonStart || !geojsonEnd || geojsonEnd === geojsonStart) { @@ -18,7 +18,7 @@ AS """ if (npoints != null) { options.npoints = Number(npoints); } - const greatCircle = lib.transformations.greatCircle(JSON.parse(geojsonStart), JSON.parse(geojsonEnd), options); + const greatCircle = transformationsLib.greatCircle(JSON.parse(geojsonStart), JSON.parse(geojsonEnd), options); return JSON.stringify(greatCircle.geometry); """; diff --git a/clouds/bigquery/modules/sql/transformations/ST_LINE_INTERPOLATE_POINT.sql b/clouds/bigquery/modules/sql/transformations/ST_LINE_INTERPOLATE_POINT.sql index fac984957..6c2c85b1a 100644 --- a/clouds/bigquery/modules/sql/transformations/ST_LINE_INTERPOLATE_POINT.sql +++ b/clouds/bigquery/modules/sql/transformations/ST_LINE_INTERPOLATE_POINT.sql @@ -8,7 +8,7 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_TRANSFORMATIONS_BUCKET@@"] ) AS """ if (!geojson || distance == null) { @@ -18,7 +18,7 @@ AS """ if (units) { options.units = units; } - const along = lib.transformations.along(JSON.parse(geojson), distance, options); + const along = transformationsLib.along(JSON.parse(geojson), distance, options); return JSON.stringify(along.geometry); """; diff --git a/clouds/bigquery/modules/sql/transformations/ST_POINTONSURFACE.sql b/clouds/bigquery/modules/sql/transformations/ST_POINTONSURFACE.sql index 9fcce0575..361545e95 100644 --- a/clouds/bigquery/modules/sql/transformations/ST_POINTONSURFACE.sql +++ b/clouds/bigquery/modules/sql/transformations/ST_POINTONSURFACE.sql @@ -8,13 +8,13 @@ RETURNS STRING DETERMINISTIC LANGUAGE js OPTIONS ( - library = ["@@BQ_LIBRARY_BUCKET@@"] + library = ["@@BQ_LIBRARY_TRANSFORMATIONS_BUCKET@@"] ) AS """ if (!geojson) { return null; } - const center = lib.transformations.pointOnFeature(JSON.parse(geojson)); + const center = transformationsLib.pointOnFeature(JSON.parse(geojson)); return JSON.stringify(center.geometry); """;