Sql 如何从BigQuery JavaScript UDF为字符串化几何体集合中的每个特征创建几何体?
我不熟悉UDF函数,我创建了一个BigQuery UDF,它接受多边形几何体并使用它创建点。我正在尝试绘制点密度图(将多边形+人口数转换为点)。我已经从中改编了代码。因为bigQuery没有办法记录变量,所以我一直在测试 我正处于函数似乎正常工作的阶段。输出是点的几何图形集合。它在bigquery文档中表示,Sql 如何从BigQuery JavaScript UDF为字符串化几何体集合中的每个特征创建几何体?,sql,google-bigquery,user-defined-functions,Sql,Google Bigquery,User Defined Functions,我不熟悉UDF函数,我创建了一个BigQuery UDF,它接受多边形几何体并使用它创建点。我正在尝试绘制点密度图(将多边形+人口数转换为点)。我已经从中改编了代码。因为bigQuery没有办法记录变量,所以我一直在测试 我正处于函数似乎正常工作的阶段。输出是点的几何图形集合。它在bigquery文档中表示,st_geogfromgeojson可以接受几何体集合 我的UDF返回字符串化几何体集合 但我不明白为什么st_geogfromgeojson不起作用。我不知道我是不是在逃避什么 CREAT
st_geogfromgeojson
可以接受几何体集合
我的UDF返回字符串化几何体集合
但我不明白为什么st_geogfromgeojson不起作用。我不知道我是不是在逃避什么
CREATE TEMP FUNCTION myFunc(feature string, ethnicity_column FLOAT64, year INT64)
RETURNS string
LANGUAGE js
OPTIONS (
library=["https://storage.googleapis.com.../d3.js","https://storage.googleapis.com/.../turf.min.js","https://storage.googleapis.com/.../wellknown.js"]
)
AS
"""
if (feature === undefined || feature === null) return;
var feature_parsed = wellknown.parse(feature)
const bounds = turf.bbox(feature_parsed);
const populationData = Math.round(ethnicity_column / 10);
if (!populationData) return;
const x_min = bounds[0];
const y_min = bounds[1];
const x_max = bounds[2];
const y_max = bounds[3];
let hits = 0;
let count = 0;
const limit = populationData * 10; // limit test to 10x the population.
let points = [];
while (hits < populationData - 1 && count < limit) {
const lat = y_min + Math.random() * (y_max - y_min);
const lng = x_min + Math.random() * (x_max - x_min);
const randomPoint = turf.point([lng, lat]);
if (turf.booleanPointInPolygon(randomPoint, feature_parsed)) {
points.push(randomPoint);
hits++;
}
count++;
}
return JSON.stringify((turf.geometryCollection(points)));
// return JSON.stringify(points)
""";
SELECT ST_GEOGFROMGEOJSON(JSON_EXTRACT((myFunc(st_astext(geom), white_pop, 2018)),'$')) FROM `myteam.kyle_data.blockgroups_with_acs`
CREATE TEMP FUNCTION myFunc(要素字符串,第64列,第64年)
返回字符串
语言js
选择权(
库=[”https://storage.googleapis.com.../d3.js","https://storage.googleapis.com/.../turf.min.js","https://storage.googleapis.com/.../wellknown.js"]
)
作为
"""
if(feature==undefined | | feature==null)返回;
var feature_parsed=wellknown.parse(feature)
const-bounds=turp.bbox(已解析的特征);
const populationData=Math.round(第/10列);
如果(!populationData)返回;
常数x_min=界限[0];
常数y_min=界限[1];
常数x_max=界限[2];
常数y_max=界[3];
设hits=0;
让计数=0;
const limit=populationData*10;//将测试限制为总体的10倍。
设点=[];
while(点击次数
但是我不断地碰到随机错误,好像我没有正确地使用函数
我愿意接受所有建议。为了简单起见,我返回一个字符串,但可能需要使用STRUCT。也许我应该从创造积分中剔除草皮?我一定是遗漏了什么。GeoJson有两种不同的集合类型:
- 一种是
——这是一种描述几何图形集合的几何图形,例如点和多边形的并集就是GeometryCollectionGeometryCollection
- 另一种是
——特征、具有各种特性的对象的集合,包括FeatureCollection
(可以是几何体集合或任何其他几何体)和其他用户定义的特性几何体
功能
:(这就是它也接受属性
参数的原因)
ST_GEOGFROMGEOJSON
构造几何体,它确实支持GeometryCollection
,但不支持turf返回的FeatureCollection
或singularFeature
您可以做的是从该功能中提取一个
几何体
,并将其传递给ST_GEOGFROMGEOJSON
。我认为只需使用JSON选择器$。几何体而不是$
就足够了。两件事解决了它:
- 返回
数组
而不是字符串
- 在
选择中取消交叉连接
创建临时函数myFunc(要素字符串,第64列)
返回数组
语言js
选择权(
库=[”https://storage.googleapis.com/../d3.js","https://storage.googleapis.com/.../turf.min.js","https://storage.googleapis.com/.../wellknown.js"]
)
作为
"""
geopath=d3.geopath()
if(feature==undefined | | feature==null)返回;
var feature_parsed=wellknown.parse(feature)
const-bounds=turp.bbox(已解析的特征);
const populationData=Math.round(第/10列);
如果(!populationData)返回;
常数x_min=界限[0];
常数y_min=界限[1];
常数x_max=界限[2];
常数y_max=界[3];
设hits=0;
让计数=0;
const limit=populationData;//将测试限制为总体的10倍。
设点=[];
while(点击次数
感谢您的回复。核心问题似乎是turf说它返回了GeometryCollection,而实际上它是一个FeatureCollection<代码>ST_GEOGFROMGEOJSON(JSON_摘录((myFunc(ST_astext(geom),white_pop,2018)),“$.geometry”)
仍然获取ST_GEOGFROMGEOJSON失败:GeoJSON阅读器接受几何体对象,不是Feature或FeatureCollection对象
,所以听起来我需要调试Turp,或者找出如何从这个事实上的FeatureCollection中获取几何体。从描述中,我希望Turp返回一个F
CREATE TEMP FUNCTION myFunc(feature string, ethnicity_column FLOAT64)
RETURNS array<String>
LANGUAGE js
OPTIONS (
library=["https://storage.googleapis.com/../d3.js","https://storage.googleapis.com/.../turf.min.js","https://storage.googleapis.com/.../wellknown.js"]
)
AS
"""
geopath = d3.geoPath()
if (feature === undefined || feature === null) return;
var feature_parsed = wellknown.parse(feature)
const bounds = turf.bbox(feature_parsed);
const populationData = Math.round(ethnicity_column / 10);
if (!populationData) return;
const x_min = bounds[0];
const y_min = bounds[1];
const x_max = bounds[2];
const y_max = bounds[3];
let hits = 0;
let count = 0;
const limit = populationData; // limit test to 10x the population.
let points = [];
while (hits < populationData - 1 && count < limit) {
const lat = y_min + Math.random() * (y_max - y_min);
const lng = x_min + Math.random() * (x_max - x_min);
const randomPoint = turf.point([lng, lat]);
if (turf.booleanPointInPolygon(randomPoint, feature_parsed)) {
points.push('POINT ('+lng+' '+lat+')');
hits++;
}
count++;
}
return points;
""";
SELECT st_geogfromtext(points) as the_geom, 'white' as ethnicity from (SELECT (myFunc(st_astext(geom), white_pop)) as points FROM `tableonmybq`) CROSS JOIN UNNEST(points) as points