@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
120 lines (119 loc) • 4.16 kB
JavaScript
;
import { isBoolean } from "../../../core/Type";
import { FeatureConverter } from "../../../core/thirdParty/Mapbox/FeatureConverter";
import { NodeParamsConfig, ParamConfig } from "../../nodes/utils/params/ParamsConfig";
import { pushOnArrayAtEntry } from "../../../core/MapUtils";
import { arrayChunk } from "../../../core/ArrayUtils";
import { TypedSopNode } from "./_Base";
import { MapboxMapsController } from "../../../core/thirdParty/Mapbox/MapboxMapsController";
import { ParamType } from "../../poly/ParamType";
class MapboxLayerSopParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
/** @param names of layers to create */
// layers = ParamConfig.STRING(DEFAULT_LIST);
this.updateLayers = ParamConfig.BUTTON(null, {
callback: (node) => {
MapboxLayerSopNode.PARAM_CALLBACK_reload(node);
}
});
}
}
const ParamsConfig = new MapboxLayerSopParamsConfig();
export class MapboxLayerSopNode extends TypedSopNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
this._featuresByName = /* @__PURE__ */ new Map();
}
static type() {
return "mapboxLayer";
}
async cook() {
const map = await MapboxMapsController.waitForMap();
if (!map) {
this.states.error.set("map not initialized yet");
return;
}
const layerNames = this.params.spare.filter((param) => param.value == true).map((param) => param.name());
const existingLayerNames = [];
for (const layerName of layerNames) {
if (map.getLayer(layerName)) {
existingLayerNames.push(layerName);
} else {
this.states.error.set(`layer ${layerName} does not exist`);
return;
}
}
const features = map.queryRenderedFeatures(void 0, {
layers: existingLayerNames
});
const objects = [];
if (features) {
const featuresByName = this._groupFeaturesByName(features);
featuresByName.forEach((featuresForName, featureName) => {
const converter = new FeatureConverter(this, featureName, featuresForName);
const new_object = converter.createObject();
if (new_object) {
objects.push(new_object);
}
});
}
this.setObjects(objects);
}
_groupFeaturesByName(features) {
this._featuresByName.clear();
for (const feature of features) {
const name = this._feature_name(feature);
if (name) {
pushOnArrayAtEntry(this._featuresByName, name, feature);
}
}
return this._featuresByName;
}
_feature_name(feature) {
const properties = feature["properties"];
let name;
if (properties) {
name = properties["name"] || properties["name_en"];
if (name == null) {
name = this._id_from_feature(feature);
}
}
return name;
}
_id_from_feature(feature) {
const json_str = JSON.stringify(feature.geometry).replace(/{|}|"|:|\[|\]|,|\./g, "");
const json_str_elements = json_str.split("");
const letters_count = 30;
const chunks = arrayChunk(json_str_elements, json_str_elements.length / letters_count);
const first_elements = chunks.map((c) => c[0]);
return first_elements.join("");
}
static PARAM_CALLBACK_reload(node) {
node._paramCallbackReload();
}
async _paramCallbackReload() {
const map = await MapboxMapsController.waitForMap();
const layers = map.getStyle().layers;
const layerNames = layers.map((layer) => layer.id).sort();
const currentSpareParams = this.params.spare;
const currentValuesByName = /* @__PURE__ */ new Map();
for (const spareParam of currentSpareParams) {
const value = spareParam.value;
if (isBoolean(value)) {
currentValuesByName.set(spareParam.name(), value);
}
}
this.params.updateParams({
namesToDelete: currentSpareParams.map((p) => p.name()),
toAdd: layerNames.map((layerName) => ({
name: layerName,
type: ParamType.BOOLEAN,
initValue: currentValuesByName.get(layerName) || false,
rawInput: currentValuesByName.get(layerName) || false,
options: { spare: true }
}))
});
}
}