How to customize czml datasource? - datasource

I have a CZML data that I extracted via python.
I have buildings, with their geometry, height, building ID, and intervals. each interval has a value.
After loading the czml data to Cesium, I'd like to access the attributes and then customize the color of the buildings according to the value given.
Here is a sample of my CZML:
[{
"id": "document",
"version": "1.0"
}, {
"id": 32,
"availability": "2014-01-01T00:00:00Z/2014-12-31T00:00:00Z",
"polygon": {
"positions": {
"cartographicDegrees": [54.7162360431897, 24.4519912715277, 0, 54.716219612921, 24.4519754832587, 0, 54.7162501395131, 24.4519488635358, 0, 54.7162465684811, 24.4519454316688, 0, 54.7162670831639, 24.4519275432238, 0, 54.7162707308589, 24.4519310439514, 0, 54.7163022563025, 24.4519035537608, 0, 54.7161962974502, 24.4518018819532, 0, 54.7161647729823, 24.4518293730395, 0, 54.7162035538772, 24.4520196028966, 0, 54.7162360431897, 24.4519912715277, 0]
},
"someProperty": [{
"interval": "2014-00-01T00:00:00Z/2014-01-01T00:00:00Z",
"En_C_need": 0.7
}, {
"interval": "2014-01-01T00:00:00Z/2014-02-01T00:00:00Z",
"En_C_need": 1.0
}, {
"interval": "2014-02-01T00:00:00Z/2014-03-01T00:00:00Z",
"En_C_need": 2.6
}, {
"interval": "2014-03-01T00:00:00Z/2014-04-01T00:00:00Z",
"En_C_need": 12.1
}, {
"interval": "2014-04-01T00:00:00Z/2014-05-01T00:00:00Z",
"En_C_need": 30.2
}, {
"interval": "2014-05-01T00:00:00Z/2014-06-01T00:00:00Z",
"En_C_need": 37.8
}],
"extrudedHeight": 6.0
}
}]
I have other GeoJSON data that I customized, I tried the same method but it didn't work.
Here is what I'm trying to do (this does not work):
var test2 = Cesium.CzmlDataSource.load ('Data/czml/TESTING/example_8.czml');
test2.then(function (dataSource) {
viewer.dataSources.add(test2);
viewer.zoomTo (test2);
var entities = dataSource.entities.values;
var colorHash = {};
var Energy = [];
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
Energy = entity.someProperty.En_C_need;
var color = colorHash [Energy];
if(!color ) {
if (Energy < 5 ) {
color = Cesium.Color.DARKSALMON.withAlpha (0.95);
} else if (Energy < 10) {
color = Cesium.Color.BURLYWOOD.withAlpha (0.95);
} else if (Energy < 20) {
color = Cesium.Color.RED.withAlpha (0.95);
} else {
color = Cesium.Color.PINK.withAlpha (0.95);
};
colorHash[Energy] = color;
};
entity.polygon.fill = true;
entity.polygon.material = color;
entity.polygon.outline = false;
};
});

