ConicPolygonBufferGeometry and GeoJsonGeometry implements to customThreeObject options
i have noticed that by scaling polygon object i can display curved polygon of country but i want to as flat
is there any solution to this??
import * as THREE from "three";
import Globe from "globe.gl";
// import country_geo_info from "./country_geo_info.json";
import country_geo_info from "./admin_country.json";
import state_geo_info from "./admin_states.json";
import coord_geo_info from "./coord_geo_info.json";
import { ConicPolygonBufferGeometry } from "three-conic-polygon-geometry";
import { GeoJsonGeometry } from "three-geojson-geometry";
import { _objectSpread2, _toConsumableArray$1 } from "./coord.js";
import { FontLoader } from "three/examples/jsm/loaders/FontLoader";
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry";
import { TWEEN } from "three/examples/jsm/libs/tween.module.min";
import ARIAL_BOLD_FONT from "./Gothic A1_Bold.json";
import earcut from "earcut";
import _ from "lodash";
import * as d3 from "d3";
import * as turf from "@turf/turf";
import {
BoxBufferGeometry,
BufferGeometry,
Line,
LineBasicMaterial,
Mesh,
MeshBasicMaterial,
ShapeBufferGeometry,
SphereBufferGeometry,
Vector2
} from "three";
import { result } from "lodash";
class EarthGlobe {
GLOBE_RADIUS = 100;
geo_info = [];
label_rank = 2;
constructor(element, globeImage, width, height) {
this.element = element;
this.globeImage = globeImage;
this.earthGlobe = Globe();
this.width = width;
this.height = height;
this.myFont = new FontLoader().parse(ARIAL_BOLD_FONT);
this.mergeToSingleArray();
this.createGlobe();
this.setGlobeInfo();
}
mergeToSingleArray() {
for (const feature of this.checkArray(country_geo_info)) {
const { properties } = feature;
const { GU_A3, ADMIN } = properties;
const states = this.checkArray(state_geo_info).filter(
item => item.properties.gu_a3 === GU_A3 || item.properties.admin === ADMIN
);
const details = this.checkArray(coord_geo_info).find(item => {
if (item.iso3 === GU_A3 || item.name === ADMIN) return item;
});
feature.details = details;
feature.states = states;
}
for (const feature of this.checkArray(country_geo_info)) {
const { states, details } = feature;
if (states === undefined || states.length < 1 || details === undefined) {
}
}
}
setGlobeInfo() {
this.renderer = this.earthGlobe.renderer();
this.camera = this.earthGlobe.camera();
this.scene = this.earthGlobe.scene();
this.scene.add(new THREE.AxesHelper(1000));
this.controls = this.earthGlobe.controls();
this.renderer.domElement.style.position = "absolute";
this.raycaster = new THREE.Raycaster();
}
checkArray(data) {
if (Array.isArray(data)) return data;
return data.features;
}
createGlobe() {
this.earthGlobe(this.element)
.globeImageUrl(this.globeImage)
.customLayerData(this.checkArray(country_geo_info))
.customLayerLabel(null)
.customThreeObject((d, _) => {
return this.drawFirstLayer(d);
})
.onCustomLayerHover((obj, prevObj) => {})
.onCustomLayerClick((obj, ev, coord) => {})
.onZoom(
_.throttle(coord => {
const alt = coord.altitude;
if (alt > 1.5) {
//* LABEL RANK 3
if (this.label_rank === 3) return;
this.label_rank = 3;
this.showHideByLabelRank();
console.log("above 1.5");
} else if (alt > 0.5) {
if (this.label_rank === 4) return;
this.label_rank = 4;
this.showHideByLabelRank();
console.log("above 0.8");
} else if (alt > 0.2) {
if (this.label_rank === 5) return;
this.label_rank = 5;
this.showHideByLabelRank(true);
console.log("above 0.2");
}
}, 200)
)
.onGlobeReady(() => {});
}
showHideByLabelRank(isHigher) {
for (const item of this.checkArray(country_geo_info)) {
const obj = this.scene.getObjectByName(`${item.properties.ADMIN}_info`);
if (isHigher) {
if (obj && item.properties.LABELRANK >= this.label_rank) {
obj.visible = true;
}
} else {
if (obj && item.properties.LABELRANK <= this.label_rank) {
obj.visible = true;
} else {
obj.visible = false;
}
}
}
}
drawFirstLayer(d) {
const { properties, geometry } = d;
const first_group = this.createGroup(`${properties.ADMIN}_container`);
const coord = geometry.coordinates;
const polygon_group = this.createGroup(`${properties.ADMIN}_country`);
const polygon_color = 0xff0000;
const type = geometry.type;
if (type === "Polygon") {
this.drawPolygon(coord, polygon_color, true, polygon_group);
} else if (type === "MultiPolygon") {
const singlePolygons = this.addCoord(coord);
for (const coords of singlePolygons) {
this.drawPolygon(coords.coords, polygon_color, true, polygon_group);
}
}
const box_obj = this.drawBoxHelper(polygon_group);
const info_group = this.drawCountryName(properties, true, box_obj.boxSize);
first_group.add(info_group);
first_group.add(polygon_group);
return first_group;
}
drawCountryName(properties, hasCircle, polygonBboxSize) {
const alt = 0.01;
const country_info_group = this.createGroup(`${properties.ADMIN}_info`);
const { NAME_KO, LATITUDE, LONGITUDE, LABELRANK, MIN_LABEL, MAX_LABEL, MIN_ZOOM } = properties;
let text;
if (LABELRANK === 2) {
text = this.drawText(NAME_KO, 1, 0xff0000, true);
} else if (LABELRANK === 3) {
text = this.drawText(NAME_KO, 1, 0xff0000, true);
} else if (LABELRANK === 4) {
text = this.drawText(NAME_KO, 0.8, 0xff0000, true);
} else if (LABELRANK === 5) {
text = this.drawText(NAME_KO, 0.3, 0xff0000, true);
} else if (LABELRANK === 6) {
text = this.drawText(NAME_KO, 0.2, 0xff0000, true);
} else if (LABELRANK === 7) {
text = this.drawText(NAME_KO, 0.1, 0xff0000, true);
}
country_info_group.add(text);
if (LABELRANK !== 2 && LABELRANK !== 3) {
country_info_group.visible = false;
}
const coord = this.earthGlobe.getCoords(LATITUDE, LONGITUDE, alt + 0.003);
country_info_group.position.set(coord.x, coord.y, coord.z);
country_info_group.lookAt(this.scene.localToWorld(new THREE.Vector3(0, 0, 0)));
country_info_group.rotateY(Math.PI);
country_info_group.rotateZ((-0 * Math.PI) / 180);
country_info_group.scale.x = country_info_group.scale.y = country_info_group.scale.z = 1;
return country_info_group;
}
drawPolygon(coord, color, hasStroke, polygon_group) {
let alt = 0.01,
resolution = 0.5;
const shape = new ConicPolygonBufferGeometry(coord, 1, this.GLOBE_RADIUS, false, true, false, resolution);
const mesh = this.drawMesh(shape, 0xffffff);
const new_alt = 1 + alt + 0.001;
if (hasStroke) {
const line_alt = new_alt + 0.001;
const line = this.drawLine(coord, resolution);
line.scale.set(line_alt, line_alt, line_alt);
polygon_group.add(line);
}
mesh.scale.set(new_alt, new_alt, new_alt);
polygon_group.add(mesh);
}
drawText(text, size, color, isCenter) {
const text_geometry = new TextGeometry(`${text}`, {
font: this.myFont,
size: size,
height: 0,
curveSegments: 3
});
const text_material = new THREE.MeshBasicMaterial({ color });
if (isCenter) text_geometry.center();
return new THREE.Mesh(text_geometry, text_material);
}
drawLine(coord, resolution) {
const line_shape = new GeoJsonGeometry(
{
type: "Polygon",
coordinates: coord
},
this.GLOBE_RADIUS,
resolution
);
const line = new THREE.LineSegments(line_shape, new THREE.LineBasicMaterial({ color: 0x000000 }));
return line;
}
addCoord(coord) {
const singlePolygons = [];
singlePolygons.push.apply(
singlePolygons,
_toConsumableArray$1(
coord.map(function(coords, idx) {
return _objectSpread2({
coords: coords
});
})
)
);
return singlePolygons;
}
createGroup(name) {
const group = new THREE.Group();
group.name = name;
return group;
}
drawMesh(geometry, color) {
const mesh = new THREE.Mesh(
geometry,
new THREE.MeshBasicMaterial({
color: color,
side: THREE.DoubleSide
})
);
return mesh;
}
drawBoxHelper(object) {
let bbox, boxSize, boxHelper;
bbox = new THREE.Box3();
boxSize = new THREE.Vector3();
boxHelper = new THREE.Box3Helper(bbox, 0xff000);
bbox.setFromObject(object);
bbox.getSize(boxSize);
return {
bbox,
boxSize,
boxHelper
};
}
}
export default EarthGlobe;
I am very new to three.js with webgl and im trying to solve how to put 2d country map above 3d globe map whenever use click the center of each country point
I have manged to draw 3d globe map using
ConicPolygonBufferGeometry and GeoJsonGeometry implements to customThreeObject options
i have noticed that by scaling polygon object i can display curved polygon of country but i want to as flat is there any solution to this??
I am very new to three.js with webgl and im trying to solve how to put 2d country map above 3d globe map whenever use click the center of each country point