Skip to content

Commit

Permalink
rough projection support
Browse files Browse the repository at this point in the history
  • Loading branch information
ansis committed May 26, 2021
1 parent 73544cc commit ace7e13
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 19 deletions.
32 changes: 31 additions & 1 deletion debug/satellite.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@

var map = window.map = new mapboxgl.Map({
container: 'map',
zoom: 12.5,
zoom: 0,
center: [-77.01866, 38.888],
style: 'mapbox://styles/mapbox/satellite-v9',
hash: true
});
map.on('load', function () {
/*
map.addSource('mapbox-dem', {
"type": "raster-dem",
"url": "mapbox://mapbox.terrain-rgb",
Expand All @@ -48,6 +49,35 @@
document.getElementById('terrain').onclick = function() {
map.setTerrain(this.checked ? {"source": "mapbox-dem"} : undefined);
};
*/

map.addSource('streets', {"url":"mapbox://mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7","type":"vector"});
/*
map.addLayer({
id: 'water',
type: 'fill',
'source-layer': 'water',
'source': 'streets',
paint: {
'fill-color': 'blue'
}
});
*/

map.addLayer({
id: 'symbol',
type: 'symbol',
'source-layer': 'country_label',
'source': 'streets',
paint: {
"text-color": "white",
"text-halo-color": "black"
},
layout: {
"text-field": ["get", "name_en"]
}
});
});

</script>
</body>
Expand Down
3 changes: 2 additions & 1 deletion src/data/bucket/fill_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class FillBucket implements Bucket {

constructor(options: BucketParameters<FillStyleLayer>) {
this.zoom = options.zoom;
this.canonical = options.canonical;
this.overscaling = options.overscaling;
this.layers = options.layers;
this.layerIds = this.layers.map(layer => layer.id);
Expand Down Expand Up @@ -96,7 +97,7 @@ class FillBucket implements Bucket {
type: feature.type,
sourceLayerIndex,
index,
geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature),
geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature, this.canonical),
patterns: {},
sortKey
};
Expand Down
3 changes: 2 additions & 1 deletion src/data/bucket/line_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class LineBucket implements Bucket {

constructor(options: BucketParameters<LineStyleLayer>) {
this.zoom = options.zoom;
this.canonical = options.canonical;
this.overscaling = options.overscaling;
this.layers = options.layers;
this.layerIds = this.layers.map(layer => layer.id);
Expand Down Expand Up @@ -155,7 +156,7 @@ class LineBucket implements Bucket {
type: feature.type,
sourceLayerIndex,
index,
geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature),
geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature, this.canonical),
patterns: {},
sortKey
};
Expand Down
3 changes: 2 additions & 1 deletion src/data/bucket/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ class SymbolBucket implements Bucket {
constructor(options: BucketParameters<SymbolStyleLayer>) {
this.collisionBoxArray = options.collisionBoxArray;
this.zoom = options.zoom;
this.canonical = options.canonical;
this.overscaling = options.overscaling;
this.layers = options.layers;
this.layerIds = this.layers.map(layer => layer.id);
Expand Down Expand Up @@ -455,7 +456,7 @@ class SymbolBucket implements Bucket {
continue;
}

if (!needGeometry) evaluationFeature.geometry = loadGeometry(feature);
if (!needGeometry) evaluationFeature.geometry = loadGeometry(feature, this.canonical);

let text: Formatted | void;
if (hasText) {
Expand Down
50 changes: 44 additions & 6 deletions src/data/load_geometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import {warnOnce, clamp} from '../util/util.js';

import EXTENT from './extent.js';
import MercatorCoordinate from '../geo/mercator_coordinate.js';
import Transform from '../geo/transform.js';
import assert from 'assert';

import type Point from '@mapbox/point-geometry';

Expand All @@ -14,23 +17,58 @@ const BITS = 15;
const MAX = Math.pow(2, BITS - 1) - 1;
const MIN = -MAX - 1;

const projection = (new Transform()).projection;

function resample(ring) {
if (ring.length === 0) return;
const result = [];
result.push(ring[0]);
for (let i = 1; i < ring.length; i++) {
const last = result[result.length - 1];
const p = ring[i];
const d = p.dist(last);
const m = 16;
for (let i = m; i < d; i += m) {
result.push(last.add(p.sub(last).mult(i / d)));
}
result.push(p);
}
return result;
}

/**
* Loads a geometry from a VectorTileFeature and scales it to the common extent
* used internally.
* @param {VectorTileFeature} feature
* @private
*/
export default function loadGeometry(feature: VectorTileFeature): Array<Array<Point>> {
const scale = EXTENT / feature.extent;
export default function loadGeometry(feature: VectorTileFeature, canonical): Array<Array<Point>> {
if (!canonical) return [];
const cs = projection.tileTransform(canonical);
const reproject = (p, featureExtent) => {
const s = Math.pow(2, canonical.z)
const x = (canonical.x + p.x / featureExtent) / s;
const y = (canonical.y + p.y / featureExtent) / s;
const l = new MercatorCoordinate(x, y).toLngLat();
const x_ = projection.projectX(l.lng, l.lat);
const y_ = projection.projectY(l.lng, l.lat);
p.x = (x_ * cs.scale - cs.x) * EXTENT;
p.y = (y_ * cs.scale - cs.y) * EXTENT;
};
const scale = EXTENT / EXTENT;
const geometry = feature.loadGeometry();
for (let r = 0; r < geometry.length; r++) {
const ring = geometry[r];
let ring = geometry[r];
ring = resample(ring);
geometry[r] = ring;
for (let p = 0; p < ring.length; p++) {
const point = ring[p];
let point = ring[p];
// round here because mapbox-gl-native uses integers to represent
// points and we need to do the same to avoid rendering differences.
const x = Math.round(point.x * scale);
const y = Math.round(point.y * scale);
//const x = Math.round(point.x * scale);
//const y = Math.round(point.y * scale);
reproject(point, feature.extent);
const {x, y} = point;

point.x = clamp(x, MIN, MAX);
point.y = clamp(y, MIN, MAX);
Expand Down
16 changes: 16 additions & 0 deletions src/geo/mercator_coordinate.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
import LngLat, {earthRadius} from '../geo/lng_lat.js';
import type {LngLatLike} from '../geo/lng_lat.js';

export const mercatorProjection = {
projectX: (lng) => mercatorXfromLng(lng),
projectY: (lng, lat) => mercatorYfromLat(lat),
unproject: (x, y) => new MercatorCoordinate(x, y).toLngLat(),
tileTransform: (id) => {
const scale = Math.pow(2, id.z);
return {
x: id.x,
y: id.y,
x2: id.x + 1,
y2: id.y + 1,
scale
};
}
}

/*
* The average circumference of the world in meters.
*/
Expand Down
Loading

0 comments on commit ace7e13

Please sign in to comment.