To start with the solution - here's the working plnkr:
https://plnkr.co/edit/P1Cg4DNJYtK9r9XrLzxK?p=preview
I've changed several things in your code:
1) viewer.dataSources.add(test2); should be outside your promise (it doesn't really matter, but it's cleaner code - using the promise inside the promise feels strange).
2) According to the CZML properties spec, you need to place the properties in the right location in the CZML. It should not be inside the polygon, but in the "root":
var czml = [{"id": "document", "version": "1.0"},
{
"id": 32, "availability": "2014-01-01T00:00:00Z/2014-12-31T00:00:00Z", "properties": {
"someProperty": [
{"interval": "2014-00-01T00:00:00Z/2014-01-01T00:00:00Z", "En_C_need": 0.7},
{"interval": "2014-01-01T00:00:00Z/2014-02-01T00:00:00Z", "En_C_need": 1.0},
{"interval": "2014-02-01T00:00:00Z/2014-03-01T00:00:00Z", "En_C_need": 2.6},
{"interval": "2014-03-01T00:00:00Z/2014-04-01T00:00:00Z", "En_C_need": 12.1},
{"interval": "2014-04-01T00:00:00Z/2014-05-01T00:00:00Z", "En_C_need": 30.2},
{"interval": "2014-05-01T00:00:00Z/2014-06-01T00:00:00Z", "En_C_need": 37.8}
],
},
"polygon": {
"positions": {
"cartographicDegrees":
[54.7162360431897, 24.4519912715277, 0, 54.716219612921, 24.4519754832587, 0, 54.7162501395131, 24.4519488635358, 0, 54.7162465684811, 24.4519454316688, 0, 54.7162670831639, 24.4519275432238, 0, 54.7162707308589, 24.4519310439514, 0, 54.7163022563025, 24.4519035537608, 0, 54.7161962974502, 24.4518018819532, 0, 54.7161647729823, 24.4518293730395, 0, 54.7162035538772, 24.4520196028966, 0, 54.7162360431897, 24.4519912715277, 0]
},
"extrudedHeight": 6.0
}
}];
Then you can ask for the properties according to the interval (Energy = entity.properties.getValue(viewer.clock.currentTime).someProperty.En_C_need;) and get the Energy at viewer's current time.
Update after commentchatting:
Your code was not meant to change dynamically. You need to set the value either by callbackProperty as in this example: plnkr.co/edit/lm290uaQewEvfIOgXbDP?p=preview or by using timeIntervalCollection

Related

Change color of pie chart with google sheets API

I'm using Python google sheet API v4 to produce a pie chart using the following code:
body = {
"requests": [
{
"addChart": {
"chart": {
"spec": {
"backgroundColorStyle" : {
"themeColor": "BACKGROUND"
},
"pieChart": {
"legendPosition": "LABELED_LEGEND",
"pieHole":0.7,
"domain": {
"sourceRange": {
"sources": [
{
"sheetId": 0,
"startRowIndex": 0,
"endRowIndex": last_row,
"startColumnIndex": 0,
"endColumnIndex": 1
}
]
}
},
"series": {
"sourceRange": {
"sources": [
{
"sheetId": 0,
"startRowIndex": 0,
"endRowIndex": 7,
"startColumnIndex": 3,
"endColumnIndex": 4
}
]
}
},
}
},
"position": {
"overlayPosition": {
"anchorCell": {
"sheetId": 0,
"rowIndex": 1,
"columnIndex": 5
}
}
}
}
}
}
]
}
request = service.spreadsheets().batchUpdate(spreadsheetId=sheet_id, body=body)
response = request.execute()
This get me exactly what I want, but I would like to set the color of each slice according to a give color palette. I've looked for a way to do so but haven't found it, so is it possible to do so thought the API?
To further clarify with an image, this is what I get with 4 class. How can I set the color of this 4 slice to go from green, blu, yellow, red to green, purple, yellow, orange?
Graph I get with 4 class

threeJS Raycaster.set() not detecting intersections ( plane )

