Skip to content

Commit

Permalink
Merge pull request #7002 from TerriaJS/geojson-table-changes
Browse files Browse the repository at this point in the history
Geojson and  Table style changes
  • Loading branch information
nf-s committed Dec 8, 2023
2 parents 12ccee3 + 788b485 commit c4d9682
Show file tree
Hide file tree
Showing 13 changed files with 508 additions and 82 deletions.
10 changes: 10 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,18 @@

#### next release (8.4.1)

- Temporary UX fixes for clipping box:
- An option to zoom to clipping box
- An option to re-position the clipping box
- Trigger repositioning of clipping box when the user enables clipping box for the first time
- Cursor and scale point handle changes (makes it much easier to grasp)
- More robust interaction with the box
- Fix a bug where `DragPoints` was interfering with pedstrian mode mouse movements.
- Update `webpack` to `4.47.0` to support Node >= 18 without extra command line parameters.
- Add support for multiple `urls` for `GeoJsonCatalogItem`.
- Automatically explode GeoJSON `MultiPoint` features to `Point` features.
- Add new table styling traits - `scaleByDistance` and `disableDepthTestDistance`.
- Add support for `LineString` and `MultiLineString` when using `GeoJsonCatalogItem` in `CZML` mode.
- [The next improvement]

#### 8.4.0 - 2023-12-01
Expand Down
95 changes: 89 additions & 6 deletions lib/ModelMixins/GeojsonMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
Geometries,
Geometry,
GeometryCollection,
LineString,
MultiLineString,
MultiPoint,
MultiPolygon,
Point,
Expand All @@ -29,10 +31,10 @@ import {
} from "mobx";
import { createTransformer } from "mobx-utils";
import {
Feature as ProtomapsFeature,
GeomType,
LineSymbolizer,
PolygonSymbolizer,
Feature as ProtomapsFeature
PolygonSymbolizer
} from "protomaps";
import Cartesian2 from "terriajs-cesium/Source/Core/Cartesian2";
import Cartesian3 from "terriajs-cesium/Source/Core/Cartesian3";
Expand Down Expand Up @@ -75,8 +77,8 @@ import { isJson } from "../Core/loadBlob";
import StandardCssColors from "../Core/StandardCssColors";
import TerriaError, { networkRequestError } from "../Core/TerriaError";
import ProtomapsImageryProvider, {
GEOJSON_SOURCE_LAYER_NAME,
GeojsonSource,
GEOJSON_SOURCE_LAYER_NAME,
ProtomapsData
} from "../Map/ImageryProvider/ProtomapsImageryProvider";
import Reproject from "../Map/Vector/Reproject";
Expand Down Expand Up @@ -396,6 +398,7 @@ function GeoJsonMixin<T extends AbstractConstructor<BaseType>>(Base: T) {
points = points?.entities.values.length === 0 ? undefined : points;

points ? (points.show = this.show) : null;

return filterOutUndefined([
points,
this._dataSource,
Expand Down Expand Up @@ -478,6 +481,7 @@ function GeoJsonMixin<T extends AbstractConstructor<BaseType>>(Base: T) {
protected async forceLoadMapItems(): Promise<void> {
const czmlTemplate = this.czmlTemplate;
const filterByProperties = this.filterByProperties;
const explodeMultiPoints = this.explodeMultiPoints;

let geoJson: FeatureCollectionWithCrs | undefined;

Expand Down Expand Up @@ -534,6 +538,14 @@ function GeoJsonMixin<T extends AbstractConstructor<BaseType>>(Base: T) {
continue;
}

if (explodeMultiPoints && feature.geometry.type === "MultiPoint") {
// Replace the MultiPoint with equivalent Point features and repeat
// the iteration to pick up the exploded features.
features.splice(i, 1, ...explodeMultiPoint(feature));
i--;
continue;
}

geoJsonWgs84.features.push(feature);

// Add feature index to FEATURE_ID_PROP ("_id_") feature property
Expand Down Expand Up @@ -902,10 +914,12 @@ function GeoJsonMixin<T extends AbstractConstructor<BaseType>>(Base: T) {
czml.properties ?? {},
stringifyFeatureProperties(feature.properties ?? {})
);

rootCzml.push(czml);
} else if (
feature.geometry?.type === "Polygon" ||
(feature.geometry?.type === "MultiPolygon" && czmlTemplate?.polygon)
(feature.geometry?.type === "Polygon" ||
feature.geometry?.type === "MultiPolygon") &&
czmlTemplate?.polygon
) {
const czml = clone(czmlTemplate ?? {}, true);

Expand Down Expand Up @@ -948,6 +962,59 @@ function GeoJsonMixin<T extends AbstractConstructor<BaseType>>(Base: T) {
czml.polygon.positions = { cartographicDegrees: positions };
czml.polygon.holes = { cartographicDegrees: holes };

czml.properties = Object.assign(
czml.properties ?? {},
stringifyFeatureProperties(feature.properties ?? {})
);
rootCzml.push(czml);
}
} else if (
(feature?.geometry?.type === "LineString" ||
feature.geometry?.type === "MultiLineString") &&
(czmlTemplate?.polyline ||
czmlTemplate?.polylineVolume ||
czmlTemplate?.wall ||
czmlTemplate?.corridor)
) {
const czml = clone(czmlTemplate ?? {}, true);

// To handle both Polygon and MultiPolygon - transform Polygon coords into MultiPolygon coords
const multiLineString =
feature.geometry?.type === "LineString"
? [(feature.geometry as LineString).coordinates]
: (feature.geometry as MultiLineString).coordinates;

// Loop through Polygons in MultiPolygon
for (let j = 0; j < multiLineString.length; j++) {
const geom = multiLineString[j];
const positions: number[] = [];

geom.forEach((coords) => {
if (isJsonNumber(this.czmlTemplate?.heightOffset)) {
coords[2] = (coords[2] ?? 0) + this.czmlTemplate!.heightOffset;
}
positions.push(coords[0], coords[1], coords[2]);
});

// Add positions to all CZML line like features
if (czml.polyline) {
czml.polyline.positions = { cartographicDegrees: positions };
}

if (czml.polylineVolume) {
czml.polylineVolume.positions = {
cartographicDegrees: positions
};
}

if (czml.wall) {
czml.wall.positions = { cartographicDegrees: positions };
}

if (czml.corridor) {
czml.corridor.positions = { cartographicDegrees: positions };
}

czml.properties = Object.assign(
czml.properties ?? {},
stringifyFeatureProperties(feature.properties ?? {})
Expand Down Expand Up @@ -1382,6 +1449,22 @@ export function isGeometries(json: any): json is Geometries {
);
}

/**
* Returns the points in a MultiPoint as separate Point features.
*/
function explodeMultiPoint(feature: Feature): Feature[] {
return feature.geometry?.type === "MultiPoint"
? feature.geometry.coordinates.map((coordinates) => ({
type: "Feature",
geometry: {
type: "Point",
coordinates
} as Point,
properties: feature.properties
}))
: [];
}

export function toFeatureCollection(
json: any
): FeatureCollectionWithCrs | undefined {
Expand Down Expand Up @@ -1448,7 +1531,7 @@ function createPolylineFromPolygon(
createEntitiesFromHoles(entities, hierarchy.holes, entity);
}

async function reprojectToGeographic(
export async function reprojectToGeographic(
geoJson: FeatureCollectionWithCrs,
proj4ServiceBaseUrl?: string
): Promise<FeatureCollectionWithCrs> {
Expand Down
Loading

0 comments on commit c4d9682

Please sign in to comment.