Mesh Map
Overview
The Mesh Map prefab takes a GeoJson and d3-geo projection input and generates a Extruded Polygon mesh for each polygon or multi-polygon GeoJSON feature. This prefab also utilize topoJson for mesh simplification. The createMeshMap() method returns an instance of the MeshMap object which contains the relevant properties for the mesh creation and manipulation. Each polygon metadata.data property will be set with the data from its features.properties GeoJSON.
Usage
js
//name (required), options (geojson required), babylon scene (optional)
// returns instance of MeshMap
let map = anu.createMeshMap(name: String, options: {}, scene: BABYLON.Scene);
//The transformed input d3-geo projection
let projection = map.projection
// A selection object containing all the generated polygons
let selection = map.selection
Options
Option | Value | Default |
---|---|---|
geoJson (required) | a valid geoJSON file | null |
projection | (d3.GeoProjection) such as d3.geoAlbers() | d3.geoAlbers() |
size | ([number, number]) an array with the max height and width of the projection | [10,10] |
transform | ([number, number]) and array with the center coordinates of the projection in render space | [0,0] |
simplification | (number) the simplification factor relative to the projection size | 0 |
depth | (number) the height of the extruded the polygons | 1 |
cot | (Babylon.Node) The node to be the parent of all the polygons, if not set a transform node "meshMapCOT" will be created | TransformNode('meshMapCOT') |
Methods and Properties
Property / Method | Description |
---|---|
projection | the transformed d3.geoProjection which can be used map position from longitude and latitude as projection([lon, lat]) |
selection | a selection object containing all the generated polygons with their respective geoJSON properties data binded to them |
Examples
js
// SPDX-License-Identifier: Apache-2.0
// Copyright : J.P. Morgan Chase & Co.
import * as anu from '@jpmorganchase/anu';
import * as d3 from "d3";
import { Scene, HemisphericLight, ArcRotateCamera, Vector3, Color4 } from '@babylonjs/core';
import data from './data/airports.csv'; //Our data
import geoJ from "./data/gz_2010_us_040_00_5m.json"; //GeoJSON
//Create and export a function that takes a Babylon engine and returns a Babylon Scene
export function meshMap(engine) {
//Create an empty Scene
const scene = new Scene(engine);
//Add some lighting
new HemisphericLight('light1', new Vector3(0, 10, 0), scene);
//Add a camera that rotates around the origin and adjust its properties
const camera = new ArcRotateCamera("Camera", -(Math.PI / 4) * 3, Math.PI / 4, 10, new Vector3(0, 0, 0), scene);
camera.wheelPrecision = 100; // Adjust the sensitivity of the mouse wheel's zooming
camera.minZ = 0; // Adjust the distance of the camera's near plane
camera.attachControl(true); // Allow the camera to respond to user controls
camera.position = new Vector3(0, 1.25, -1);
//createMeshMap() is an Anu prefab that easily allows us to create a mesh map using geoJSON data
let meshMap = anu.createMeshMap('meshMap', { geoJson: geoJ, depth: 0.05, projection: d3.geoAlbers().reflectY(true), size: [2, 2], simplification: 0.00001 });
//Get the newly created meshes that correspond to US states as an Anu selection
let states = meshMap.selection;
//Create a D3 color scale to assign colors to these states
let scaleC = d3.scaleOrdinal(anu.ordinalChromatic('d310').toStandardMaterial());
//Set their color
states.material((d) => scaleC(d.NAME))
.prop("isPickable", false); //Turn off picking to improve performance of our complex mesh geometry
//If picking of the mesh map is necessary, wrap it in an empty mesh that is sized to the bounding box
//Get the CoT of the mesh map
let CoT = anu.selectName("meshMap", scene);
//Because our data has over 3000 points, we will use mesh instancing for better performance
//Create a mesh to be our root instance, and register a buffer for color
let rootSphere = anu.create('sphere', 'sphere', {diameter: 0.003})
rootSphere.isVisible = false;
rootSphere.registerInstancedBuffer("color", 4);
rootSphere.instancedBuffers.color = new Color4(0, 0, 0, 1);
//Create our spheres for our data
let spheres = CoT.bindInstance(rootSphere, data)
.positionX((d) => meshMap.projection([d.longitude, d.latitude])[0]) //The meshMap prefab object contains a projection() function that will convert
.positionZ((d) => meshMap.projection([d.longitude, d.latitude])[1]) //a longitude and latitude into the correct position on the meshMap
.setInstancedBuffer("color", new Color4(0,0,0,1));
return scene;
}