const origin = new THREE.Vector3(...point, -100),
direction = new THREE.Vector3(0, 0, 1) // is a normalized vector
const raycaster = new THREE.Raycaster( origin, direction );
const intersects = raycaster.intersectObject( dem ); // is a planeGeometry (mesh)
const length = 2000;
const hex = 0xff0000;
const arrowHelper = new THREE.ArrowHelper( direction, origin, length, hex );
cx3d.addObject( arrowHelper );
if( intersects.length ){
console.log( intersects[0] )
}
now intersects = [], but point is in the plane mesh, so I need help, thank everyone
like this https://jsfiddle.net/Hoshua/obm8ke0q/2/
You need to update your mesh matrix world with mesh.updateMatrixWorld();. See below.
function seta(){
const origin = new THREE.Vector3(0.5, 0, 0),
direction = new THREE.Vector3(-1, 0, 0)
const raycaster = new THREE.Raycaster( origin, direction );
mesh.updateMatrixWorld(); // here
const intersects = raycaster.intersectObject( mesh );
const length = 1.5;
const hex = 0xff0000;
const arrowHelper = new THREE.ArrowHelper( direction, origin, length, hex );
scene.add( arrowHelper );
console.log(intersects)
}
Not sure if link will work. In case: https://jsfiddle.net/4n0tgwuo/
Output:
[{
distance: 0.5,
face: {
a: 0,
b: 2,
c: 1,
materialIndex: 0,
normal: { ... }
},
faceIndex: 0,
object: {
animations: [],
castShadow: false,
children: [],
frustumCulled: true,
geometry: { ... },
isMesh: true,
isObject3D: true,
layers: { ... },
material: { ... },
matrix: { ... },
matrixAutoUpdate: true,
matrixWorld: { ... },
matrixWorldNeedsUpdate: false,
name: "",
parent: { ... },
position: { ... },
quaternion: { ... },
receiveShadow: false,
renderOrder: 0,
rotation: { ... },
scale: { ... },
type: "Mesh",
up: { ... },
userData: { ... },
uuid: "cb14eb31-b325-4252-8fb6-0d4417cbf39d",
visible: true
},
point: {
isVector3: true,
x: 0,
y: 0,
z: 0
},
uv: {
isVector2: true,
x: 0.5,
y: 0.5
}
}, {
distance: 0.5,
face: {
a: 2,
b: 3,
c: 1,
materialIndex: 0,
normal: { ... }
},
faceIndex: 1,
object: [circular object Object],
point: {
isVector3: true,
x: 0,
y: 0,
z: 0
},
uv: {
isVector2: true,
x: 0.5,
y: 0.5
}
}]

Generate custom ores in custom dimension

