Skip to content

Commit

Permalink
replace Coordinate with MercatorCoordinate
Browse files Browse the repository at this point in the history
  • Loading branch information
ansis committed Oct 26, 2018
1 parent 050b1e5 commit 8856fbf
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 272 deletions.
79 changes: 0 additions & 79 deletions src/geo/coordinate.js

This file was deleted.

1 change: 0 additions & 1 deletion src/geo/mercator_coordinate.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class MercatorCoordinate {
const y = (180 - (180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lngLat.lat * Math.PI / 360)))) / 360;
const z = altitude === undefined ? 0 : (altitude / circumferenceAtLatitude(lngLat.lat));
return new MercatorCoordinate(x, y, z);

}

/**
Expand Down
68 changes: 31 additions & 37 deletions src/geo/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import LngLat from './lng_lat';
import LngLatBounds from './lng_lat_bounds';
import MercatorCoordinate from './mercator_coordinate';
import Point from '@mapbox/point-geometry';
import Coordinate from './coordinate';
import { wrap, clamp } from '../util/util';
import {number as interpolate} from '../style-spec/util/interpolate';
import tileCover from '../util/tile_cover';
Expand Down Expand Up @@ -204,12 +203,12 @@ class Transform {
getVisibleUnwrappedCoordinates(tileID: CanonicalTileID) {
const result = [new UnwrappedTileID(0, tileID)];
if (this._renderWorldCopies) {
const utl = this.pointCoordinate(new Point(0, 0), 0);
const utr = this.pointCoordinate(new Point(this.width, 0), 0);
const ubl = this.pointCoordinate(new Point(this.width, this.height), 0);
const ubr = this.pointCoordinate(new Point(0, this.height), 0);
const w0 = Math.floor(Math.min(utl.column, utr.column, ubl.column, ubr.column));
const w1 = Math.floor(Math.max(utl.column, utr.column, ubl.column, ubr.column));
const utl = this.pointCoordinate(new Point(0, 0));
const utr = this.pointCoordinate(new Point(this.width, 0));
const ubl = this.pointCoordinate(new Point(this.width, this.height));
const ubr = this.pointCoordinate(new Point(0, this.height));
const w0 = Math.floor(Math.min(utl.x, utr.x, ubl.x, ubr.x));
const w1 = Math.floor(Math.max(utl.x, utr.x, ubl.x, ubr.x));

// Add an extra copy of the world on each side to properly render ImageSources and CanvasSources.
// Both sources draw outside the tile boundaries of the tile that "contains them" so we need
Expand Down Expand Up @@ -252,13 +251,14 @@ class Transform {
if (options.minzoom !== undefined && z < options.minzoom) return [];
if (options.maxzoom !== undefined && z > options.maxzoom) z = options.maxzoom;

const centerCoord = this.pointCoordinate(this.centerPoint, z);
const centerPoint = new Point(centerCoord.column - 0.5, centerCoord.row - 0.5);
const centerCoord = MercatorCoordinate.fromLngLat(this.center);
const numTiles = Math.pow(2, z);
const centerPoint = new Point(numTiles * centerCoord.x - 0.5, numTiles * centerCoord.y - 0.5);
const cornerCoords = [
this.pointCoordinate(new Point(0, 0), z),
this.pointCoordinate(new Point(this.width, 0), z),
this.pointCoordinate(new Point(this.width, this.height), z),
this.pointCoordinate(new Point(0, this.height), z)
this.pointCoordinate(new Point(0, 0)),
this.pointCoordinate(new Point(this.width, 0)),
this.pointCoordinate(new Point(this.width, this.height)),
this.pointCoordinate(new Point(0, this.height))
];
return tileCover(z, cornerCoords, options.reparseOverscaled ? actualZ : z, this._renderWorldCopies)
.sort((a, b) => centerPoint.dist(a.canonical) - centerPoint.dist(b.canonical));
Expand Down Expand Up @@ -292,8 +292,13 @@ class Transform {
get point(): Point { return this.project(this.center); }

setLocationAtPoint(lnglat: LngLat, point: Point) {
const translate = this.pointCoordinate(point)._sub(this.pointCoordinate(this.centerPoint));
this.center = this.coordinateLocation(this.locationCoordinate(lnglat)._sub(translate));
const a = this.pointCoordinate(point);
const b = this.pointCoordinate(this.centerPoint);
const loc = this.locationCoordinate(lnglat);
const newCenter = new MercatorCoordinate(
loc.x - (a.x - b.x),
loc.y - (a.y - b.y));
this.center = this.coordinateLocation(newCenter);
if (this._renderWorldCopies) {
this.center = this.center.wrap();
}
Expand Down Expand Up @@ -324,28 +329,19 @@ class Transform {
* @returns {Coordinate}
*/
locationCoordinate(lnglat: LngLat) {
const coord = this.project(lnglat);
return new Coordinate(
coord.x / this.tileSize,
coord.y / this.tileSize,
this.zoom).zoomTo(this.tileZoom);
return MercatorCoordinate.fromLngLat(lnglat);
}

