Skip to content

Commit

Permalink
Revert "Add projection expression syntax (#888)"
Browse files Browse the repository at this point in the history
This reverts commit 107bd0e.
  • Loading branch information
birkskyum authored Nov 13, 2024
1 parent 107bd0e commit 87e304f
Show file tree
Hide file tree
Showing 32 changed files with 106 additions and 575 deletions.
3 changes: 1 addition & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
## main

### ✨ Features and improvements
- Add projection type expression syntax ([#888](https://github.com/maplibre/maplibre-style-spec/pull/888))
- _...Add new stuff here..._

### 🐞 Bug fixes
Expand All @@ -10,7 +9,7 @@
## 21.2.0

### ✨ Features and improvements
- Add `vertical-perspective` projection ([#890](https://github.com/maplibre/maplibre-style-spec/pull/890))
Add `vertical-perspective` projection ([#890](https://github.com/maplibre/maplibre-style-spec/pull/890))

## 21.1.0

Expand Down
3 changes: 0 additions & 3 deletions build/generate-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ function typeToMarkdownLink(type: string): string {
case 'promoteid':
return ` [${type}](types.md)`;
case 'color':
case 'projection':
case 'number':
case 'string':
case 'boolean':
Expand All @@ -181,8 +180,6 @@ function typeToMarkdownLink(type: string): string {
case 'paint':
case 'layout':
return ` [${type}](layers.md#${type.toLocaleLowerCase()})`;
case 'projectionconfig':
return ' [projectionConfig](projection.md)';
default:
// top level types have their own file
return ` [${type}](${type}.md)`;
Expand Down
11 changes: 2 additions & 9 deletions build/generate-style-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ function propertyType(property) {
return 'SkySpecification';
case 'sources':
return '{[_: string]: SourceSpecification}';
case 'projection:':
return 'ProjectionSpecification';
case '*':
return 'unknown';
default:
Expand Down Expand Up @@ -124,9 +122,6 @@ fs.writeFileSync('src/types.g.ts',
export type ColorSpecification = string;
export type ProjectionT = [string, string, number];
export type ProjectionSpecification = string | ProjectionT | PropertyValueSpecification<ProjectionT>
export type PaddingSpecification = number | number[];
export type VariableAnchorOffsetCollectionSpecification = Array<string | [number, number]>;
Expand Down Expand Up @@ -208,8 +203,6 @@ export type ExpressionSpecification =
// Ramps, scales, curves
| ['interpolate', InterpolationSpecification, number | ExpressionSpecification,
...(number | number[] | ColorSpecification | ExpressionSpecification)[]] // alternating number and number | number[] | ColorSpecification
| ['interpolate-projection', InterpolationSpecification, number | ExpressionSpecification,
...(number | string)[]] // alternating Projection
| ['interpolate-hcl', InterpolationSpecification, number | ExpressionSpecification,
...(number | ColorSpecification)[]] // alternating number and ColorSpecificaton
| ['interpolate-lab', InterpolationSpecification, number | ExpressionSpecification,
Expand Down Expand Up @@ -324,10 +317,10 @@ ${objectDeclaration('LightSpecification', spec.light)}
${objectDeclaration('SkySpecification', spec.sky)}
${objectDeclaration('ProjectionConfigSpecification', spec.projectionConfig)}
${objectDeclaration('TerrainSpecification', spec.terrain)}
${objectDeclaration('ProjectionSpecification', spec.projection)}
${spec.source.map(key => {
let str = objectDeclaration(sourceTypeName(key), spec[key]);
if (sourceTypeName(key) === 'GeoJSONSourceSpecification') {
Expand Down
73 changes: 0 additions & 73 deletions docs/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,76 +133,3 @@ The following example applies 2em padding on top and bottom and 3em padding left
"icon-padding": [2, 3]
}
```

## Projection

The `projection` is used to configure which projection to use for the map.

There are currently two projections implemented.

- `mercator` - [Web Mercator projection](https://en.wikipedia.org/wiki/Web_Mercator_projection)
- `vertical-perspective` - [Vertical Perspective projection](https://en.wikipedia.org/wiki/General_Perspective_projection)

And the following [presets](#use-a-projection-preset)

The `projection` output sent to the renderer is always of the shape:

`[from, to, transition]: [string, string, number]`

- `from` is the projection of lower zoom level
- `to` is the projection of higher zoom level
- `transition` is the interpolation value, going from 0 to 1, with 0 being in the `from` projection, and 1 being in the `to` projection.

In case `from` and `to` are equal, the `transition` will have no effect.

### Examples

#### Step between projection at discrete zoom levels

Use a [`camera expression`](./expressions.md#camera-expressions), to discretely [`step`](./expressions.md#step) between projections at certain zoom levels.


```ts
type: ["step", ["zoom"],
"vertical-perspective",
11, "mercator"
]


output at zoom 10.9: "vertical-perspective"
output at zoom 11.0: "vertical-perspective"
output at zoom 11.1: "mercator"
```

#### Animate between different projections based on zoom level**

Use a [`camera expression`](./expressions.md#camera-expressions), to animate between projections based on zoom, using [`interpolate-projection`](./expressions.md#interpolate-projection) function. The example below will yield an adaptive globe that interpolates from `vertical-perspective` to `mercator` between zoom 10 and 12.

```ts
type: ["interpolate-projection", ["linear"], ["zoom"],
10,"vertical-perspective",
12,"mercator"
]


output at zoom 9.9: "vertical-perspective"
output at zoom 11: ["vertical-perspective", "mercator", 0.5]
output at zoom 12: ["vertical-perspective", "mercator", 1]
output at zoom 12.1: "mercator"
```


#### Provide a `projection`

```ts
type: ["vertical-perspective", "mercator", 0.7]
```

#### Use a projection preset

There are also additional presets that yield commonly used expressions:


| Preset | Full value | Description |
|--------|------------|-------------|
| `globe` | `["interpolate-projection", ["linear"], ["zoom"],`<br>`10, "vertical-perspective", 12, "mercator"]` | Adaptive globe: interpolates from vertical-perspective to mercator projection between zoom levels 10 and 12. |
7 changes: 4 additions & 3 deletions src/diff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -606,10 +606,11 @@ describe('diff', () => {
expect(diffStyles({
} as StyleSpecification,
{
projection: {type: ['vertical-perspective', 'mercator', 0.5]}

projection: {
type: 'globe'
}
} as StyleSpecification)).toEqual([
{command: 'setProjection', args: [{type: ['vertical-perspective', 'mercator', 0.5]}]},
{command: 'setProjection', args: [{type: 'globe'}]},
]);
});
});
4 changes: 2 additions & 2 deletions src/diff.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import {GeoJSONSourceSpecification, LayerSpecification, LightSpecification, ProjectionConfigSpecification, SkySpecification, SourceSpecification, SpriteSpecification, StyleSpecification, TerrainSpecification, TransitionSpecification} from './types.g';
import {GeoJSONSourceSpecification, LayerSpecification, LightSpecification, ProjectionSpecification, SkySpecification, SourceSpecification, SpriteSpecification, StyleSpecification, TerrainSpecification, TransitionSpecification} from './types.g';
import isEqual from './util/deep_equal';

/**
Expand Down Expand Up @@ -30,7 +30,7 @@ export type DiffOperationsMap = {
'setLight': [LightSpecification];
'setTerrain': [TerrainSpecification];
'setSky': [SkySpecification];
'setProjection': [ProjectionConfigSpecification];
'setProjection': [ProjectionSpecification];
}

export type DiffOperations = keyof DiffOperationsMap;
Expand Down
1 change: 0 additions & 1 deletion src/expression/definitions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ export const expressions: ExpressionRegistry = {
'interpolate': Interpolate,
'interpolate-hcl': Interpolate,
'interpolate-lab': Interpolate,
'interpolate-projection': Interpolate,
'length': Length,
'let': Let,
'literal': Literal,
Expand Down
31 changes: 7 additions & 24 deletions src/expression/definitions/interpolate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import UnitBezier from '@mapbox/unitbezier';

import interpolate from '../../util/interpolate';
import {array, ArrayType, ColorType, ProjectionTypeT, ColorTypeT, NumberType, NumberTypeT, PaddingType, PaddingTypeT, VariableAnchorOffsetCollectionType, VariableAnchorOffsetCollectionTypeT, toString, verifyType, ProjectionType} from '../types';
import {array, ArrayType, ColorType, ColorTypeT, NumberType, NumberTypeT, PaddingType, PaddingTypeT, VariableAnchorOffsetCollectionType, VariableAnchorOffsetCollectionTypeT, toString, verifyType} from '../types';
import {findStopLessThanOrEqualTo} from '../stops';

import type {Stops} from '../stops';
Expand All @@ -19,18 +19,18 @@ export type InterpolationType = {
name: 'cubic-bezier';
controlPoints: [number, number, number, number];
};
type InterpolatedValueType = NumberTypeT | ColorTypeT | ProjectionTypeT | PaddingTypeT | VariableAnchorOffsetCollectionTypeT | ArrayType<NumberTypeT>;
type InterpolationOperator = 'interpolate' | 'interpolate-hcl' | 'interpolate-lab' | 'interpolate-projection';
type InterpolatedValueType = NumberTypeT | ColorTypeT | PaddingTypeT | VariableAnchorOffsetCollectionTypeT | ArrayType<NumberTypeT>;

class Interpolate implements Expression {
type: InterpolatedValueType;

operator: InterpolationOperator ;
operator: 'interpolate' | 'interpolate-hcl' | 'interpolate-lab';
interpolation: InterpolationType;
input: Expression;
labels: Array<number>;
outputs: Array<Expression>;

constructor(type: InterpolatedValueType, operator: InterpolationOperator, interpolation: InterpolationType, input: Expression, stops: Stops) {
constructor(type: InterpolatedValueType, operator: 'interpolate' | 'interpolate-hcl' | 'interpolate-lab', interpolation: InterpolationType, input: Expression, stops: Stops) {
this.type = type;
this.operator = operator;
this.interpolation = interpolation;
Expand Down Expand Up @@ -108,8 +108,6 @@ class Interpolate implements Expression {
let outputType: Type = null;
if (operator === 'interpolate-hcl' || operator === 'interpolate-lab') {
outputType = ColorType;
} else if (operator === 'interpolate-projection') {
outputType = ProjectionType;
} else if (context.expectedType && context.expectedType.kind !== 'value') {
outputType = context.expectedType;
}
Expand Down Expand Up @@ -137,7 +135,6 @@ class Interpolate implements Expression {

if (!verifyType(outputType, NumberType) &&
!verifyType(outputType, ColorType) &&
!verifyType(outputType, ProjectionType) &&
!verifyType(outputType, PaddingType) &&
!verifyType(outputType, VariableAnchorOffsetCollectionType) &&
!verifyType(outputType, array(NumberType))
Expand Down Expand Up @@ -173,28 +170,14 @@ class Interpolate implements Expression {

const outputLower = outputs[index].evaluate(ctx);
const outputUpper = outputs[index + 1].evaluate(ctx);

switch (this.operator) {
case 'interpolate':
switch (this.type.kind) {
case 'number':
return interpolate.number(outputLower, outputUpper, t);
case 'color':
return interpolate.color(outputLower, outputUpper, t, 'rgb');
case 'array':
return interpolate.array(outputLower, outputUpper, t);
case 'padding':
return interpolate.padding(outputLower, outputUpper, t);
case 'variableAnchorOffsetCollection':
return interpolate.variableAnchorOffsetCollection(outputLower, outputUpper, t);
}
return interpolate[this.type.kind](outputLower, outputUpper, t);
case 'interpolate-hcl':
return interpolate.color(outputLower, outputUpper, t, 'hcl');
case 'interpolate-lab':
return interpolate.color(outputLower, outputUpper, t, 'lab');
case 'interpolate-projection': {
return interpolate.projection(outputLower, outputUpper, t);
}
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/expression/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ function findZoomCurve(expression: Expression): Step | Interpolate | ExpressionP
return result;
}

import {ColorType, StringType, NumberType, BooleanType, ValueType, FormattedType, PaddingType, ResolvedImageType, VariableAnchorOffsetCollectionType, array, ProjectionType} from './types';
import {ColorType, StringType, NumberType, BooleanType, ValueType, FormattedType, PaddingType, ResolvedImageType, VariableAnchorOffsetCollectionType, array} from './types';
import Padding from '../util/padding';
import {ICanonicalTileID} from '../tiles_and_coordinates';

Expand All @@ -453,7 +453,6 @@ function getExpectedType(spec: StylePropertySpecification): Type {
boolean: BooleanType,
formatted: FormattedType,
padding: PaddingType,
projection: ProjectionType,
resolvedImage: ResolvedImageType,
variableAnchorOffsetCollection: VariableAnchorOffsetCollectionType
};
Expand Down
2 changes: 0 additions & 2 deletions src/expression/parsing_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ class ParsingContext {
//
if ((expected.kind === 'string' || expected.kind === 'number' || expected.kind === 'boolean' || expected.kind === 'object' || expected.kind === 'array') && actual.kind === 'value') {
parsed = annotate(parsed, expected, options.typeAnnotation || 'assert');
} else if ((expected.kind === 'projection') && (actual.kind === 'string')) {
parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');
} else if ((expected.kind === 'color' || expected.kind === 'formatted' || expected.kind === 'resolvedImage') && (actual.kind === 'value' || actual.kind === 'string')) {
parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');
} else if (expected.kind === 'padding' && (actual.kind === 'value' || actual.kind === 'number' || actual.kind === 'array')) {
Expand Down
7 changes: 1 addition & 6 deletions src/expression/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ export type BooleanTypeT = {
export type ColorTypeT = {
kind: 'color';
};
export type ProjectionTypeT = {
kind: 'projection';
};
export type ObjectTypeT = {
kind: 'object';
};
Expand Down Expand Up @@ -43,7 +40,7 @@ export type VariableAnchorOffsetCollectionTypeT = {

export type EvaluationKind = 'constant' | 'source' | 'camera' | 'composite';

export type Type = NullTypeT | NumberTypeT | StringTypeT | BooleanTypeT | ColorTypeT | ProjectionTypeT | ObjectTypeT | ValueTypeT |
export type Type = NullTypeT | NumberTypeT | StringTypeT | BooleanTypeT | ColorTypeT | ObjectTypeT | ValueTypeT |
ArrayType | ErrorTypeT | CollatorTypeT | FormattedTypeT | PaddingTypeT | ResolvedImageTypeT | VariableAnchorOffsetCollectionTypeT;

export interface ArrayType<T extends Type = Type> {
Expand All @@ -59,7 +56,6 @@ export const NumberType = {kind: 'number'} as NumberTypeT;
export const StringType = {kind: 'string'} as StringTypeT;
export const BooleanType = {kind: 'boolean'} as BooleanTypeT;
export const ColorType = {kind: 'color'} as ColorTypeT;
export const ProjectionType = {kind: 'projection'} as ProjectionTypeT;
export const ObjectType = {kind: 'object'} as ObjectTypeT;
export const ValueType = {kind: 'value'} as ValueTypeT;
export const ErrorType = {kind: 'error'} as ErrorTypeT;
Expand Down Expand Up @@ -94,7 +90,6 @@ const valueMemberTypes = [
StringType,
BooleanType,
ColorType,
ProjectionType,
FormattedType,
ObjectType,
array(ValueType),
Expand Down
12 changes: 4 additions & 8 deletions src/expression/values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import Formatted from './types/formatted';
import Padding from '../util/padding';
import VariableAnchorOffsetCollection from '../util/variable_anchor_offset_collection';
import ResolvedImage from './types/resolved_image';
import {NullType, NumberType, StringType, BooleanType, ColorType, ObjectType, ValueType, CollatorType, FormattedType, ResolvedImageType, array, PaddingType, VariableAnchorOffsetCollectionType, ProjectionType} from './types';
import {NullType, NumberType, StringType, BooleanType, ColorType, ObjectType, ValueType, CollatorType, FormattedType, ResolvedImageType, array, PaddingType, VariableAnchorOffsetCollectionType} from './types';

import type {Type} from './types';
import Projection from '../util/projection';

export function validateRGBA(r: unknown, g: unknown, b: unknown, a?: unknown): string | null {
if (!(
Expand All @@ -29,7 +28,7 @@ export function validateRGBA(r: unknown, g: unknown, b: unknown, a?: unknown): s
return null;
}

export type Value = null | string | boolean | number | Color | Projection | Collator | Formatted | Padding | ResolvedImage | VariableAnchorOffsetCollection | ReadonlyArray<Value> | {
export type Value = null | string | boolean | number | Color | Collator | Formatted | Padding | ResolvedImage | VariableAnchorOffsetCollection | ReadonlyArray<Value> | {
readonly [x: string]: Value;
};

Expand All @@ -38,7 +37,6 @@ export function isValue(mixed: unknown): boolean {
typeof mixed === 'string' ||
typeof mixed === 'boolean' ||
typeof mixed === 'number' ||
mixed instanceof Projection ||
mixed instanceof Color ||
mixed instanceof Collator ||
mixed instanceof Formatted ||
Expand Down Expand Up @@ -76,8 +74,6 @@ export function typeOf(value: Value): Type {
return NumberType;
} else if (value instanceof Color) {
return ColorType;
} else if (value instanceof Projection) {
return ProjectionType;
} else if (value instanceof Collator) {
return CollatorType;
} else if (value instanceof Formatted) {
Expand Down Expand Up @@ -116,11 +112,11 @@ export function toString(value: Value) {
return '';
} else if (type === 'string' || type === 'number' || type === 'boolean') {
return String(value);
} else if (value instanceof Color || value instanceof Projection || value instanceof Formatted || value instanceof Padding || value instanceof VariableAnchorOffsetCollection || value instanceof ResolvedImage) {
} else if (value instanceof Color || value instanceof Formatted || value instanceof Padding || value instanceof VariableAnchorOffsetCollection || value instanceof ResolvedImage) {
return value.toString();
} else {
return JSON.stringify(value);
}
}

export {Color, Collator, Projection, Padding, VariableAnchorOffsetCollection};
export {Color, Collator, Padding, VariableAnchorOffsetCollection};
3 changes: 1 addition & 2 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ function validSchema(k, v, obj, ref, version, kind) {
'promoteId',
'padding',
'variableAnchorOffsetCollection',
'sprite',
'projection'
'sprite'
]);
const keys = [
'default',
Expand Down
Loading

0 comments on commit 87e304f

Please sign in to comment.