From 3ddd18031de5da3435a0e470719ff1c6137aabb2 Mon Sep 17 00:00:00 2001 From: Margriet Groenendijk Date: Tue, 3 May 2022 11:45:44 +0100 Subject: [PATCH 1/8] renamed visualize.py Renamed visualize.py to show.py --- pybabylonjs/__init__.py | 2 +- pybabylonjs/{visualize.py => show.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename pybabylonjs/{visualize.py => show.py} (100%) diff --git a/pybabylonjs/__init__.py b/pybabylonjs/__init__.py index 050ecef..13dd425 100644 --- a/pybabylonjs/__init__.py +++ b/pybabylonjs/__init__.py @@ -1,6 +1,6 @@ import json from pathlib import Path -from .visualize import BabylonJS, Show +from .show import BabylonJS, Show from ._version import __version__ HERE = Path(__file__).parent.resolve() diff --git a/pybabylonjs/visualize.py b/pybabylonjs/show.py similarity index 100% rename from pybabylonjs/visualize.py rename to pybabylonjs/show.py From a451387e69928eda2b77a70bb090f2c0e2367073 Mon Sep 17 00:00:00 2001 From: Margriet Groenendijk Date: Thu, 5 May 2022 16:49:21 +0100 Subject: [PATCH 2/8] refactored show.py added new methods Show.point_cloud(), Show.image() and Show.mbrs() --- pybabylonjs/babylonjs.py | 26 +++++++++++------------ pybabylonjs/data.py | 9 +++----- pybabylonjs/show.py | 46 ++++++++++++++++++++-------------------- src/widget.ts | 40 +++++++++++++++++----------------- 4 files changed, 59 insertions(+), 62 deletions(-) diff --git a/pybabylonjs/babylonjs.py b/pybabylonjs/babylonjs.py index 005a908..4eebb7b 100644 --- a/pybabylonjs/babylonjs.py +++ b/pybabylonjs/babylonjs.py @@ -64,13 +64,13 @@ def set_defaults(validator, properties, instance, schema): "required": ["data"], } -pc_schema = deepcopy(core_schema) +point_cloud_schema = deepcopy(core_schema) attrs = ["X", "Y", "Z", "Red", "Green", "Blue"] -pc_schema["properties"]["data"]["required"].extend(attrs) +point_cloud_schema["properties"]["data"]["required"].extend(attrs) mbrs_schema = deepcopy(core_schema) -ground_schema = { +image_schema = { "type": "object", "properties": { "inspector": {"type": "boolean", "default": False}, @@ -90,13 +90,13 @@ def set_defaults(validator, properties, instance, schema): class BabylonBase(DOMWidget): + """Base class for all Babylon derived widgets""" + _model_module = Unicode(module_name).tag(sync=True) _model_module_version = Unicode(module_version).tag(sync=True) _view_module_version = Unicode(module_version).tag(sync=True) _view_module = Unicode(module_name).tag(sync=True) - """Base class for all Babylon derived widgets""" - @validate("value") def _validate_value(self, proposal): try: @@ -107,13 +107,13 @@ def _validate_value(self, proposal): @register -class BabylonPC(BabylonBase): +class BabylonPointCloud(BabylonBase): """3D point cloud with BabylonJS""" - _model_name = Unicode("BabylonPCModel").tag(sync=True) - _view_name = Unicode("BabylonPCView").tag(sync=True) + _model_name = Unicode("BabylonPointCloudModel").tag(sync=True) + _view_name = Unicode("BabylonPointCloudView").tag(sync=True) value = Dict().tag(sync=True) - _schema = pc_schema + _schema = point_cloud_schema @register @@ -127,10 +127,10 @@ class BabylonMBRS(BabylonBase): @register -class BabylonGround(BabylonBase): +class BabylonImage(BabylonBase): """Ground surface as 2D array with BabylonJS""" - _model_name = Unicode("BabylonGroundModel").tag(sync=True) - _view_name = Unicode("BabylonGroundView").tag(sync=True) + _model_name = Unicode("BabylonImageModel").tag(sync=True) + _view_name = Unicode("BabylonImageView").tag(sync=True) value = Dict().tag(sync=True) - _schema = ground_schema + _schema = image_schema diff --git a/pybabylonjs/data.py b/pybabylonjs/data.py index 4a915ac..e1556c2 100644 --- a/pybabylonjs/data.py +++ b/pybabylonjs/data.py @@ -2,10 +2,7 @@ # Licensed under the MIT License. """Functions to format data from the arrays to be used in the visualization.""" -# from array import array import io -import json -from datetime import datetime import numpy as np import pandas as pd import cv2 @@ -58,7 +55,7 @@ def create_mbrs(array_uri: str): return dict(extents=extents, data=data) -def create_ground(array_uri: str, **kwargs): +def create_image(array_uri: str, **kwargs): """Create a Dict to be passed on to BabylonGround containing images as blobs. Parameters: @@ -77,13 +74,13 @@ def numpy_to_binary(arr): bbox = kwargs["xy_bbox"] band = kwargs["band"] image_type = kwargs["image_type"] - sar_scale_factor = kwargs["sar_scale_factor"] + sar_scale = kwargs["sar_scale_factor"] with tiledb.open(array_uri, "r") as arr: img = arr[band, bbox[0] : bbox[1], bbox[2] : bbox[3]][kwargs["attribute"]] if image_type == "sar": - img = 20 * np.log10(img * sar_scale_factor) + img = 20 * np.log10(img * sar_scale) img = ((img - np.min(img)) / (np.max(img) - np.min(img))) * 255 binary_image = numpy_to_binary(img) diff --git a/pybabylonjs/show.py b/pybabylonjs/show.py index 4ede625..3302b40 100644 --- a/pybabylonjs/show.py +++ b/pybabylonjs/show.py @@ -5,10 +5,15 @@ from IPython.display import display from typing import Optional -from .babylonjs import BabylonPC, BabylonMBRS, BabylonGround +from .babylonjs import BabylonPointCloud, BabylonMBRS, BabylonImage from .data import * +def create_dataviz(dataviz, d, **kwargs): + dataviz.value = {**d, **kwargs} + display(dataviz) + + class PyBabylonJSError(Exception): pass @@ -25,40 +30,34 @@ def __init__(self): self._dataviz = None @classmethod - def from_dict( + def point_cloud( self, data: dict, - style: str, time: Optional[bool] = False, classes: Optional[bool] = False, + # topo: Optional[bool] = False, **kwargs, ): - if style == "pointcloud": - dataviz = BabylonPC() - d = {"classes": classes, "time": time, "data": data} - dataviz.value = {**d, **kwargs} - display(dataviz) - else: - raise PyBabylonJSError(f"Unsupported style {style}") + d = {"classes": classes, "time": time, "data": data} + create_dataviz(BabylonPointCloud(), d, **kwargs) @classmethod - def from_array( + def image( self, array_uri: str, - style: str, **kwargs, ): - if style == "mbrs": - dataviz = BabylonMBRS() - d = create_mbrs(array_uri) - elif style == "ground": - dataviz = BabylonGround() - d = create_ground(array_uri, **kwargs) - else: - raise PyBabylonJSError(f"Unsupported style {style}") + d = create_image(array_uri, **kwargs) + create_dataviz(BabylonImage(), d, **kwargs) - dataviz.value = {**d, **kwargs} - display(dataviz) + @classmethod + def mbrs( + self, + array_uri: str, + **kwargs, + ): + d = create_mbrs(array_uri) + create_dataviz(BabylonMBRS(), d, **kwargs) class BabylonJS: @@ -82,4 +81,5 @@ def _ipython_display_(self): if self.height: kwargs["height"] = self.height - Show.from_dict(data=self.value, style="pointcloud", **kwargs) + d = {"data": self.value} + create_dataviz(BabylonPointCloud(), d, **kwargs) diff --git a/src/widget.ts b/src/widget.ts index d9412d7..8a55c15 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -87,24 +87,24 @@ abstract class BabylonBaseView extends DOMWidgetView { } -export class BabylonPCModel extends BabylonBaseModel { +export class BabylonPointCloudModel extends BabylonBaseModel { defaults(): any { return { ...super.defaults(), - _model_name: BabylonPCModel.model_name, - _model_module: BabylonPCModel.model_module, - _model_module_version: BabylonPCModel.model_module_version, - _view_name: BabylonPCModel.view_name, - _view_module: BabylonPCModel.view_module, - _view_module_version: BabylonPCModel.view_module_version, + _model_name: BabylonPointCloudModel.model_name, + _model_module: BabylonPointCloudModel.model_module, + _model_module_version: BabylonPointCloudModel.model_module_version, + _view_name: BabylonPointCloudModel.view_name, + _view_module: BabylonPointCloudModel.view_module, + _view_module_version: BabylonPointCloudModel.view_module_version, }; } - static model_name = 'BabylonPCModel'; - static view_name = 'BabylonPCView'; + static model_name = 'BabylonPointCloudModel'; + static view_name = 'BabylonPointCloudView'; } -export class BabylonPCView extends BabylonBaseView { +export class BabylonPointCloudView extends BabylonBaseView { protected async createScene(): Promise { return super.createScene().then( ( scene ) => { @@ -357,24 +357,24 @@ export class BabylonMBRSView extends BabylonBaseView { } } -export class BabylonGroundModel extends BabylonBaseModel { +export class BabylonImageModel extends BabylonBaseModel { defaults(): any { return { ...super.defaults(), - _model_name: BabylonGroundModel.model_name, - _model_module: BabylonGroundModel.model_module, - _model_module_version: BabylonGroundModel.model_module_version, - _view_name: BabylonGroundModel.view_name, - _view_module: BabylonGroundModel.view_module, - _view_module_version: BabylonGroundModel.view_module_version, + _model_name: BabylonImageModel.model_name, + _model_module: BabylonImageModel.model_module, + _model_module_version: BabylonImageModel.model_module_version, + _view_name: BabylonImageModel.view_name, + _view_module: BabylonImageModel.view_module, + _view_module_version: BabylonImageModel.view_module_version, }; } - static model_name = 'BabylonGroundModel'; - static view_name = 'BabylonGroundView'; + static model_name = 'BabylonImageModel'; + static view_name = 'BabylonImageView'; } -export class BabylonGroundView extends BabylonBaseView { +export class BabylonImageView extends BabylonBaseView { protected async createScene(): Promise { return super.createScene().then( ( scene ) => { From 9d5f53b67224d791c0a5652c1a77562709ee2178 Mon Sep 17 00:00:00 2001 From: Margriet Groenendijk Date: Mon, 9 May 2022 16:13:09 +0100 Subject: [PATCH 3/8] mapbox image backup --- pybabylonjs/data.py | 37 ++++++++++++++++++++++++++++++++++ pybabylonjs/show.py | 7 +++++-- src/widget.ts | 48 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/pybabylonjs/data.py b/pybabylonjs/data.py index e1556c2..163514c 100644 --- a/pybabylonjs/data.py +++ b/pybabylonjs/data.py @@ -87,3 +87,40 @@ def numpy_to_binary(arr): [img_height, img_width] = np.shape(img) return dict(data=binary_image, img_width=img_width, img_height=img_height) + + +def create_mapbox_image(data: dict, **kwargs): + """Create a Dict with an additional topographic image from mapbox + + Parameters: + """ + import requests + from rasterio.coords import BoundingBox + from rasterio.warp import transform_bounds + + mbtoken = kwargs["mbtoken"] + data_crs = kwargs["crs"] + + dst_crs = {"init": "EPSG:4326"} # lat/lon + + bbox = BoundingBox( + data["X"].min(), data["Y"].min(), data["X"].max(), data["Y"].max() + ) + dst_bbox = transform_bounds(data_crs, dst_crs, *bbox) + + f = requests.get( + ( + "https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/[" + + str(dst_bbox[0]) + + "," + + str(dst_bbox[1]) + + "," + + str(dst_bbox[2]) + + "," + + str(dst_bbox[3]) + + "]/400x400?access_token=" + + mbtoken + ) + ) + + return f.content diff --git a/pybabylonjs/show.py b/pybabylonjs/show.py index 3302b40..03d7c72 100644 --- a/pybabylonjs/show.py +++ b/pybabylonjs/show.py @@ -35,10 +35,13 @@ def point_cloud( data: dict, time: Optional[bool] = False, classes: Optional[bool] = False, - # topo: Optional[bool] = False, + topo: Optional[bool] = False, **kwargs, ): - d = {"classes": classes, "time": time, "data": data} + d = {"classes": classes, "time": time, "topo": topo, "data": data} + if topo: + img = create_mapbox_image(data, **kwargs) + d = {**d, "mapbox_img": img} create_dataviz(BabylonPointCloud(), d, **kwargs) @classmethod diff --git a/src/widget.ts b/src/widget.ts index 8a55c15..34225d6 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -118,9 +118,13 @@ export class BabylonPointCloudView extends BabylonBaseView { const isClass = this.values.classes; const class_numbers = this.values.class_numbers; const class_names = this.values.class_names; + const isTopo = this.values.topo; const scale = this.zScale; var doClear = false; + console.log("isTopo") + console.log(isTopo) + if (isClass) { var pcs = new PointsCloudSystem('pcs', pointSize, scene, { updatable: isClass @@ -250,6 +254,44 @@ export class BabylonPointCloudView extends BabylonBaseView { panel.addControl(slider); } + if(isTopo) { + + const mapbox_img = this.values.mapbox_img; + var blob = new Blob([mapbox_img]); + var url = URL.createObjectURL(blob); + + //console.log("blob") + //console.log(blob) + + const mat = new StandardMaterial("mat", scene); + mat.emissiveColor = Color3.Random(); + mat.diffuseTexture = new Texture(url, scene); + mat.ambientTexture = new Texture(url, scene); + + //var xmin = Math.min(...data.X) + const xmin = data.X.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); + const xmax = data.X.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); + const ymin = data.Y.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); + const ymax = data.Y.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); + + console.log("position") + console.log((xmin+xmax)/2) + console.log((ymin+ymax)/2) + console.log("scaling") + console.log(xmax-xmin) + console.log(ymax-ymin) + + //abstractPlane = Plane.FromPositionAndNormal(new BABYLON.Vector3(1, 1, 1), new BABYLON.Vector3(0.2, 0.5, -1)); + + const plane = MeshBuilder.CreatePlane("plane", {height:1, width: 1}, scene); + plane.position.x = (xmin+xmax)/2; + plane.position.y = 0; + plane.position.z = (ymin+ymax)/2; + plane.scaling.x = xmax-xmin; + plane.scaling.z = ymax-ymin; + plane.material = mat; + } + let camera = scene.activeCamera as ArcRotateCamera; // possibly make these configurable, but they are good defaults camera.panningAxis = new Vector3(1, 1, 0); @@ -262,7 +304,7 @@ export class BabylonPointCloudView extends BabylonBaseView { camera.wheelPrecision = this.wheelPrecision; camera.alpha += Math.PI; - camera.attachControl(this.canvas, true); + camera.attachControl(this.canvas, false); return scene; }); @@ -314,7 +356,7 @@ export class BabylonMBRSView extends BabylonBaseView { camera.wheelPrecision = this.wheelPrecision; camera.setTarget(new Vector3((((maxx+minx)/2) - minx) / xy_length, 0, (((maxy+miny)/2) - miny) / xy_length)); - camera.attachControl(this.canvas, true); + camera.attachControl(this.canvas, false); var mat = new StandardMaterial('mt1', scene); mat.alpha = 0.85; @@ -410,7 +452,7 @@ export class BabylonImageView extends BabylonBaseView { camera.wheelPrecision = this.wheelPrecision; camera.alpha += Math.PI; - camera.attachControl(this.canvas, true); + camera.attachControl(this.canvas, false); return scene; }); From e83d867e16f15216dd15ab1accf0654dd1434eb3 Mon Sep 17 00:00:00 2001 From: Margriet Groenendijk Date: Tue, 10 May 2022 09:00:16 +0100 Subject: [PATCH 4/8] Update widget.ts --- src/widget.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/widget.ts b/src/widget.ts index 34225d6..6fe1627 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -254,6 +254,11 @@ export class BabylonPointCloudView extends BabylonBaseView { panel.addControl(slider); } + const xmin = data.X.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); + const xmax = data.X.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); + const ymin = data.Y.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); + const ymax = data.Y.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); + if(isTopo) { const mapbox_img = this.values.mapbox_img; @@ -269,11 +274,7 @@ export class BabylonPointCloudView extends BabylonBaseView { mat.ambientTexture = new Texture(url, scene); //var xmin = Math.min(...data.X) - const xmin = data.X.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); - const xmax = data.X.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); - const ymin = data.Y.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); - const ymax = data.Y.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); - + console.log("position") console.log((xmin+xmax)/2) console.log((ymin+ymax)/2) @@ -285,10 +286,10 @@ export class BabylonPointCloudView extends BabylonBaseView { const plane = MeshBuilder.CreatePlane("plane", {height:1, width: 1}, scene); plane.position.x = (xmin+xmax)/2; - plane.position.y = 0; + //plane.position.z = 0; plane.position.z = (ymin+ymax)/2; plane.scaling.x = xmax-xmin; - plane.scaling.z = ymax-ymin; + plane.scaling.y = ymax-ymin; plane.material = mat; } @@ -304,6 +305,7 @@ export class BabylonPointCloudView extends BabylonBaseView { camera.wheelPrecision = this.wheelPrecision; camera.alpha += Math.PI; + camera.setTarget(new Vector3((xmin+xmax)/2, 0, (ymin+ymax)/2)); camera.attachControl(this.canvas, false); return scene; From 0272e0bc8b74befc5f3b4245864ae63915188b75 Mon Sep 17 00:00:00 2001 From: Margriet Groenendijk Date: Tue, 10 May 2022 12:43:18 +0100 Subject: [PATCH 5/8] mapbox base layer added to point cloud --- pybabylonjs/babylonjs.py | 2 ++ pybabylonjs/data.py | 7 +++++-- pybabylonjs/show.py | 15 +++++++++++++++ src/widget.ts | 40 +++++++++++----------------------------- 4 files changed, 33 insertions(+), 31 deletions(-) diff --git a/pybabylonjs/babylonjs.py b/pybabylonjs/babylonjs.py index 4eebb7b..3c2ff0a 100644 --- a/pybabylonjs/babylonjs.py +++ b/pybabylonjs/babylonjs.py @@ -57,6 +57,8 @@ def set_defaults(validator, properties, instance, schema): "classes": {"type": "boolean", "default": False}, "class_numbers": {"type": "array"}, "class_names": {"type": "array"}, + "topo": {"type": "boolean", "default": False}, + "topo_offset": {"type": "number", "default": 0}, "gltf_data": {"type": "string"}, "point_size": {"type": "number", "default": 1}, "data": {"type": "object", "properties": {}, "required": []}, diff --git a/pybabylonjs/data.py b/pybabylonjs/data.py index 163514c..ba8868c 100644 --- a/pybabylonjs/data.py +++ b/pybabylonjs/data.py @@ -99,6 +99,7 @@ def create_mapbox_image(data: dict, **kwargs): from rasterio.warp import transform_bounds mbtoken = kwargs["mbtoken"] + style_id = kwargs["mbstyle"] data_crs = kwargs["crs"] dst_crs = {"init": "EPSG:4326"} # lat/lon @@ -110,7 +111,9 @@ def create_mapbox_image(data: dict, **kwargs): f = requests.get( ( - "https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/[" + "https://api.mapbox.com/styles/v1/mapbox/" + + style_id + + "/static/[" + str(dst_bbox[0]) + "," + str(dst_bbox[1]) @@ -118,7 +121,7 @@ def create_mapbox_image(data: dict, **kwargs): + str(dst_bbox[2]) + "," + str(dst_bbox[3]) - + "]/400x400?access_token=" + + "]/1280x1280?access_token=" + mbtoken ) ) diff --git a/pybabylonjs/show.py b/pybabylonjs/show.py index 03d7c72..e1ede71 100644 --- a/pybabylonjs/show.py +++ b/pybabylonjs/show.py @@ -62,6 +62,21 @@ def mbrs( d = create_mbrs(array_uri) create_dataviz(BabylonMBRS(), d, **kwargs) + @classmethod + def from_dict( + self, + data: dict, + time: Optional[bool] = False, + classes: Optional[bool] = False, + topo: Optional[bool] = False, + **kwargs, + ): + d = {"classes": classes, "time": time, "topo": topo, "data": data} + if topo: + img = create_mapbox_image(data, **kwargs) + d = {**d, "mapbox_img": img} + create_dataviz(BabylonPointCloud(), d, **kwargs) + class BabylonJS: """Legacy class for instantiating the widget""" diff --git a/src/widget.ts b/src/widget.ts index 6fe1627..62f6d83 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -119,11 +119,15 @@ export class BabylonPointCloudView extends BabylonBaseView { const class_numbers = this.values.class_numbers; const class_names = this.values.class_names; const isTopo = this.values.topo; + const topo_offset = this.values.topo_offset; const scale = this.zScale; var doClear = false; - console.log("isTopo") - console.log(isTopo) + const xmin = data.X.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); + const xmax = data.X.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); + const ymin = data.Y.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); + const ymax = data.Y.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); + if (isClass) { var pcs = new PointsCloudSystem('pcs', pointSize, scene, { @@ -140,7 +144,7 @@ export class BabylonPointCloudView extends BabylonBaseView { // Y is up particle.position = new Vector3( data.X[i], - data.Z[i] * scale, + (data.Z[i]-topo_offset) * scale, data.Y[i] ); @@ -254,43 +258,21 @@ export class BabylonPointCloudView extends BabylonBaseView { panel.addControl(slider); } - const xmin = data.X.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); - const xmax = data.X.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); - const ymin = data.Y.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); - const ymax = data.Y.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); - if(isTopo) { const mapbox_img = this.values.mapbox_img; var blob = new Blob([mapbox_img]); var url = URL.createObjectURL(blob); - //console.log("blob") - //console.log(blob) - const mat = new StandardMaterial("mat", scene); mat.emissiveColor = Color3.Random(); mat.diffuseTexture = new Texture(url, scene); mat.ambientTexture = new Texture(url, scene); - //var xmin = Math.min(...data.X) - - console.log("position") - console.log((xmin+xmax)/2) - console.log((ymin+ymax)/2) - console.log("scaling") - console.log(xmax-xmin) - console.log(ymax-ymin) - - //abstractPlane = Plane.FromPositionAndNormal(new BABYLON.Vector3(1, 1, 1), new BABYLON.Vector3(0.2, 0.5, -1)); - - const plane = MeshBuilder.CreatePlane("plane", {height:1, width: 1}, scene); - plane.position.x = (xmin+xmax)/2; - //plane.position.z = 0; - plane.position.z = (ymin+ymax)/2; - plane.scaling.x = xmax-xmin; - plane.scaling.y = ymax-ymin; - plane.material = mat; + const options = {xmin: xmin, zmin: ymin, xmax: xmax, zmax: ymax}; + const ground = MeshBuilder.CreateTiledGround("tiled ground", options, scene); + ground.material = mat; + } let camera = scene.activeCamera as ArcRotateCamera; From 1d57c2a442d1f517fe64bc116ca3680742d1f005 Mon Sep 17 00:00:00 2001 From: Margriet Groenendijk Date: Fri, 13 May 2022 21:21:07 +0100 Subject: [PATCH 6/8] extended mapbox api call --- pybabylonjs/babylonjs.py | 2 +- pybabylonjs/data.py | 31 ++++++++++++++++++++++++++----- src/widget.ts | 11 +++++++---- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/pybabylonjs/babylonjs.py b/pybabylonjs/babylonjs.py index 3c2ff0a..37f4fed 100644 --- a/pybabylonjs/babylonjs.py +++ b/pybabylonjs/babylonjs.py @@ -87,7 +87,7 @@ def set_defaults(validator, properties, instance, schema): "img_width": {"type": "number"}, "img_height": {"type": "number"}, }, - "required": ["xy_bbox", "img_width"], + "required": ["xy_bbox"], } diff --git a/pybabylonjs/data.py b/pybabylonjs/data.py index ba8868c..b2ef57a 100644 --- a/pybabylonjs/data.py +++ b/pybabylonjs/data.py @@ -84,9 +84,9 @@ def numpy_to_binary(arr): img = ((img - np.min(img)) / (np.max(img) - np.min(img))) * 255 binary_image = numpy_to_binary(img) - [img_height, img_width] = np.shape(img) + #[img_height, img_width] = np.shape(img) - return dict(data=binary_image, img_width=img_width, img_height=img_height) + return dict(data=binary_image) def create_mapbox_image(data: dict, **kwargs): @@ -101,13 +101,30 @@ def create_mapbox_image(data: dict, **kwargs): mbtoken = kwargs["mbtoken"] style_id = kwargs["mbstyle"] data_crs = kwargs["crs"] - + dst_crs = {"init": "EPSG:4326"} # lat/lon - + bbox = BoundingBox( data["X"].min(), data["Y"].min(), data["X"].max(), data["Y"].max() ) + dst_bbox = transform_bounds(data_crs, dst_crs, *bbox) + + print(bbox) + print(dst_bbox) + + w = bbox[2] - bbox[0] + h = bbox[3] - bbox[1] + + if w>h: + ww = 1280 + hh = int(h/w * 1280) + elif h>w: + hh = 1280 + ww = int(w/h * 1280) + + print(ww) + print(hh) f = requests.get( ( @@ -121,7 +138,11 @@ def create_mapbox_image(data: dict, **kwargs): + str(dst_bbox[2]) + "," + str(dst_bbox[3]) - + "]/1280x1280?access_token=" + + "]/" + + str(ww) + + "x" + + str(hh) + + "?access_token=" + mbtoken ) ) diff --git a/src/widget.ts b/src/widget.ts index 62f6d83..d6d1597 100644 --- a/src/widget.ts +++ b/src/widget.ts @@ -128,7 +128,6 @@ export class BabylonPointCloudView extends BabylonBaseView { const ymin = data.Y.reduce((accum: number, currentNumber: number) => Math.min(accum, currentNumber)); const ymax = data.Y.reduce((accum: number, currentNumber: number) => Math.max(accum, currentNumber)); - if (isClass) { var pcs = new PointsCloudSystem('pcs', pointSize, scene, { updatable: isClass @@ -405,8 +404,7 @@ export class BabylonImageView extends BabylonBaseView { protected async createScene(): Promise { return super.createScene().then( ( scene ) => { const data = this.values.data; - const img_height = this.values.img_height; - const img_width = this.values.img_width; + const bbox = this.values.xy_bbox; scene.createDefaultCameraOrLight(true, true, true); scene.clearColor = new Color4(0.95, 0.94, 0.92, 1); @@ -422,7 +420,12 @@ export class BabylonImageView extends BabylonBaseView { groundMaterial.specularColor = new Color3(0.5, 0.5, 0.5); groundMaterial.specularPower = 32; - const ground = MeshBuilder.CreateGround("ground", {height: img_height*0.005, width: img_width*0.005, subdivisions: 16}, scene); + const xmin = bbox[0]; + const xmax = bbox[1]; + const ymin = bbox[2]; + const ymax = bbox[3]; + + const ground = MeshBuilder.CreateGround("ground", {height: (xmax-xmin)*0.005, width: (ymax-ymin)*0.005, subdivisions: 36}, scene); ground.material = groundMaterial; let camera = scene.activeCamera as ArcRotateCamera; From e345c3949272e8781eae935dc79730c82b0bd59d Mon Sep 17 00:00:00 2001 From: Margriet Groenendijk Date: Mon, 16 May 2022 11:18:15 +0100 Subject: [PATCH 7/8] Update data.py --- pybabylonjs/data.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/pybabylonjs/data.py b/pybabylonjs/data.py index b2ef57a..758d625 100644 --- a/pybabylonjs/data.py +++ b/pybabylonjs/data.py @@ -84,8 +84,6 @@ def numpy_to_binary(arr): img = ((img - np.min(img)) / (np.max(img) - np.min(img))) * 255 binary_image = numpy_to_binary(img) - #[img_height, img_width] = np.shape(img) - return dict(data=binary_image) @@ -101,27 +99,27 @@ def create_mapbox_image(data: dict, **kwargs): mbtoken = kwargs["mbtoken"] style_id = kwargs["mbstyle"] data_crs = kwargs["crs"] - + dst_crs = {"init": "EPSG:4326"} # lat/lon - + bbox = BoundingBox( data["X"].min(), data["Y"].min(), data["X"].max(), data["Y"].max() ) - + dst_bbox = transform_bounds(data_crs, dst_crs, *bbox) - + print(bbox) print(dst_bbox) w = bbox[2] - bbox[0] h = bbox[3] - bbox[1] - if w>h: + if w > h: ww = 1280 - hh = int(h/w * 1280) - elif h>w: + hh = int(h / w * 1280) + elif h > w: hh = 1280 - ww = int(w/h * 1280) + ww = int(w / h * 1280) print(ww) print(hh) From b1e501b91f9688d6bcda8288ddc2342f2dd73c12 Mon Sep 17 00:00:00 2001 From: Margriet Groenendijk Date: Thu, 26 May 2022 10:48:06 +0100 Subject: [PATCH 8/8] removed print statements --- pybabylonjs/data.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pybabylonjs/data.py b/pybabylonjs/data.py index 758d625..d54539c 100644 --- a/pybabylonjs/data.py +++ b/pybabylonjs/data.py @@ -108,9 +108,6 @@ def create_mapbox_image(data: dict, **kwargs): dst_bbox = transform_bounds(data_crs, dst_crs, *bbox) - print(bbox) - print(dst_bbox) - w = bbox[2] - bbox[0] h = bbox[3] - bbox[1] @@ -121,9 +118,6 @@ def create_mapbox_image(data: dict, **kwargs): hh = 1280 ww = int(w / h * 1280) - print(ww) - print(hh) - f = requests.get( ( "https://api.mapbox.com/styles/v1/mapbox/"