I have recently created a custom dimension using data packs in Minecraft 1.16.5.
This dimension is a part of a mod that I am writing and I am currently trying to generate custom ores in that dimension; However, I was not able to generate ores in a custom dimension the same way that I generate ores in the Overworld or Nether. As I mentioned the dimension is handled via data packs (.json files) but the biomes are handled in game code (.java). I am very new to Java & modding, any suggestions would be appreciated.
Thanks in advance.
Minecraft version : 1.16.5
Forge version : 36.2.9
The current code for Overworld & Nether ore gen :
public class OreGeneration
{
public static void generateOres(final BiomeLoadingEvent event)
{
// Gigalium :
if(!(event.getCategory().equals(Biome.Category.THEEND)))
{
// Nether :
if(event.getCategory().equals(Biome.Category.NETHER))
{
generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 6, 25, 50, 2);
generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 4, 51, 120, 2);
}
// Overworld :
if(event.getCategory().equals(Biome.Category.SWAMP) || event.getCategory().equals(Biome.Category.TAIGA))
{
generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 5, 12, 15, 2);
generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 16, 20, 2);
}
if(!(event.getCategory().equals(Biome.Category.SWAMP) && event.getCategory().equals(Biome.Category.TAIGA)))
{
generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 10, 13, 1);
generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 3, 14, 18, 1);
}
}
}
private static void generateOre(BiomeGenerationSettingsBuilder settings, RuleTest fillerType, BlockState state, int veinSize, int minHeight, int maxHeight, int amount)
{
settings.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Feature.ORE.configured(new OreFeatureConfig(fillerType, state, veinSize)).decorated(Placement.RANGE.configured(new TopSolidRangeConfig(minHeight, 0, maxHeight))).squared().count(amount));
}
}
Dimension code :
{
"type": "gigawhat_gigamod:gigaland",
"generator": {
"type": "minecraft:noise",
"seed": 0,
"settings": {
"bedrock_roof_position": -10,
"bedrock_floor_position": 0,
"sea_level": 80,
"disable_mob_generation": true,
"default_block": {
"Name": "gigawhat_gigamod:gigastone"
},
"default_fluid": {
"Name": "minecraft:water",
"Properties": {
"level": "0"
}
},
"noise": {
"height": 256,
"density_factor": 1,
"density_offset": -0.46875,
"size_horizontal": 1,
"size_vertical": 2,
"simplex_surface_noise": true,
"random_density_offset": true,
"amplified": true,
"sampling": {
"xz_scale": 1,
"y_scale": 1,
"xz_factor": 80,
"y_factor": 160
},
"bottom_slide": {
"target": -30,
"size": 0,
"offset": 0
},
"top_slide": {
"target": -10,
"size": 3,
"offset": 0
}
},
"structures": {
"structures": {}
}
},
"biome_source": {
"type": "minecraft:fixed",
"biome": "gigawhat_gigamod:gigaland_main_biome"
}
}
}
Biome Init code :
public class ModBiomes
{
public static final DeferredRegister<Biome> BIOMES = DeferredRegister.create(ForgeRegistries.BIOMES, Gigamod.MOD_ID);
public static final RegistryObject<Biome> GIGALAND_MAIN_BIOME = BIOMES.register("gigaland_main_biome", () -> makeGigalandMainBiome(() -> ModConfiguredSurfaceBuilders.GIGALAND_SURFACE, 0.205f, 0.02f));
private static Biome makeGigalandMainBiome(final Supplier<ConfiguredSurfaceBuilder<?>> surfaceBuilder, float depth, float scale)
{
MobSpawnInfo.Builder mobspawninfo$builder = new MobSpawnInfo.Builder();
BiomeGenerationSettings.Builder biomegenerationsettings$builder = (new BiomeGenerationSettings.Builder()).surfaceBuilder(surfaceBuilder);
DefaultBiomeFeatures.addDefaultOverworldLandStructures(biomegenerationsettings$builder);
biomegenerationsettings$builder.addStructureStart(StructureFeatures.MINESHAFT);
DefaultBiomeFeatures.addDefaultCarvers(biomegenerationsettings$builder);
DefaultBiomeFeatures.addDefaultUndergroundVariety(biomegenerationsettings$builder);
mobspawninfo$builder.addSpawn(EntityClassification.MONSTER, new MobSpawnInfo.Spawners(EntityType.BLAZE, 100, 10, 15));
return (new Biome.Builder()).precipitation(RainType.RAIN).biomeCategory(Category.EXTREME_HILLS).depth(depth).scale(scale).temperature(1.5F).downfall(0.9F).specialEffects((new BiomeAmbience.Builder()).waterColor(65518).waterFogColor(16763760).fogColor(16763760).skyColor(16763760).foliageColorOverride(9547008).grassColorOverride(9547008).ambientParticle(new ParticleEffectAmbience(ParticleTypes.LAVA, 0.003f)).skyColor(16763760).ambientLoopSound(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP).ambientMoodSound(new MoodSoundAmbience(SoundEvents.AMBIENT_WARPED_FOREST_MOOD, 6000, 8, 2.0D)).ambientAdditionsSound(new SoundAdditionsAmbience(SoundEvents.AMBIENT_NETHER_WASTES_MOOD, 0.0111D)).build()).mobSpawnSettings(mobspawninfo$builder.build()).generationSettings(biomegenerationsettings$builder.build()).build();
}
public static void register(IEventBus eventBus)
{
BIOMES.register(eventBus);
}
}
Answering my own question.
Instead of using event.getCategory().equals(SomeBiomeCategory) in the if statement in the OreGen class you should use event.getName().equals(YourModBiomeInit.BiomeName.getId(). Because event.getCategory().equals(SomeBiomeCategory) gets the category of the biome currently generating whilst event.getName().equals(YourModBiomeInit.BiomeName.getId() gets the registered name (or id).
So the if statement would look something like this :
if(event.getName().equals(YourModBiomeInit.SOME_BIOME.getId()))
{
// Generate ores ...
}

Trying to do slow scrolling, but it seems gsap can't handle as many events per scroll

I need to slow down scroll speed on the page to animate elements better (For example one wheel event on mine laptop makes deltaY = 378 and it's too hard to calculate correct offset to start animations). I decided to disable scroll with e.preventDefault() and e.returnValue = false. It works well, but sometimes page starts 'jumping', when u try to scroll.
import { gsap } from 'gsap'
import { ScrollToPlugin } from 'gsap/src/ScrollToPlugin.js'
gsap.registerPlugin(ScrollToPlugin);
export default {
data: () => {
return {
currentSlide: 0,
offsetTop: 0,
pageHeight: 0,
wheelCounter: 0,
scrollCounter: 0,
slides: [
{
id: 'ad1',
bg: '/hall.jpg'
},
{
id: 'ad2',
bg: '/home.jpg'
},
{
id: 'ad3',
bg: '/hall.jpg'
},
{
id: 'ad4',
bg: '/home.jpg'
}]
}
},
methods: {
checkScroll (event) {
event.returnValue = false
event.preventDefault()
let sliderGap = 300
let current, next
let tl = gsap.timeline()
this.wheelCounter += parseInt(event.deltaY / 5)
if (this.wheelCounter < 0) this.wheelCounter = 0
gsap.to(window, {scrollTo: this.wheelCounter, duration: 0.2})
current = parseInt(this.wheelCounter / sliderGap)
if (current > 4) current = 4
if ((current != this.currentSlide) && (current < 4)) {
document.getElementById('main').style.backgroundImage = 'url("' + this.slides[current].bg + '")'
tl.to('#' + this.slides[this.currentSlide].id, {x: 20, opacity: 0, duration: 0.3})
tl.to('#' + this.slides[current].id, {x: -20, opacity: 1, duration: 0.7})
this.currentSlide = current
}
if (window.scrollY > 300) {
tl.to('#about_header', {x: 0, opacity: 1, duration: 0.7})
tl.to('#about_description', {y: 0, opacity: 1, duration: 0.7}, 0.5)
tl.to('#about_picture', {x: 0, opacity: 1, duration: 1}, 0.5)
}
if (window.scrollY > 500) {
tl.to('#left_offer', {y: 0, opacity: 1, duration: 1}, 0)
tl.to('#right_offer', {y: 0, opacity: 1, duration: 1}, 0.5)
tl.to('#offers_description', {x: 0, opacity: 1, duration: 0.5}, 1.5)
}
}
}
}
I thought about adding vue-observe-visibility package and perform animation via it. But scroll should be smooth too and idk how can I do it.

jsaTypeError: GoogleTiledMap is not a constructor

I define a class and then use it to create a layer.but it has error.but I don't know where it was wrong?
define(["dojo/_base/declare","esri/SpatialReference","esri/layers/TiledMapServiceLayer","esri/geometry/webMercatorUtils","esri/geometry/Extent",
"esri/layers/TileInfo"],function(declare,SpatialReference,TiledMapServiceLayer,webMercatorUtils,Extent,TileInfo){
declare("extras.layer.GoogleTiledMap", [TiledMapServiceLayer], {
online: false,
mapStyle: "roadmap",
constructor: function(a) {
this.spatialReference = new esri.SpatialReference({
wkid: 102113
});
this.online = a.online || false;
this.mapStyle = a.mapStyle || "roadmap";
this.layerId = a.layerId;
this.suffix = a.suffix || ".png";
this.tile_url = a.tile_url;
this.fullExtent = new Extent( - 20037508.342787, -20037508.342787, 20037508.342787, 20037508.342787, this.spatialReference);
this.initialExtent = new Extent(12557877.595482401, 2596928.9267310356, 12723134.450635016, 2688653.360673282);
this.tileInfo = new TileInfo({
"rows": 256,
"cols": 256,
"compressionQuality": 0,
"origin": {
"x": -20037508.342787,
"y": 20037508.342787
},
"spatialReference": {
"wkid": 102113
},
"lods": [{
"level": 3,
"scale": 73957190.948944,
"resolution": 19567.8792409999
},
{ ...
I use it in html file.
require([
"esri/map",
"extras/layer/GoogleTiledMap",
"dojo/domReady!"
], function(map,GoogleTiledMap) {
var layer=new GoogleTiledMap({
"id": "100",
"layerId":"GXX_XXXXX",
"online":false,
"name": "谷歌电子地图",
"suffix": "png",
"tileSize": "256",
"tileType": "googlemap",
"mapStyle":"roadmap",
"tile_url": "127.0.0.1:8080"
});
Just declaring is not sufficient, you need to return it as well. Like below
define(["dojo/_base/declare",...], function(declare,...){
return declare([...], {
//you module here
});
});