Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GeoJson clustering #7208

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#### next release (8.7.5)

- Add clustering trait to GeoJson (and consequently to WFS, ...) using Cesium as viewer.
- TSify some `js` and `jsx` files and provide `.d.ts` ambient type files for a few others. This is so that running `tsc` on an external project that imports Terria code will typecheck successfully.
- Upgraded a bunch of d3 dependencies for fixing security errors.
- Show rectangle selector for WPS bounding box parameter
Expand Down
28 changes: 28 additions & 0 deletions lib/ModelMixins/GeojsonMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ import { ExportData } from "./ExportableMixin";
import FeatureInfoUrlTemplateMixin from "./FeatureInfoUrlTemplateMixin";
import { isDataSource } from "./MappableMixin";
import TableMixin from "./TableMixin";
import PinBuilder from "terriajs-cesium/Source/Core/PinBuilder";
import VerticalOrigin from "terriajs-cesium/Source/Scene/VerticalOrigin";

export const FEATURE_ID_PROP = "_id_";

Expand Down Expand Up @@ -602,6 +604,32 @@ function GeoJsonMixin<T extends AbstractConstructor<BaseType>>(Base: T) {
});
} else {
const dataSource = await this.loadGeoJsonDataSource(geoJsonWgs84);

if (this.clustering.enabled) {
const pinBackgroundColor = this.clustering.pinBackgroundColor;
const pinSize = this.clustering.pinSize;

const pinBuilder = new PinBuilder();
dataSource.clustering.enabled = true;
dataSource.clustering.pixelRange = this.clustering.pixelRange;
dataSource.clustering.minimumClusterSize = this.clustering.minimumClusterSize;
dataSource.clustering.clusterEvent.addEventListener(function (
entities,
cluster
) {
cluster.label.show = false;
cluster.billboard.verticalOrigin = VerticalOrigin.BOTTOM;
cluster.billboard.image = pinBuilder
.fromText(
entities.length.toLocaleString(),
Color.fromCssColorString(pinBackgroundColor),
pinSize
)
.toDataURL();
cluster.billboard.show = true;
});
}

runInAction(() => {
this._dataSource = dataSource;
this._imageryProvider = undefined;
Expand Down
43 changes: 43 additions & 0 deletions lib/Traits/TraitsClasses/ClusteringTraits.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import ModelTraits from "../ModelTraits";
import primitiveTrait from "../Decorators/primitiveTrait";

export default class ClusteringTraits extends ModelTraits {
@primitiveTrait({
name: "Enabled",
description: "True to enable clustering. False by default",
type: "boolean"
})
enabled = false;

@primitiveTrait({
name: "pixelRange",
description:
"The pixel range to extend the screen space bounding box",
type: "number"
})
pixelRange: number = 35;

@primitiveTrait({
name: "minimumClusterSize",
description:
"The minimum number of screen space objects that can be clustered",
type: "number"
})
minimumClusterSize: number = 5;

@primitiveTrait({
name: "pinSize",
description:
"The size of the pin, in pixels",
type: "number"
})
pinSize: number = 60;

@primitiveTrait({
name: "pinBackgroundColor",
type: "string",
description:
"The color of the pin"
})
pinBackgroundColor: string = "gray";
}
9 changes: 9 additions & 0 deletions lib/Traits/TraitsClasses/GeoJsonTraits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import objectTrait from "../Decorators/objectTrait";
import primitiveTrait from "../Decorators/primitiveTrait";
import mixTraits from "../mixTraits";
import ModelTraits from "../ModelTraits";
import ClusteringTraits from "./ClusteringTraits";
import FeatureInfoUrlTemplateTraits from "./FeatureInfoTraits";
import LegendOwnerTraits from "./LegendOwnerTraits";
import StyleTraits from "./StyleTraits";
Expand Down Expand Up @@ -163,4 +164,12 @@ export class GeoJsonTraits extends mixTraits(
"Replaces `MultiPoint` features with its equivalent `Point` features when `true`. This is useful for example when using Table mode which does not support `MultiPoint` features currently."
})
explodeMultiPoints = true;

@objectTrait({
type: ClusteringTraits,
name: "clustering",
description:
"Allows to activate the clustering of entities, works only with Cesium as a viewer."
})
clustering?: ClusteringTraits;
}