@maptrip/map-tiles 1.3.3 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,11 @@
1
1
  export declare class MapReleaseFetcher {
2
2
  private _token;
3
3
  private _tomtom;
4
+ private _orbis;
4
5
  private _osm;
5
6
  private _here;
6
7
  constructor(token: string);
7
8
  getRelease(provider: string): Promise<string | null | undefined>;
8
- fetchAndExtractRelease(url: string): Promise<string | null>;
9
+ fetchAndExtractRelease(provider: string, url: string): Promise<string | null>;
9
10
  private extractTargetString;
10
11
  }
@@ -119,10 +119,12 @@ class MapTripLeafletGridLayer extends L.GridLayer {
119
119
  const eventProvider = event.layer.options.provider;
120
120
  let newProvider: string;
121
121
  if (eventProvider) {
122
- if (eventProvider.toLowerCase() === "opensreetmap") {
122
+ if (eventProvider.toLowerCase() === "openstreetmap") {
123
123
  newProvider = "openstreetmap";
124
124
  } else if (eventProvider.toLowerCase() === "tomtom") {
125
125
  newProvider = "tomtom";
126
+ } else if (eventProvider.toLowerCase() === "orbis") {
127
+ newProvider = "orbis";
126
128
  } else if (eventProvider.toLowerCase() === "here") {
127
129
  newProvider = "here";
128
130
  } else {
@@ -6,6 +6,8 @@ import {
6
6
  URL_TEMPLATE,
7
7
  PROVIDER_PROJECTS,
8
8
  PROVIDER_TRAFFIC,
9
+ VECTOR_TILE_SIZE,
10
+ VECTOR_TILE_RENDER_PADDING
9
11
  } from "./constants.js";
10
12
 
11
13
  import WebFont from "webfontloader";
@@ -163,6 +165,49 @@ class VectorTileFactory {
163
165
  }
164
166
  }
165
167
 
168
+ private createCanvas(size: number, padding: number): HTMLCanvasElement {
169
+ let canvas = document.createElement("canvas");
170
+
171
+ const paddedTileSize = size + 2 * padding;
172
+
173
+ canvas.width = paddedTileSize;
174
+ canvas.height = paddedTileSize;
175
+ canvas.style.width = paddedTileSize + 'px';
176
+ canvas.style.height = paddedTileSize + 'px';
177
+ canvas.style.maxWidth = paddedTileSize + 'px';
178
+ canvas.style.maxHeight = paddedTileSize + 'px';
179
+ canvas.style.left = -padding + 'px';
180
+ canvas.style.top = -padding + 'px';
181
+
182
+ const context = canvas.getContext('2d');
183
+ if (!context) {
184
+ throw new Error("Failed to create canvas");
185
+ }
186
+
187
+ if (typeof context.setTransform === 'function') {
188
+ context.setTransform(1, 0, 0, 1, padding, padding);
189
+ }
190
+ else {
191
+ context.translate(padding, padding);
192
+ }
193
+
194
+ return canvas;
195
+ }
196
+
197
+ private cropCanvas(source: HTMLCanvasElement, target: HTMLCanvasElement): void {
198
+ const ctx = target.getContext("2d");
199
+
200
+ if (ctx) {
201
+ ctx.drawImage(
202
+ source,
203
+ VECTOR_TILE_RENDER_PADDING, VECTOR_TILE_RENDER_PADDING, // position in source
204
+ VECTOR_TILE_SIZE, VECTOR_TILE_SIZE, // size in source
205
+ 0, 0, // position in target
206
+ VECTOR_TILE_SIZE, VECTOR_TILE_SIZE // size in target
207
+ );
208
+ }
209
+ }
210
+
166
211
  public getJsonTile(
167
212
  z: number,
168
213
  x: number,
@@ -174,9 +219,8 @@ class VectorTileFactory {
174
219
  x = (x + 16 * maximumIndex) % maximumIndex;
175
220
  y = (y + 16 * maximumIndex) % maximumIndex;
176
221
 
177
- let canvas = document.createElement("canvas");
178
- canvas.width = 256;
179
- canvas.height = 256;
222
+ let resultCanvas = this.createCanvas(VECTOR_TILE_SIZE, 0);
223
+ let tempCanvas = this.createCanvas(VECTOR_TILE_SIZE, VECTOR_TILE_RENDER_PADDING);
180
224
 
181
225
  let baseMapUrl = this.resolveTileUrl(z, x, y);
182
226
  let urls = baseMapUrl ? [baseMapUrl] : [];
@@ -192,15 +236,16 @@ class VectorTileFactory {
192
236
  });
193
237
 
194
238
  let tileLoadedSuccessfullyCallback = (json: GeoJSON.Feature) => {
195
- this.drawTile(json, z, x, y, canvas);
239
+ this.drawTile(json, z, x, y, tempCanvas);
240
+ this.cropCanvas(tempCanvas, resultCanvas);
196
241
 
197
242
  if (callback) {
198
- callback(canvas);
243
+ callback(resultCanvas);
199
244
  }
200
245
  };
201
246
 
202
247
  let tile_FailedCallback = () => {
203
- this.drawErroredTile(canvas);
248
+ this.drawErroredTile(resultCanvas);
204
249
 
205
250
  if (callback) {
206
251
  callback(null);
@@ -217,7 +262,7 @@ class VectorTileFactory {
217
262
  this._tileLoader.loadNext();
218
263
  }
219
264
 
220
- return canvas;
265
+ return resultCanvas;
221
266
  }
222
267
 
223
268
  /**
@@ -6,7 +6,9 @@ import {
6
6
  MultiPolygon,
7
7
  GeoJsonProperties,
8
8
  } from "geojson";
9
+
9
10
  import { CollisionDetector } from "./CollisionDetector.js";
11
+
10
12
  import {
11
13
  Boundaries,
12
14
  ImageStyle,
@@ -19,7 +21,11 @@ import {
19
21
  Vertex,
20
22
  } from "../types/interfaces.js";
21
23
 
22
- import { RENDERING_CONFIG} from "../types/interfaces.js"
24
+ import {
25
+ VECTOR_TILE_SIZE
26
+ } from "./constants.js"
27
+
28
+ import { RENDERING_CONFIG } from "../types/interfaces.js"
23
29
 
24
30
  class VectorTileRenderer {
25
31
  private _styles: RENDERING_CONFIG;
@@ -38,7 +44,7 @@ class VectorTileRenderer {
38
44
  context: CanvasRenderingContext2D
39
45
  ): void {
40
46
  context.fillStyle = this.getBackgroundColor(z);
41
- context.fillRect(0, 0, 256, 256);
47
+ context.fillRect(0, 0, VECTOR_TILE_SIZE, VECTOR_TILE_SIZE);
42
48
 
43
49
  var collisions = new CollisionDetector();
44
50
  let polygons = layer
@@ -73,6 +79,7 @@ class VectorTileRenderer {
73
79
  );
74
80
 
75
81
  this.drawTilePhase(polygons, z, boundaries, context, "areas", collisions);
82
+ // add phase areasOutline here if polygon outlines should be rendered
76
83
  this.drawPolylineLayers(lines, z, boundaries, context, "", collisions);
77
84
  this.drawTilePhase(points, z, boundaries, context, "texts", collisions);
78
85
  this.drawTilePhase(lines, z, boundaries, context, "lineTexts", collisions);
@@ -113,6 +120,14 @@ class VectorTileRenderer {
113
120
  "linesOutline",
114
121
  collisions
115
122
  );
123
+ }
124
+
125
+ for (let i = 0; i < rank.length; i++) {
126
+ // select all lines with this sort rank
127
+ let currentRank = lines.filter(
128
+ (it) => parseInt(it.properties!.sort_rank) === rank[i]
129
+ );
130
+
116
131
  this.drawTilePhase(
117
132
  currentRank,
118
133
  z,
@@ -123,12 +138,12 @@ class VectorTileRenderer {
123
138
  );
124
139
  }
125
140
  }
126
-
141
+
127
142
  drawErroredTile(canvas: HTMLCanvasElement): void {
128
143
  var context = canvas.getContext("2d");
129
144
  if (context != null) {
130
145
  context.fillStyle = "#C8C8C8";
131
- context.fillRect(0, 0, 256, 256);
146
+ context.fillRect(0, 0, VECTOR_TILE_SIZE, VECTOR_TILE_SIZE);
132
147
  context.fillStyle = "#AAA";
133
148
  context.font = "15px Arial";
134
149
  context.textAlign = "center";
@@ -164,7 +179,7 @@ class VectorTileRenderer {
164
179
  const rendererName = this._styles.layers[kind];
165
180
  const renderer = rendererName
166
181
  ? //@ts-ignore
167
- this._styles?.renderers[rendererName]
182
+ this._styles?.renderers[rendererName]
168
183
  : undefined;
169
184
 
170
185
  if (renderer) {
@@ -179,10 +194,7 @@ class VectorTileRenderer {
179
194
  if (geometry.type === "Polygon") {
180
195
  const polygonGeometry = geometry as Polygon;
181
196
  const coordinates = polygonGeometry.coordinates;
182
- if (
183
- (phase === "areasOutline" || phase === "areas") &&
184
- renderer[j].polygon
185
- ) {
197
+ if ((phase === "areasOutline" || phase === "areas") && renderer[j].polygon) {
186
198
  this.drawPolygon(
187
199
  coordinates,
188
200
  layer[i].properties,
@@ -192,10 +204,7 @@ class VectorTileRenderer {
192
204
  context,
193
205
  phase
194
206
  );
195
- } else if (
196
- phase === "areaTexts" &&
197
- renderer[j].text !== undefined
198
- ) {
207
+ } else if (phase === "areaTexts" && renderer[j].text !== undefined) {
199
208
  this.drawPolygon(
200
209
  coordinates,
201
210
  layer[i].properties,
@@ -211,10 +220,7 @@ class VectorTileRenderer {
211
220
  } else if (geometry.type === "MultiPolygon") {
212
221
  const multiPolygonGeometry = geometry as MultiPolygon;
213
222
  const coordinates = multiPolygonGeometry.coordinates;
214
- if (
215
- (phase === "areasOutline" || phase === "areas") &&
216
- renderer[j].polygon
217
- ) {
223
+ if ((phase === "areasOutline" || phase === "areas") && renderer[j].polygon) {
218
224
  for (let k = 0; k < coordinates.length; k++) {
219
225
  this.drawPolygon(
220
226
  coordinates[k],
@@ -244,10 +250,7 @@ class VectorTileRenderer {
244
250
  } else if (geometry.type === "LineString") {
245
251
  const lineStringGeometry = geometry as LineString;
246
252
  const coordinates = lineStringGeometry.coordinates;
247
- if (
248
- (phase === "linesOutline" || phase === "lines") &&
249
- renderer[j].line
250
- ) {
253
+ if ((phase === "linesOutline" || phase === "lines") && renderer[j].line) {
251
254
  this.drawPolyline(
252
255
  coordinates,
253
256
  layer[i].properties,
@@ -270,10 +273,7 @@ class VectorTileRenderer {
270
273
  } else if (geometry.type === "MultiLineString") {
271
274
  const multiLineStringGeometry = geometry as MultiLineString;
272
275
  const coordinates = multiLineStringGeometry.coordinates;
273
- if (
274
- (phase === "linesOutline" || phase === "lines") &&
275
- renderer[j].line
276
- ) {
276
+ if ((phase === "linesOutline" || phase === "lines") && renderer[j].line) {
277
277
  for (let k = 0; k < coordinates.length; k++) {
278
278
  this.drawPolyline(
279
279
  coordinates[k],
@@ -315,12 +315,18 @@ class VectorTileRenderer {
315
315
  collisions
316
316
  )
317
317
  ) {
318
- const match = text.match(/([A-Z])\s?([0-9]+[a-z]*).*/);
318
+ const match = text.match(/([a-zA-Z])\s?([0-9]+[a-z]*).*/);
319
319
  if (match) {
320
320
  const letter = match[1];
321
321
  const number = match[2];
322
- if (letter === "A" || letter === "B") {
323
- text = number;
322
+
323
+ // Stadsroutes are major roads in some cities in the Netherlands and start with s.
324
+ // Adding them here will render them like Bundesstraßen in Germany.
325
+ // If country-dependent rendering is added, it should be a white box with black border and text.
326
+
327
+ if (letter === "A" || letter === "B" || letter === "s") {
328
+ text = letter === "A" || letter === "B" ? number : letter + number;
329
+
324
330
  this.drawImage(
325
331
  coordinates,
326
332
  boundaries,
@@ -360,6 +366,9 @@ class VectorTileRenderer {
360
366
  }
361
367
  }
362
368
  }
369
+ else {
370
+ console.log("no renderer for kind " + kind);
371
+ }
363
372
  }
364
373
  }
365
374
 
@@ -435,17 +444,24 @@ class VectorTileRenderer {
435
444
  var part = coordinates[j];
436
445
 
437
446
  context.globalAlpha = merged.opacity;
438
- context.beginPath();
439
447
 
448
+ if ('areas' !== phase || j === 0) {
449
+ // when rendering areas, only the first part of a polygon should begin a path
450
+ // (otherwise especially islands are clipped on some zoom levels)
451
+ context.beginPath();
452
+ }
453
+
454
+ const width = boundaries.max.lon - boundaries.min.lon;
455
+ const height = boundaries.max.lat - boundaries.min.lat;
456
+ if (width === 0 || height === 0) {
457
+ return;
458
+ }
459
+
440
460
  var points: { x: number; y: number }[] = [];
441
461
 
442
462
  for (let k = 0; k < part.length; k++) {
443
- let x =
444
- (256 * (part[k][0] - boundaries.min.lon!)) /
445
- (boundaries.max.lon! - boundaries.min.lon!);
446
- let y =
447
- (256 * (part[k][1] - boundaries.min.lat!)) /
448
- (boundaries.max.lat! - boundaries.min.lat!);
463
+ let x = (VECTOR_TILE_SIZE * (part[k][0] - boundaries.min.lon!)) / width;
464
+ let y = (VECTOR_TILE_SIZE * (part[k][1] - boundaries.min.lat!)) / height;
449
465
 
450
466
  points.push({ x: x, y: y });
451
467
 
@@ -466,7 +482,7 @@ class VectorTileRenderer {
466
482
  }
467
483
 
468
484
  return;
469
- } else if ("areas" === phase) {
485
+ } else if ("areas" === phase && j === coordinates.length - 1) {
470
486
  if (merged.url) {
471
487
  if (this._images[merged.url]) {
472
488
  var pattern = context.createPattern(
@@ -486,7 +502,7 @@ class VectorTileRenderer {
486
502
  context.fillStyle = merged.color;
487
503
  }
488
504
 
489
- context.fill();
505
+ context.fill('evenodd');
490
506
  } else if ("areaTexts" === phase) {
491
507
  if (geoJsonProperties && geoJsonProperties.NAME) {
492
508
  // skip texts which already are in this tile
@@ -497,14 +513,8 @@ class VectorTileRenderer {
497
513
  let merged = { ...VectorTileRenderer.DEFAULT_STYLE.TEXT, ...style };
498
514
 
499
515
  context.globalAlpha = merged.opacity;
500
- context.font =
501
- merged.fontStyle +
502
- " " +
503
- merged.fontWeight +
504
- " " +
505
- merged.size +
506
- "px " +
507
- merged.font;
516
+ context.font = `${merged.fontStyle} ${merged.fontWeight} ${merged.size}px ${merged.font}`;
517
+
508
518
  context.textAlign = "left";
509
519
  context.textBaseline = "top";
510
520
 
@@ -518,7 +528,7 @@ class VectorTileRenderer {
518
528
  let h = merged.size!;
519
529
 
520
530
  // skip texts outside a tile
521
- if (x < 0 || x + w > 256 || y < 0 || y + h > 256) {
531
+ if (x < 0 || x + w > VECTOR_TILE_SIZE || y < 0 || y + h > VECTOR_TILE_SIZE) {
522
532
  return;
523
533
  }
524
534
 
@@ -622,15 +632,12 @@ class VectorTileRenderer {
622
632
  var lastX, lastY;
623
633
  var points = [];
624
634
 
635
+ const width = boundaries.max.lon - boundaries.min.lon;
636
+ const height = boundaries.max.lat - boundaries.min.lat;
637
+
625
638
  for (var j = 0; j < coordinates.length; j++) {
626
- var x = Math.round(
627
- (256 * (coordinates[j][0] - boundaries.min.lon!)) /
628
- (boundaries.max.lon! - boundaries.min.lon!)
629
- );
630
- var y = Math.round(
631
- (256 * (coordinates[j][1] - boundaries.min.lat!)) /
632
- (boundaries.max.lat! - boundaries.min.lat!)
633
- );
639
+ var x = Math.round((VECTOR_TILE_SIZE * (coordinates[j][0] - boundaries.min.lon!)) / width);
640
+ var y = Math.round((VECTOR_TILE_SIZE * (coordinates[j][1] - boundaries.min.lat!)) / height);
634
641
 
635
642
  if (x != lastX || y != lastY) {
636
643
  points.push({ x: x, y: y });
@@ -682,48 +689,69 @@ class VectorTileRenderer {
682
689
 
683
690
  // draw images on the line (e.g. arrows for one-way roads)
684
691
  if (merged.url && this._images[merged.url]) {
685
- var desired = 40; // XXX config
686
- var distance = Math.round(desired / 2);
692
+ const desiredDistance: number = 40;
693
+ const margin: number = Math.round(desiredDistance / 2);
694
+
695
+ let totalLength = 0;
696
+ for (let i = 0; i < points.length - 1; i++) {
697
+ totalLength += Math.hypot(
698
+ points[i + 1].x - points[i].x,
699
+ points[i + 1].y - points[i].y
700
+ );
701
+ }
702
+
703
+ let distance: number = margin;
704
+ let traveled: number = 0;
687
705
 
688
706
  for (var i = 0; i < points.length - 1; i++) {
689
707
  // calculate angle of this section of the line
690
- var dx = points[i + 1].x - points[i].x;
691
- var dy = points[i + 1].y - points[i].y;
692
- var angle = Math.atan2(dy, dx);
708
+ const dx: number = points[i + 1].x - points[i].x;
709
+ const dy: number = points[i + 1].y - points[i].y;
710
+ let angle: number = Math.atan2(dy, dx);
693
711
 
694
712
  if (merged.direction != "reverse") {
695
713
  angle = angle + Math.PI;
696
714
  }
697
715
 
698
716
  // now calculate equidistant points on the polyline
699
- var distanceToNext = Math.sqrt(dx * dx + dy * dy);
717
+ const distanceToNext: number = Math.sqrt(dx * dx + dy * dy);
700
718
  while (distance < distanceToNext) {
701
719
  // there are more points on this section of the line
702
- var f = distance / distanceToNext;
703
720
 
704
- var x = points[i].x + f * dx;
705
- var y = points[i].y + f * dy;
721
+ if (traveled + distance <= totalLength - margin) {
706
722
 
707
- context.save();
723
+ const f: number = distance / distanceToNext;
708
724
 
709
- context.translate(x, y);
710
- context.rotate(angle);
711
- context.translate(-x, -y);
725
+ const x: number = points[i].x + f * dx;
726
+ const y: number = points[i].y + f * dy;
727
+
728
+ const size: number = Math.max(12, 1.5 * merged.width);
712
729
 
713
- context.drawImage(
714
- this._images[merged.url],
715
- x + merged.dx,
716
- y + merged.dy,
717
- Number(merged.width),
718
- Number(merged.height)
719
- );
730
+ if (x > size && y > size && x < VECTOR_TILE_SIZE - size && y < VECTOR_TILE_SIZE - size) {
731
+ context.save();
732
+
733
+ context.translate(x, y);
734
+ context.rotate(angle);
735
+ context.translate(-x, -y);
736
+
737
+ context.drawImage(
738
+ this._images[merged.url],
739
+ x - size / 2,
740
+ y - size / 2,
741
+ size,
742
+ size,
743
+ );
720
744
 
721
- context.restore();
745
+ context.restore();
746
+ }
722
747
 
723
- distance += desired;
748
+ }
749
+ distance += desiredDistance;
724
750
  }
725
751
 
726
- distance = (desired - (distanceToNext - distance)) % desired;
752
+ traveled += distanceToNext;
753
+ distance -= distanceToNext;
754
+ // distance = (desiredDistance - (distanceToNext - distance)) % desiredDistance;
727
755
  }
728
756
  }
729
757
  }
@@ -755,14 +783,7 @@ class VectorTileRenderer {
755
783
  var merged = { ...VectorTileRenderer.DEFAULT_STYLE.TEXT, ...style };
756
784
 
757
785
  context.globalAlpha = merged.opacity;
758
- context.font =
759
- merged.fontStyle +
760
- " " +
761
- merged.fontWeight +
762
- " " +
763
- merged.size +
764
- "px " +
765
- merged.font;
786
+ context.font = `${merged.fontStyle} ${merged.fontWeight} ${merged.size}px ${merged.font}`;
766
787
 
767
788
  var points = this.projectCoordinates(coordinates, boundaries);
768
789
  if (points.length < 2) {
@@ -909,8 +930,8 @@ class VectorTileRenderer {
909
930
  positions.length == 0
910
931
  ? 0
911
932
  : Math.abs(
912
- positions[positions.length - 1].angle - position.angle
913
- );
933
+ positions[positions.length - 1].angle - position.angle
934
+ );
914
935
 
915
936
  if (!collision && deltaAngle < Math.PI / 6) {
916
937
  widthUsed += letterWidth;
@@ -957,7 +978,7 @@ class VectorTileRenderer {
957
978
  outline: number,
958
979
  context: CanvasRenderingContext2D
959
980
  ): void {
960
- var width = context.measureText(letter).width + outline; // XXX
981
+ var width = context.measureText(letter).width + outline;
961
982
 
962
983
  var x = position.x + 0.5 * Math.cos(position.angle) * width;
963
984
  var y = position.y + 0.5 * Math.sin(position.angle) * width;
@@ -1010,12 +1031,12 @@ class VectorTileRenderer {
1010
1031
  if (merged.url) {
1011
1032
  if (this._images[merged.url]) {
1012
1033
  var x = Math.round(
1013
- (256 * (coordinate[0] - boundaries.min.lon!)) /
1014
- (boundaries.max.lon! - boundaries.min.lon!)
1034
+ (VECTOR_TILE_SIZE * (coordinate[0] - boundaries.min.lon!)) /
1035
+ (boundaries.max.lon! - boundaries.min.lon!)
1015
1036
  );
1016
1037
  var y = Math.round(
1017
- (256 * (coordinate[1] - boundaries.min.lat!)) /
1018
- (boundaries.max.lat! - boundaries.min.lat!)
1038
+ (VECTOR_TILE_SIZE * (coordinate[1] - boundaries.min.lat!)) /
1039
+ (boundaries.max.lat! - boundaries.min.lat!)
1019
1040
  );
1020
1041
  if (merged.width && merged.height) {
1021
1042
  merged.width = Number(merged.width);
@@ -1045,26 +1066,19 @@ class VectorTileRenderer {
1045
1066
  ): boolean {
1046
1067
  var merged = { ...VectorTileRenderer.DEFAULT_STYLE.TEXT, ...style };
1047
1068
 
1048
- var x = Math.round(
1049
- (256 * (coordinate[0] - boundaries.min.lon)) /
1050
- (boundaries.max.lon - boundaries.min.lon)
1069
+ let x = Math.round(
1070
+ (VECTOR_TILE_SIZE * (coordinate[0] - boundaries.min.lon)) /
1071
+ (boundaries.max.lon - boundaries.min.lon)
1051
1072
  );
1052
- var y = Math.round(
1053
- (256 * (coordinate[1] - boundaries.min.lat)) /
1054
- (boundaries.max.lat - boundaries.min.lat)
1073
+ let y = Math.round(
1074
+ (VECTOR_TILE_SIZE * (coordinate[1] - boundaries.min.lat)) /
1075
+ (boundaries.max.lat - boundaries.min.lat)
1055
1076
  );
1056
1077
 
1057
- context.font =
1058
- merged.fontStyle +
1059
- " " +
1060
- merged.fontWeight +
1061
- " " +
1062
- merged.size +
1063
- "px " +
1064
- merged.font;
1078
+ context.font = `${merged.fontStyle} ${merged.fontWeight} ${merged.size}px ${merged.font}`;
1065
1079
 
1066
- var w = context.measureText(name).width;
1067
- var h = merged.size; // XXX ???
1080
+ const w = context.measureText(name).width;
1081
+ const h = merged.size; // XXX ???
1068
1082
 
1069
1083
  x = x - w / 2; // center on x
1070
1084
 
@@ -1085,23 +1099,16 @@ class VectorTileRenderer {
1085
1099
  var merged = { ...VectorTileRenderer.DEFAULT_STYLE.TEXT, ...style };
1086
1100
 
1087
1101
  var x = Math.round(
1088
- (256 * (coordinate[0] - boundaries.min.lon)) /
1089
- (boundaries.max.lon - boundaries.min.lon)
1102
+ (VECTOR_TILE_SIZE * (coordinate[0] - boundaries.min.lon)) /
1103
+ (boundaries.max.lon - boundaries.min.lon)
1090
1104
  );
1091
1105
  var y = Math.round(
1092
- (256 * (coordinate[1] - boundaries.min.lat)) /
1093
- (boundaries.max.lat - boundaries.min.lat)
1106
+ (VECTOR_TILE_SIZE * (coordinate[1] - boundaries.min.lat)) /
1107
+ (boundaries.max.lat - boundaries.min.lat)
1094
1108
  );
1095
1109
 
1096
1110
  context.globalAlpha = merged.opacity;
1097
- context.font =
1098
- merged.fontStyle +
1099
- " " +
1100
- merged.fontWeight +
1101
- " " +
1102
- merged.size +
1103
- "px " +
1104
- merged.font;
1111
+ context.font = `${merged.fontStyle} ${merged.fontWeight} ${merged.size}px ${merged.font}`;
1105
1112
 
1106
1113
  var w = context.measureText(name).width;
1107
1114
  var h = merged.size; // XXX ???
@@ -1158,15 +1165,8 @@ class VectorTileRenderer {
1158
1165
  let text = this._styles.renderers[renderer][i].text;
1159
1166
  if (text) {
1160
1167
  let merged = { ...VectorTileRenderer.DEFAULT_STYLE.TEXT, ...text };
1161
- let font = (
1162
- merged.fontStyle +
1163
- " " +
1164
- merged.fontWeight +
1165
- " " +
1166
- merged.size +
1167
- "px " +
1168
- merged.font
1169
- ).trim();
1168
+ let font = `${merged.fontStyle} ${merged.fontWeight} ${merged.size}px ${merged.font}`.trim();
1169
+
1170
1170
  result.push(font);
1171
1171
  }
1172
1172
  }
@@ -1,13 +1,21 @@
1
1
  export const URL_TEMPLATE =
2
2
  "https://v${index}.maptrip.de/?tilex=${x}&tiley=${y}&acao=true&context=tomtom${z}&project=${project}&projection=wgs84";
3
3
 
4
-
4
+
5
5
  export const PROVIDER_PROJECTS: { [key: string]: string } = {
6
6
  tomtom: "TomTom_latest",
7
+ orbis: "Orbis_latest",
7
8
  here: "HERE_latest",
8
9
  openstreetmap: "OSM_latest",
9
10
  };
10
11
 
12
+ export const PROVIDER_NAMES: { [key: string]: string } = {
13
+ tomtom: "TomTom",
14
+ orbis: "TomTom Orbis",
15
+ here: "HERE",
16
+ openstreetmap: "OpenStreetMap",
17
+ };
18
+
11
19
  export const PROVIDER_TRAFFIC: { [key: string]: string | null } = {
12
20
  tomtom:
13
21
  "https://v0.maptrip.de/tiles?project=TrafficMobileTomTom_EUROPE&tilex=${x}&tiley=${y}&acao=true&context=traffic${z}&projection=wgs84",
@@ -20,3 +28,6 @@ export const MAX_ZOOM = 18;
20
28
 
21
29
  export const ATTRIBUTION =
22
30
  '&#169;&nbsp;<a href="https://maptrip.de/" target="_blank">infoware GmbH</a>';
31
+
32
+ export const VECTOR_TILE_SIZE = 256;
33
+ export const VECTOR_TILE_RENDER_PADDING = 32;