/**
* Given a Coordinate, return its geographical position.
* @param {Coordinate} coord
* @returns {LngLat} lnglat
*/
coordinateLocation(coord: Coordinate) {
const zoomedCoord = coord.zoomTo(this.zoom);
return this.unproject(new Point(
zoomedCoord.column * this.tileSize,
zoomedCoord.row * this.tileSize));
coordinateLocation(coord: MercatorCoordinate) {
return coord.toLngLat();
}

pointCoordinate(p: Point, zoom?: number) {
if (zoom === undefined) zoom = this.tileZoom;

pointCoordinate(p: Point) {
const targetZ = 0;
// since we don't know the correct projected z value for the point,
// unproject two points to get a line and then find the point on that
Expand All @@ -368,20 +364,18 @@ class Transform {

const t = z0 === z1 ? 0 : (targetZ - z0) / (z1 - z0);

return new Coordinate(
interpolate(x0, x1, t) / this.tileSize,
interpolate(y0, y1, t) / this.tileSize,
this.zoom)._zoomTo(zoom);
return new MercatorCoordinate(
interpolate(x0, x1, t) / this.worldSize,
interpolate(y0, y1, t) / this.worldSize);
}

/**
* Given a coordinate, return the screen point that corresponds to it
* @param {Coordinate} coord
* @returns {Point} screen point
*/
coordinatePoint(coord: Coordinate) {
const zoomedCoord = coord.zoomTo(this.zoom);
const p = [zoomedCoord.column * this.tileSize, zoomedCoord.row * this.tileSize, 0, 1];
coordinatePoint(coord: MercatorCoordinate) {
const p = [coord.x * this.worldSize, coord.y * this.worldSize, 0, 1];
vec4.transformMat4(p, p, this.pixelMatrix);
return new Point(p[0] / p[3], p[1] / p[3]);
}
Expand Down Expand Up @@ -593,8 +587,8 @@ class Transform {
// calcMatrices hasn't run yet
if (!this.pixelMatrixInverse) return 1;

const coord = this.pointCoordinate(new Point(0, 0)).zoomTo(this.zoom);
const p = [coord.column * this.tileSize, coord.row * this.tileSize, 0, 1];
const coord = this.pointCoordinate(new Point(0, 0));
const p = [coord.x * this.worldSize, coord.y * this.worldSize, 0, 1];
const topPoint = vec4.transformMat4(p, p, this.pixelMatrix);
return topPoint[3] / this.cameraToCenterDistance;
}
Expand Down
12 changes: 5 additions & 7 deletions src/render/program/hillshade_program.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
UniformMatrix4f
} from '../uniform_binding';
import EXTENT from '../../data/extent';
import Coordinate from '../../geo/coordinate';
import MercatorCoordinate from '../../geo/mercator_coordinate';

import type Context from '../../gl/context';
import type {UniformValues, UniformLocations} from '../uniform_binding';
Expand Down Expand Up @@ -104,13 +104,11 @@ const hillshadeUniformPrepareValues = (

function getTileLatRange(painter: Painter, tileID: OverscaledTileID) {
// for scaling the magnitude of a points slope by its latitude
const coordinate0 = tileID.toCoordinate();
const coordinate1 = new Coordinate(
coordinate0.column, coordinate0.row + 1, coordinate0.zoom);
const tilesAtZoom = Math.pow(2, tileID.canonical.z);
const y = tileID.canonical.y;
return [
painter.transform.coordinateLocation(coordinate0).lat,
painter.transform.coordinateLocation(coordinate1).lat
];
new MercatorCoordinate(0, y / tilesAtZoom).toLngLat().lat,
new MercatorCoordinate(0, (y + 1) / tilesAtZoom).toLngLat().lat];
}

export {
Expand Down
60 changes: 36 additions & 24 deletions src/source/image_source.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// @flow

import { getCoordinatesCenter } from '../util/util';

import { CanonicalTileID } from './tile_id';
import LngLat from '../geo/lng_lat';
import Point from '@mapbox/point-geometry';
import { Event, ErrorEvent, Evented } from '../util/evented';
import { getImage, ResourceType } from '../util/ajax';
import browser from '../util/browser';
Expand All @@ -13,13 +9,13 @@ import { RasterBoundsArray } from '../data/array_types';
import rasterBoundsAttributes from '../data/raster_bounds_attributes';
import SegmentVector from '../data/segment';
import Texture from '../render/texture';
import MercatorCoordinate from '../geo/mercator_coordinate';

import type {Source} from './source';
import type {CanvasSourceSpecification} from './canvas_source';
import type Map from '../ui/map';
import type Dispatcher from '../util/dispatcher';
import type Tile from './tile';
import type Coordinate from '../geo/coordinate';
import type {Callback} from '../types/callback';
import type VertexBuffer from '../gl/vertex_buffer';
import type {
Expand Down Expand Up @@ -84,7 +80,6 @@ class ImageSource extends Evented implements Source {
map: Map;
texture: Texture | null;
image: ImageData;
centerCoord: Coordinate;
tileID: CanonicalTileID;
_boundsArray: RasterBoundsArray;
boundsBuffer: VertexBuffer;
Expand Down Expand Up @@ -180,35 +175,21 @@ class ImageSource extends Evented implements Source {
// and create a buffer with the corner coordinates. These coordinates
// may be outside the tile, because raster tiles aren't clipped when rendering.

const map = this.map;

// transform the geo coordinates into (zoom 0) tile space coordinates
const cornerZ0Coords = coordinates.map((coord) => {
return map.transform.locationCoordinate(LngLat.convert(coord)).zoomTo(0);
});
const cornerCoords = coordinates.map(MercatorCoordinate.fromLngLat);

// Compute the coordinates of the tile we'll use to hold this image's
// render data
const centerCoord = this.centerCoord = getCoordinatesCenter(cornerZ0Coords);
// `column` and `row` may be fractional; round them down so that they
// represent integer tile coordinates
centerCoord.column = Math.floor(centerCoord.column);
centerCoord.row = Math.floor(centerCoord.row);
this.tileID = new CanonicalTileID(centerCoord.zoom, centerCoord.column, centerCoord.row);
this.tileID = getCoordinatesCenterTileID(cornerCoords);

// Constrain min/max zoom to our tile's zoom level in order to force
// SourceCache to request this tile (no matter what the map's zoom
// level)
this.minzoom = this.maxzoom = centerCoord.zoom;
this.minzoom = this.maxzoom = this.tileID.z;

// Transform the corner coordinates into the coordinate space of our
// tile.
const tileCoords = cornerZ0Coords.map((coord) => {
const zoomedCoord = coord.zoomTo(centerCoord.zoom);
return new Point(
Math.round((zoomedCoord.column - centerCoord.column) * EXTENT),
Math.round((zoomedCoord.row - centerCoord.row) * EXTENT));
});
const tileCoords = cornerCoords.map((coord) => this.tileID.getTilePoint(coord)._round());

this._boundsArray = new RasterBoundsArray();
this._boundsArray.emplaceBack(tileCoords[0].x, tileCoords[0].y, 0, 0);
Expand Down Expand Up @@ -285,4 +266,35 @@ class ImageSource extends Evented implements Source {
}
}

/**
* Given a list of coordinates, get their center as a coordinate.
*
* @returns centerpoint
* @private
*/
export function getCoordinatesCenterTileID(coords: Array<MercatorCoordinate>) {
let minX = Infinity;
let minY = Infinity;
let maxX = -Infinity;
let maxY = -Infinity;

for (const coord of coords) {
minX = Math.min(minX, coord.x);
minY = Math.min(minY, coord.y);
maxX = Math.max(maxX, coord.x);
maxY = Math.max(maxY, coord.y);
}

const dx = maxX - minX;
const dy = maxY - minY;
const dMax = Math.max(dx, dy);
const zoom = Math.max(0, Math.floor(-Math.log(dMax) / Math.LN2));
const tilesAtZoom = Math.pow(2, zoom);

return new CanonicalTileID(
zoom,
Math.floor((minX + maxX) / 2 * tilesAtZoom),
Math.floor((minY + maxY) / 2 * tilesAtZoom));
}

export default ImageSource;
4 changes: 2 additions & 2 deletions src/source/query_features.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import type SourceCache from './source_cache';
import type StyleLayer from '../style/style_layer';
import type Coordinate from '../geo/coordinate';
import type MercatorCoordinate from '../geo/mercator_coordinate';
import type CollisionIndex from '../symbol/collision_index';
import type Transform from '../geo/transform';
import type { RetainedQueryData } from '../symbol/placement';
Expand All @@ -11,7 +11,7 @@ import assert from 'assert';

export function queryRenderedFeatures(sourceCache: SourceCache,
styleLayers: {[string]: StyleLayer},
queryGeometry: Array<Coordinate>,
queryGeometry: Array<MercatorCoordinate>,
params: { filter: FilterSpecification, layers: Array<string> },
transform: Transform) {
const maxPitchScaleFactor = transform.maxPitchScaleFactor();
Expand Down
Loading

0 comments on commit 8856fbf

Please sign in to comment.