| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778 |
- import Cartographic from "../Core/Cartographic.js";
- import Color from "../Core/Color.js";
- import defined from "../Core/defined.js";
- import Cesium3DTileFeature from "./Cesium3DTileFeature.js";
- import createBillboardPointCallback from "./createBillboardPointCallback.js";
-
- /** @import Billboard from "./Billboard.js"; */
- /** @import Cesium3DTileContent from "./Cesium3DTileContent.js"; */
- /** @import Cesium3DTileset from "./Cesium3DTileset.js"; */
- /** @import DistanceDisplayCondition from "../Core/DistanceDisplayCondition.js"; */
- /** @import HorizontalOrigin from "./HorizontalOrigin.js"; */
- /** @import Label from "./Label.js"; */
- /** @import NearFarScalar from "../Core/NearFarScalar.js"; */
- /** @import Polyline from "./Polyline.js"; */
- /** @import VerticalOrigin from "./VerticalOrigin.js"; */
-
- /** @ignore */
- const scratchCartographic = new Cartographic();
-
- /**
- * A point feature of a {@link Cesium3DTileset}.
- * <p>
- * Provides access to a feature's properties stored in the tile's batch table, as well
- * as the ability to show/hide a feature and change its point properties
- * </p>
- * <p>
- * Modifications to a <code>Cesium3DTilePointFeature</code> object have the lifetime of the tile's
- * content. If the tile's content is unloaded, e.g., due to it going out of view and needing
- * to free space in the cache for visible tiles, listen to the {@link Cesium3DTileset#tileUnload} event to save any
- * modifications. Also listen to the {@link Cesium3DTileset#tileVisible} event to reapply any modifications.
- * </p>
- * <p>
- * Do not construct this directly. Access it through {@link Cesium3DTileContent#getFeature}
- * or picking using {@link Scene#pick} and {@link Scene#pickPosition}.
- * </p>
- *
- * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy.
- *
- * @example
- * // On mouse over, display all the properties for a feature in the console log.
- * handler.setInputAction(function(movement) {
- * const feature = scene.pick(movement.endPosition);
- * if (feature instanceof Cesium.Cesium3DTilePointFeature) {
- * const propertyIds = feature.getPropertyIds();
- * const length = propertyIds.length;
- * for (let i = 0; i < length; ++i) {
- * const propertyId = propertyIds[i];
- * console.log(`{propertyId}: ${feature.getProperty(propertyId)}`);
- * }
- * }
- * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
- */
- class Cesium3DTilePointFeature {
- static defaultColor = Color.WHITE;
- static defaultPointOutlineColor = Color.BLACK;
- static defaultPointOutlineWidth = 0.0;
- static defaultPointSize = 8.0;
-
- /**
- * @param {Cesium3DTileContent} content
- * @param {number} batchId
- * @param {Billboard} billboard
- * @param {Label} label
- * @param {Polyline} polyline
- */
- constructor(content, batchId, billboard, label, polyline) {
- this._content = content;
- this._billboard = billboard;
- this._label = label;
- this._polyline = polyline;
-
- this._batchId = batchId;
- this._billboardImage = undefined;
- this._billboardColor = undefined;
- this._billboardOutlineColor = undefined;
- this._billboardOutlineWidth = undefined;
- this._billboardSize = undefined;
- this._pointSize = undefined;
- this._color = undefined;
- this._pointSize = undefined;
- this._pointOutlineColor = undefined;
- this._pointOutlineWidth = undefined;
- this._heightOffset = undefined;
-
- this._pickIds = new Array(3);
-
- setBillboardImage(this);
- }
-
- /**
- * Gets or sets if the feature will be shown. This is set for all features
- * when a style's show is evaluated.
- *
- * @type {boolean}
- *
- * @default true
- */
- get show() {
- return this._label.show;
- }
-
- set show(value) {
- this._label.show = value;
- this._billboard.show = value;
- this._polyline.show = value;
- }
-
- /**
- * Gets or sets the color of the point of this feature.
- * <p>
- * Only applied when <code>image</code> is <code>undefined</code>.
- * </p>
- *
- * @type {Color}
- */
- get color() {
- return this._color;
- }
-
- set color(value) {
- this._color = Color.clone(value, this._color);
- setBillboardImage(this);
- }
-
- /**
- * Gets or sets the point size of this feature.
- * <p>
- * Only applied when <code>image</code> is <code>undefined</code>.
- * </p>
- *
- * @type {number}
- */
- get pointSize() {
- return this._pointSize;
- }
-
- set pointSize(value) {
- this._pointSize = value;
- setBillboardImage(this);
- }
-
- /**
- * Gets or sets the point outline color of this feature.
- * <p>
- * Only applied when <code>image</code> is <code>undefined</code>.
- * </p>
- *
- * @type {Color}
- */
- get pointOutlineColor() {
- return this._pointOutlineColor;
- }
-
- set pointOutlineColor(value) {
- this._pointOutlineColor = Color.clone(value, this._pointOutlineColor);
- setBillboardImage(this);
- }
-
- /**
- * Gets or sets the point outline width in pixels of this feature.
- * <p>
- * Only applied when <code>image</code> is <code>undefined</code>.
- * </p>
- *
- * @type {number}
- */
- get pointOutlineWidth() {
- return this._pointOutlineWidth;
- }
-
- set pointOutlineWidth(value) {
- this._pointOutlineWidth = value;
- setBillboardImage(this);
- }
-
- /**
- * Gets or sets the label color of this feature.
- * <p>
- * The color will be applied to the label if <code>labelText</code> is defined.
- * </p>
- *
- * @type {Color}
- */
- get labelColor() {
- return this._label.fillColor;
- }
-
- set labelColor(value) {
- this._label.fillColor = value;
- this._polyline.show = this._label.show && value.alpha > 0.0;
- }
-
- /**
- * Gets or sets the label outline color of this feature.
- * <p>
- * The outline color will be applied to the label if <code>labelText</code> is defined.
- * </p>
- *
- * @type {Color}
- */
- get labelOutlineColor() {
- return this._label.outlineColor;
- }
-
- set labelOutlineColor(value) {
- this._label.outlineColor = value;
- }
-
- /**
- * Gets or sets the outline width in pixels of this feature.
- * <p>
- * The outline width will be applied to the point if <code>labelText</code> is defined.
- * </p>
- *
- * @type {number}
- */
- get labelOutlineWidth() {
- return this._label.outlineWidth;
- }
-
- set labelOutlineWidth(value) {
- this._label.outlineWidth = value;
- }
-
- /**
- * Gets or sets the font of this feature.
- * <p>
- * Only applied when the <code>labelText</code> is defined.
- * </p>
- *
- * @type {string}
- */
- get font() {
- return this._label.font;
- }
-
- set font(value) {
- this._label.font = value;
- }
-
- /**
- * Gets or sets the fill and outline style of this feature.
- * <p>
- * Only applied when <code>labelText</code> is defined.
- * </p>
- *
- * @type {LabelStyle}
- */
- get labelStyle() {
- return this._label.style;
- }
-
- set labelStyle(value) {
- this._label.style = value;
- }
-
- /**
- * Gets or sets the text for this feature.
- *
- * @type {string}
- */
- get labelText() {
- return this._label.text;
- }
-
- set labelText(value) {
- if (!defined(value)) {
- value = "";
- }
- this._label.text = value;
- }
-
- /**
- * Gets or sets the background color of the text for this feature.
- * <p>
- * Only applied when <code>labelText</code> is defined.
- * </p>
- *
- * @type {Color}
- */
- get backgroundColor() {
- return this._label.backgroundColor;
- }
-
- set backgroundColor(value) {
- this._label.backgroundColor = value;
- }
-
- /**
- * Gets or sets the background padding of the text for this feature.
- * <p>
- * Only applied when <code>labelText</code> is defined.
- * </p>
- *
- * @type {Cartesian2}
- */
- get backgroundPadding() {
- return this._label.backgroundPadding;
- }
-
- set backgroundPadding(value) {
- this._label.backgroundPadding = value;
- }
-
- /**
- * Gets or sets whether to display the background of the text for this feature.
- * <p>
- * Only applied when <code>labelText</code> is defined.
- * </p>
- *
- * @type {boolean}
- */
- get backgroundEnabled() {
- return this._label.showBackground;
- }
-
- set backgroundEnabled(value) {
- this._label.showBackground = value;
- }
-
- /**
- * Gets or sets the near and far scaling properties for this feature.
- *
- * @type {NearFarScalar}
- */
- get scaleByDistance() {
- return this._label.scaleByDistance;
- }
-
- set scaleByDistance(value) {
- this._label.scaleByDistance = value;
- this._billboard.scaleByDistance = value;
- }
-
- /**
- * Gets or sets the near and far translucency properties for this feature.
- *
- * @type {NearFarScalar}
- */
- get translucencyByDistance() {
- return this._label.translucencyByDistance;
- }
-
- set translucencyByDistance(value) {
- this._label.translucencyByDistance = value;
- this._billboard.translucencyByDistance = value;
- }
-
- /**
- * Gets or sets the condition specifying at what distance from the camera that this feature will be displayed.
- *
- * @type {DistanceDisplayCondition}
- */
- get distanceDisplayCondition() {
- return this._label.distanceDisplayCondition;
- }
-
- set distanceDisplayCondition(value) {
- this._label.distanceDisplayCondition = value;
- this._polyline.distanceDisplayCondition = value;
- this._billboard.distanceDisplayCondition = value;
- }
-
- /**
- * Gets or sets the height offset in meters of this feature.
- *
- * @type {number}
- */
- get heightOffset() {
- return this._heightOffset;
- }
-
- set heightOffset(value) {
- const offset = this._heightOffset ?? 0.0;
-
- const ellipsoid = this._content.tileset.ellipsoid;
- const cart = ellipsoid.cartesianToCartographic(
- this._billboard.position,
- scratchCartographic,
- );
- cart.height = cart.height - offset + value;
- const newPosition = ellipsoid.cartographicToCartesian(cart);
-
- this._billboard.position = newPosition;
- this._label.position = this._billboard.position;
- this._polyline.positions = [this._polyline.positions[0], newPosition];
-
- this._heightOffset = value;
- }
-
- /**
- * Gets or sets whether the anchor line is displayed.
- * <p>
- * Only applied when <code>heightOffset</code> is defined.
- * </p>
- *
- * @type {boolean}
- */
- get anchorLineEnabled() {
- return this._polyline.show;
- }
-
- set anchorLineEnabled(value) {
- this._polyline.show = value;
- }
-
- /**
- * Gets or sets the color for the anchor line.
- * <p>
- * Only applied when <code>heightOffset</code> is defined.
- * </p>
- *
- * @type {Color}
- */
- get anchorLineColor() {
- return this._polyline.material.uniforms.color;
- }
-
- set anchorLineColor(value) {
- this._polyline.material.uniforms.color = Color.clone(
- value,
- this._polyline.material.uniforms.color,
- );
- }
-
- /**
- * Gets or sets the image of this feature.
- *
- * @type {string}
- */
- get image() {
- return this._billboardImage;
- }
-
- set image(value) {
- const imageChanged = this._billboardImage !== value;
- this._billboardImage = value;
- if (imageChanged) {
- setBillboardImage(this);
- }
- }
-
- /**
- * Gets or sets the distance where depth testing will be disabled.
- *
- * @type {number}
- */
- get disableDepthTestDistance() {
- return this._label.disableDepthTestDistance;
- }
-
- set disableDepthTestDistance(value) {
- this._label.disableDepthTestDistance = value;
- this._billboard.disableDepthTestDistance = value;
- }
-
- /**
- * Gets or sets the horizontal origin of this point, which determines if the point is
- * to the left, center, or right of its anchor position.
- *
- * @type {HorizontalOrigin}
- */
- get horizontalOrigin() {
- return this._billboard.horizontalOrigin;
- }
-
- set horizontalOrigin(value) {
- this._billboard.horizontalOrigin = value;
- }
-
- /**
- * Gets or sets the vertical origin of this point, which determines if the point is
- * to the bottom, center, or top of its anchor position.
- *
- * @type {VerticalOrigin}
- */
- get verticalOrigin() {
- return this._billboard.verticalOrigin;
- }
-
- set verticalOrigin(value) {
- this._billboard.verticalOrigin = value;
- }
-
- /**
- * Gets or sets the horizontal origin of this point's text, which determines if the point's text is
- * to the left, center, or right of its anchor position.
- *
- * @type {HorizontalOrigin}
- */
- get labelHorizontalOrigin() {
- return this._label.horizontalOrigin;
- }
-
- set labelHorizontalOrigin(value) {
- this._label.horizontalOrigin = value;
- }
-
- /**
- * Get or sets the vertical origin of this point's text, which determines if the point's text is
- * to the bottom, center, top, or baseline of it's anchor point.
- *
- * @type {VerticalOrigin}
- */
- get labelVerticalOrigin() {
- return this._label.verticalOrigin;
- }
-
- set labelVerticalOrigin(value) {
- this._label.verticalOrigin = value;
- }
-
- /**
- * Gets the content of the tile containing the feature.
- *
- * @type {Cesium3DTileContent}
- *
- * @readonly
- * @private
- */
- get content() {
- return this._content;
- }
-
- /**
- * Gets the tileset containing the feature.
- *
- * @type {Cesium3DTileset}
- *
- * @readonly
- */
- get tileset() {
- return this._content.tileset;
- }
-
- /**
- * All objects returned by {@link Scene#pick} have a <code>primitive</code> property. This returns
- * the tileset containing the feature.
- *
- * @type {Cesium3DTileset}
- *
- * @readonly
- */
- get primitive() {
- return this._content.tileset;
- }
-
- /**
- * @private
- */
- get pickIds() {
- const ids = this._pickIds;
- ids[0] = this._billboard.pickId;
- ids[1] = this._label.pickId;
- ids[2] = this._polyline.pickId;
- return ids;
- }
-
- /**
- * Returns whether the feature contains this property. This includes properties from this feature's
- * class and inherited classes when using a batch table hierarchy.
- *
- * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy}
- *
- * @param {string} name The case-sensitive name of the property.
- * @returns {boolean} Whether the feature contains this property.
- */
- hasProperty(name) {
- return this._content.batchTable.hasProperty(this._batchId, name);
- }
-
- /**
- * Returns an array of property IDs for the feature. This includes properties from this feature's
- * class and inherited classes when using a batch table hierarchy.
- *
- * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy}
- *
- * @param {string[]} [results] An array into which to store the results.
- * @returns {string[]} The IDs of the feature's properties.
- */
- getPropertyIds(results) {
- return this._content.batchTable.getPropertyIds(this._batchId, results);
- }
-
- /**
- * Returns a copy of the value of the feature's property with the given name. This includes properties from this feature's
- * class and inherited classes when using a batch table hierarchy.
- *
- * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy}
- *
- * @param {string} name The case-sensitive name of the property.
- * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property.
- *
- * @example
- * // Display all the properties for a feature in the console log.
- * const propertyIds = feature.getPropertyIds();
- * const length = propertyIds.length;
- * for (let i = 0; i < length; ++i) {
- * const propertyId = propertyIds[i];
- * console.log(`{propertyId} : ${feature.getProperty(propertyId)}`);
- * }
- */
- getProperty(name) {
- return this._content.batchTable.getProperty(this._batchId, name);
- }
-
- /**
- * Returns a copy of the value of the feature's property with the given name.
- * If the feature is contained within a tileset that has metadata (3D Tiles 1.1)
- * or uses the <code>3DTILES_metadata</code> extension, tileset, group and tile metadata is
- * inherited.
- * <p>
- * To resolve name conflicts, this method resolves names from most specific to
- * least specific by metadata granularity in the order: feature, tile, group,
- * tileset. Within each granularity, semantics are resolved first, then other
- * properties.
- * </p>
- * @param {string} name The case-sensitive name of the property.
- * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property.
- * @private
- * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy.
- */
- getPropertyInherited(name) {
- return Cesium3DTileFeature.getPropertyInherited(
- this._content,
- this._batchId,
- name,
- );
- }
-
- /**
- * Sets the value of the feature's property with the given name.
- * <p>
- * If a property with the given name doesn't exist, it is created.
- * </p>
- *
- * @param {string} name The case-sensitive name of the property.
- * @param {*} value The value of the property that will be copied.
- *
- * @exception {DeveloperError} Inherited batch table hierarchy property is read only.
- *
- * @example
- * const height = feature.getProperty('Height'); // e.g., the height of a building
- *
- * @example
- * const name = 'clicked';
- * if (feature.getProperty(name)) {
- * console.log('already clicked');
- * } else {
- * feature.setProperty(name, true);
- * console.log('first click');
- * }
- */
- setProperty(name, value) {
- this._content.batchTable.setProperty(this._batchId, name, value);
-
- // PERFORMANCE_IDEA: Probably overkill, but maybe only mark the tile dirty if the
- // property is in one of the style's expressions or - if it can be done quickly -
- // if the new property value changed the result of an expression.
- this._content.featurePropertiesDirty = true;
- }
-
- /**
- * Returns whether the feature's class name equals <code>className</code>. Unlike {@link Cesium3DTilePointFeature#isClass}
- * this function only checks the feature's exact class and not inherited classes.
- * <p>
- * This function returns <code>false</code> if no batch table hierarchy is present.
- * </p>
- *
- * @param {string} className The name to check against.
- * @returns {boolean} Whether the feature's class name equals <code>className</code>
- *
- * @private
- */
- isExactClass(className) {
- return this._content.batchTable.isExactClass(this._batchId, className);
- }
-
- /**
- * Returns whether the feature's class or any inherited classes are named <code>className</code>.
- * <p>
- * This function returns <code>false</code> if no batch table hierarchy is present.
- * </p>
- *
- * @param {string} className The name to check against.
- * @returns {boolean} Whether the feature's class or inherited classes are named <code>className</code>
- *
- * @private
- */
- isClass(className) {
- return this._content.batchTable.isClass(this._batchId, className);
- }
-
- /**
- * Returns the feature's class name.
- * <p>
- * This function returns <code>undefined</code> if no batch table hierarchy is present.
- * </p>
- *
- * @returns {string} The feature's class name.
- *
- * @private
- */
- getExactClassName() {
- return this._content.batchTable.getExactClassName(this._batchId);
- }
- }
-
- /**
- * @param {Cesium3DTilePointFeature} feature
- * @ignore
- */
- function setBillboardImage(feature) {
- const b = feature._billboard;
- if (defined(feature._billboardImage) && feature._billboardImage !== b.image) {
- b.image = feature._billboardImage;
- return;
- }
-
- if (defined(feature._billboardImage)) {
- return;
- }
-
- const newColor = feature._color ?? Cesium3DTilePointFeature.defaultColor;
- const newOutlineColor =
- feature._pointOutlineColor ??
- Cesium3DTilePointFeature.defaultPointOutlineColor;
- const newOutlineWidth =
- feature._pointOutlineWidth ??
- Cesium3DTilePointFeature.defaultPointOutlineWidth;
- const newPointSize =
- feature._pointSize ?? Cesium3DTilePointFeature.defaultPointSize;
-
- const currentColor = feature._billboardColor;
- const currentOutlineColor = feature._billboardOutlineColor;
- const currentOutlineWidth = feature._billboardOutlineWidth;
- const currentPointSize = feature._billboardSize;
-
- if (
- Color.equals(newColor, currentColor) &&
- Color.equals(newOutlineColor, currentOutlineColor) &&
- newOutlineWidth === currentOutlineWidth &&
- newPointSize === currentPointSize
- ) {
- return;
- }
-
- feature._billboardColor = Color.clone(newColor, feature._billboardColor);
- feature._billboardOutlineColor = Color.clone(
- newOutlineColor,
- feature._billboardOutlineColor,
- );
- feature._billboardOutlineWidth = newOutlineWidth;
- feature._billboardSize = newPointSize;
-
- const centerAlpha = newColor.alpha;
- const cssColor = newColor.toCssColorString();
- const cssOutlineColor = newOutlineColor.toCssColorString();
- const textureId = JSON.stringify([
- cssColor,
- newPointSize,
- cssOutlineColor,
- newOutlineWidth,
- ]);
-
- b.setImage(
- textureId,
- createBillboardPointCallback(
- centerAlpha,
- cssColor,
- cssOutlineColor,
- newOutlineWidth,
- newPointSize,
- ),
- );
- }
-
- export default Cesium3DTilePointFeature;
|