Skip to content

Commit

Permalink
added(display): By using [textAnchor](https://heremaps.github.io/xyz-…
Browse files Browse the repository at this point in the history
…maps/docs/interfaces/core.textstyle.html#textanchor) it is now possible to align the text relative to the anchor point.

Signed-off-by: Tim Deubler <tim.deubler@here.com>
  • Loading branch information
TerminalTim committed Oct 24, 2023
1 parent ef5c29c commit 05b67ba
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 110 deletions.
22 changes: 20 additions & 2 deletions packages/core/src/styles/TextStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,24 @@ export interface TextStyle {
*/
text?: string | number | boolean | StyleValueFunction<string | number | boolean> | StyleZoomRange<string | number | boolean>;

/**
* The "textAnchor" attribute is used to align the text relative to the {@link anchor} point.
*
* Possible values:
* - "Left": The text is aligned left to the anchor.
* - "Right": The text is aligned right to the anchor.
* - "Center": The center of the Text is placed at the {@link anchor} point.
* - "Top": The top of the Text is placed closest the {@link anchor} point.
* - "TopLeft": The top left side of the Text is placed closest the {@link anchor} point.
* - "TopRight": The top right side of the Text is placed closest the {@link anchor} point.
* - "Bottom": The bottom of the Text is placed closest to the {@link anchor} point.
* - "BottomLeft": The bottom left side of the Text is placed closest the {@link anchor} point.
* - "BottomRight": The bottom right side of the Text is placed closest the {@link anchor} point.
*
* @defaultValue "Center"
*/
textAnchor?: 'Left' | 'Center' | 'Right' | 'Top' | 'TopLeft' | 'TopRight' | 'Bottom' | 'BottomLeft' | 'BottomRight'

/**
* "textRef" Reference to an attribute of an feature that's value should be displayed as text.
* If both "text" and "textRef" are set, "text" prevails.
Expand All @@ -121,7 +139,7 @@ export interface TextStyle {
* ```
* @example
* ```typescript
* // display the id of the featurre
* // display the id of the feature
* ...
* textRef: "id"
* ```
Expand Down Expand Up @@ -221,7 +239,7 @@ export interface TextStyle {
*
* @defaultValue For Polygon geometry the default is "Center". For Line geometry the default for styles of type "Text" is "Line".
*/
anchor?: 'Line' | 'Coordinate' | 'Centroid'
anchor?: 'Line' | 'Coordinate' | 'Centroid' | 'Center'

/**
* Enable or disable the space check for point styles on line geometries.
Expand Down
201 changes: 100 additions & 101 deletions packages/display/src/displays/webgl/buffer/FeatureFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ import {PointBuffer} from './templates/PointBuffer';
import {PolygonBuffer} from './templates/PolygonBuffer';
import {ExtrudeBuffer} from './templates/ExtrudeBuffer';
import {toPresentationFormB} from '../arabic';
import {
Tile,
Feature,
GeoJSONCoordinate
} from '@here/xyz-maps-core';
import {Tile, Feature, GeoJSONCoordinate, TextStyle} from '@here/xyz-maps-core';
import {TemplateBuffer} from './templates/TemplateBuffer';
import {addVerticalLine} from './addVerticalLine';
import {BoxBuffer} from './templates/BoxBuffer';
Expand Down Expand Up @@ -178,7 +174,8 @@ export class FeatureFactory {
rotationZ: number = 0,
rotationY: number | undefined,
text?: string,
defaultLineWrap?: number | boolean
defaultLineWrap?: number | boolean,
textAnchor?: TextStyle['textAnchor']
) {
const isFlat = z === null;
const level = this.z;
Expand All @@ -205,11 +202,8 @@ export class FeatureFactory {
texture.addChars(text);

const fontInfo = texture.getAtlas();
let lineWrap = getValue('lineWrap', style, feature, level);
let lineWrap = getValue('lineWrap', style, feature, level) ?? defaultLineWrap;

if (lineWrap == UNDEF) {
lineWrap = defaultLineWrap;
}
const lines = wrapText(text, lineWrap);

positionBuffer = flexAttributes.a_position;
Expand All @@ -226,7 +220,8 @@ export class FeatureFactory {
flexAttributes.a_texcoord.data,
fontInfo,
rotationZ,
rotationY
rotationY,
textAnchor
);
} else {
if (type == 'Model') {
Expand Down Expand Up @@ -291,13 +286,13 @@ export class FeatureFactory {
x,
y,
z,
<ImageInfo>img,
width,
height,
flexAttributes.a_size.data,
positionBuffer.data,
flexAttributes.a_texcoord.data,
rotationZ
<ImageInfo>img,
width,
height,
flexAttributes.a_size.data,
positionBuffer.data,
flexAttributes.a_texcoord.data,
rotationZ
);
groupBuffer.addUniform('u_texture', this.icons.getTexture());
// group.texture = this.icons.getTexture();
Expand Down Expand Up @@ -400,7 +395,7 @@ export class FeatureFactory {
let alignment;
let sizeUnit;
let offsetUnit;
let collisionGroups: {[key:string]: CollisionGroup} = {};
let collisionGroups: { [key: string]: CollisionGroup } = {};
let collisionData;

this.lineFactory.initFeature(level, tileSize, collisionGroup?.id);
Expand All @@ -421,10 +416,9 @@ export class FeatureFactory {

if (opacity === 0) continue;

let collide =
geomType == 'Polygon'
? true // no collision detection support for polygons
: getValue('collide', style, feature, level);
let collide = geomType == 'Polygon'
? true // no collision detection support for polygons
: getValue('collide', style, feature, level);

if (priority == UNDEF && ((type == 'Text' && !collide) || collide === false)) {
let collisionGroupId = getValue('collisionGroup', style, feature, level) || DEFAULT_COLLISION_GRP;
Expand Down Expand Up @@ -463,7 +457,7 @@ export class FeatureFactory {

if (
opacity == UNDEF ||
opacity >= 0.98 // no alpha visible -> no need to use more expensive alpha pass
opacity >= 0.98 // no alpha visible -> no need to use more expensive alpha pass
) {
opacity = 1;
}
Expand Down Expand Up @@ -544,13 +538,13 @@ export class FeatureFactory {
[offsetX, offsetUnit] = parseSizeValue(offset);

groupId =
(altitude ? 'AL' : 'L') +
sizeUnit +
offsetX +
offsetUnit +
strokeLinecap +
strokeLinejoin +
(strokeDasharray || NONE);
(altitude ? 'AL' : 'L') +
sizeUnit +
offsetX +
offsetUnit +
strokeLinecap +
strokeLinejoin +
(strokeDasharray || NONE);
} else {
fill = getValue('fill', style, feature, level);

Expand Down Expand Up @@ -801,34 +795,36 @@ export class FeatureFactory {
collisionGroup = null;
}

this.createPoint(type, group, x, y, z, style, feature, collisionData, rotation, UNDEF, text);
this.createPoint(type, group, x, y, z, style, feature, collisionData, rotation, UNDEF, text, UNDEF,
type == 'Text' && getValue('textAnchor', style, feature, level)
);
}
} else if (geomType == 'LineString') {
if (type == 'Line') {
let vertexLength = this.lineFactory.createLine(
<GeoJSONCoordinate[]>coordinates,
group,
tile,
tileSize,
removeTileBounds,
strokeDasharray,
strokeLinecap,
strokeLinejoin,
strokeWidth,
altitude,
offsetX,
getValue('from', style, feature, level),
getValue('to', style, feature, level)
<GeoJSONCoordinate[]>coordinates,
group,
tile,
tileSize,
removeTileBounds,
strokeDasharray,
strokeLinecap,
strokeLinejoin,
strokeWidth,
altitude,
offsetX,
getValue('from', style, feature, level),
getValue('to', style, feature, level)
);

group.buffer.setIdOffset(feature.id);
} else {
let isText = type == 'Text';
let anchor = getValue('anchor', style, feature, level);
if (anchor == UNDEF) {
anchor = type == 'Text' ? 'Line' : 'Coordinate';
}
anchor ??= isText ? 'Line' : 'Coordinate';

const checkCollisions = type == 'Text' ? !collide : collide === false;
const textAnchor = isText && getValue('textAnchor', style, feature, level);
const checkCollisions = isText ? !collide : collide === false;

let w;
let h;
Expand Down Expand Up @@ -876,36 +872,37 @@ export class FeatureFactory {
}

this.lineFactory.placeAtSegments(
<GeoJSONCoordinate[]>coordinates,
altitude,
tile,
tileSize,
checkCollisions && this.collisions,
priority,
getValue('repeat', style, feature, level),
offsetX,
offsetY,
w,
h,
applyRotation,
checkLineSpace,
from, to,
(x, y, z, rotationZ, rotationY, collisionData) => {
this.createPoint(
type,
group,
x,
y,
z,
style,
feature,
collisionData,
rotationZ + rotation,
rotationY,
text,
false
);
}
<GeoJSONCoordinate[]>coordinates,
altitude,
tile,
tileSize,
checkCollisions && this.collisions,
priority,
getValue('repeat', style, feature, level),
offsetX,
offsetY,
w,
h,
applyRotation,
checkLineSpace,
from, to,
(x, y, z, rotationZ, rotationY, collisionData) => {
this.createPoint(
type,
group,
x,
y,
z,
style,
feature,
collisionData,
rotationZ + rotation,
rotationY,
text,
false,
textAnchor
);
}
);
} else {
if (collisionGroup) {
Expand All @@ -917,21 +914,21 @@ export class FeatureFactory {
}

this.lineFactory.placeAtPoints(
<GeoJSONCoordinate[]>coordinates,
altitude,
tile,
tileSize,
checkCollisions && this.collisions,
priority,
w,
h,
offsetX,
offsetY,
from,
to,
(x, y, z, rotZ, rotY, collisionData) => {
this.createPoint(type, group, x, y, z, style, feature, collisionData, rotZ + rotation, UNDEF, text);
}
<GeoJSONCoordinate[]>coordinates,
altitude,
tile,
tileSize,
checkCollisions && this.collisions,
priority,
w,
h,
offsetX,
offsetY,
from,
to,
(x, y, z, rotZ, rotY, collisionData) => {
this.createPoint(type, group, x, y, z, style, feature, collisionData, rotZ + rotation, UNDEF, text, UNDEF, textAnchor);
}
);
}
}
Expand Down Expand Up @@ -960,12 +957,12 @@ export class FeatureFactory {
aPosition,
(group.buffer as ExtrudeBuffer).flexAttributes.a_normal.data,
vIndex,
<GeoJSONCoordinate[][]>coordinates,
tile,
tileSize,
extrude,
extrudeBase,
strokeIndex
<GeoJSONCoordinate[][]>coordinates,
tile,
tileSize,
extrude,
extrudeBase,
strokeIndex
);
} else if (type == 'Polygon') {
flatPoly = addPolygon(aPosition, <GeoJSONCoordinate[][]>coordinates, tile, tileSize);
Expand Down Expand Up @@ -1025,8 +1022,10 @@ export class FeatureFactory {
collisionGrp.height = halfHeight;

this.pendingCollisions.push(collisionGrp);
};
}
;
}

destroy() {
this.modelFactory.destroy();
}
Expand Down
Loading

0 comments on commit 05b67ba

Please sign in to comment.