mirror of https://gitee.com/antv-l7/antv-l7
feat(map): add mapbox
This commit is contained in:
parent
33550e1c3b
commit
d73a489172
|
@ -1,36 +0,0 @@
|
|||
import geom from '../../geom/geom';
|
||||
import { GeoBuffer, bufferGeometry, Material } from '../../geom/index';
|
||||
|
||||
|
||||
// geom shape buffer geometry material
|
||||
// shape name type()
|
||||
// buffer 1:n geometry
|
||||
// geometry
|
||||
//
|
||||
export default function polygonGeom(shape, coordinates, properties, layerid) {
|
||||
const polygongeom = geom.polygon;
|
||||
const { buffer, geometry, material } = polygongeom[shape];// polygon 映射表
|
||||
const bufferData = new GeoBuffer[buffer]({
|
||||
coordinates,
|
||||
properties,
|
||||
shape
|
||||
});
|
||||
bufferData.bufferStruct.name = layerid;
|
||||
const bg = new bufferGeometry[geometry](bufferData.bufferStruct);
|
||||
const mtl = Material[material]();
|
||||
return {
|
||||
geometry: bg,
|
||||
mtl
|
||||
};
|
||||
}
|
||||
|
||||
export function pointGeom(shape, bufferData) {
|
||||
const pointgeom = geom.point;
|
||||
const { geometry, material } = pointgeom[shape];
|
||||
const bg = new bufferGeometry[geometry](bufferData.bufferStruct);
|
||||
const mtl = Material[material]();
|
||||
return {
|
||||
geometry: bg,
|
||||
mtl
|
||||
};
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
import { getMap } from '../../map';
|
||||
import Base from '../base';
|
||||
export default class MapContorller extends Base {
|
||||
constructor(cfg, engine, scene) {
|
||||
super(cfg);
|
||||
this._engine = engine;
|
||||
this.scene = scene;
|
||||
}
|
||||
_init() {
|
||||
const mapType = this.get('mapType');
|
||||
const mapCfg = this.get('mapCfg');
|
||||
this.map = new getMap(mapType)(mapCfg);
|
||||
this.map('mapLoad', this._mapload.bind(this));
|
||||
}
|
||||
_mapload() {
|
||||
this.map.asyncCamera(this._engine);
|
||||
this.emit('loaded');
|
||||
}
|
||||
_bindMapMethod() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -11,6 +11,9 @@ export default class Engine extends EventEmitter {
|
|||
this._camera = new Camera(container).camera;
|
||||
this._renderer = new Renderer(container).renderer;
|
||||
this._world = world;
|
||||
// for MapBox
|
||||
this.world = new THREE.Group();
|
||||
this._scene.add(this.world);
|
||||
this._picking = Picking(this._world, this._renderer, this._camera, this._scene);
|
||||
this.clock = new THREE.Clock();
|
||||
}
|
||||
|
|
|
@ -63,7 +63,8 @@ export default class Layer extends Base {
|
|||
const layerId = this._getUniqueId();
|
||||
this.layerId = layerId;
|
||||
this._activeIds = null;
|
||||
scene._engine._scene.add(this._object3D);
|
||||
const world = scene._engine.world;
|
||||
world.add(this._object3D);
|
||||
this.layerMesh = null;
|
||||
this.layerLineMesh = null;
|
||||
this._initEvents();
|
||||
|
@ -110,7 +111,6 @@ export default class Layer extends Base {
|
|||
const { type = dataType } = cfg;
|
||||
cfg.data = data;
|
||||
cfg.mapType = this.get('mapType');
|
||||
|
||||
this.layerSource = new source[type](cfg);
|
||||
// this.scene.workerPool.runTask({
|
||||
// command: 'geojson',
|
||||
|
|
|
@ -3,8 +3,8 @@ import * as layers from '../layer';
|
|||
import Base from './base';
|
||||
import LoadImage from './image';
|
||||
import WorkerPool from './worker';
|
||||
import { MapProvider } from '../map/provider';
|
||||
import GaodeMap from '../map/gaodeMap';
|
||||
// import { MapProvider } from '../map/AMap';
|
||||
import { getMap } from '../map/index';
|
||||
import Global from '../global';
|
||||
export default class Scene extends Base {
|
||||
getDefaultCfg() {
|
||||
|
@ -13,7 +13,7 @@ export default class Scene extends Base {
|
|||
constructor(cfg) {
|
||||
super(cfg);
|
||||
this._initMap();
|
||||
this._initAttribution();
|
||||
// this._initAttribution();
|
||||
this.addImage();
|
||||
this._layers = [];
|
||||
}
|
||||
|
@ -29,16 +29,14 @@ export default class Scene extends Base {
|
|||
}
|
||||
_initMap() {
|
||||
this.mapContainer = this.get('id');
|
||||
this._container = document.getElementById(this.mapContainer);
|
||||
const Map = new MapProvider(this.mapContainer, this._attrs);
|
||||
this.mapType = this.get('mapType');
|
||||
const MapProvider = getMap(this.mapType);
|
||||
const Map = new MapProvider(this._attrs);
|
||||
Map.mixMap(this);
|
||||
this._container = document.getElementById(Map.container);
|
||||
// const Map = new MapProvider(this.mapContainer, this._attrs);
|
||||
Map.on('mapLoad', () => {
|
||||
this._initEngine(Map.renderDom);
|
||||
const sceneMap = new GaodeMap(Map.map);
|
||||
// eslint-disable-next-line
|
||||
Object.getOwnPropertyNames(sceneMap.__proto__).forEach((key)=>{
|
||||
// eslint-disable-next-line
|
||||
if ('key' !== 'constructor') { this.__proto__[key] = sceneMap.__proto__[key]; }
|
||||
});
|
||||
this.map = Map.map;
|
||||
Map.asyncCamera(this._engine);
|
||||
this.initLayer();
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/*
|
||||
* @Author: ThinkGIS
|
||||
* @Date: 2018-06-08 11:19:06
|
||||
* @Last Modified by: mikey.zhaopeng
|
||||
* @Last Modified time: 2018-11-01 11:50:43
|
||||
*/
|
||||
import Base from './base';
|
||||
const Controller = require('./controller/index');
|
||||
import { aProjectFlat } from '../geo/project';
|
||||
import { getMap } from '../map/index';
|
||||
export default class Source extends Base {
|
||||
getDefaultCfg() {
|
||||
return {
|
||||
|
@ -50,6 +44,8 @@ export default class Source extends Base {
|
|||
}
|
||||
_initControllers() {
|
||||
const defs = this.get('defs');
|
||||
const mapType = this.get('mapType');
|
||||
this.projectFlat = getMap(mapType).project;
|
||||
const scaleController = new Controller.Scale({
|
||||
defs
|
||||
});
|
||||
|
@ -83,8 +79,8 @@ export default class Source extends Base {
|
|||
}
|
||||
_coorConvert(geo) {
|
||||
|
||||
const ll = aProjectFlat(geo);
|
||||
return [ ll.x, -ll.y, geo[2] || 0 ];
|
||||
const ll = this.projectFlat(geo);
|
||||
return [ ll.x, ll.y, geo[2] || 0 ];
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ export { Scene } from 'three/src/scenes/Scene.js';
|
|||
export { WebGLRenderer } from 'three/src/renderers/WebGLRenderer.js';
|
||||
export { CanvasTexture } from 'three/src/textures/CanvasTexture.js';
|
||||
export { Object3D } from 'three/src/core/Object3D.js';
|
||||
export { Group } from 'three/src/objects/Group';
|
||||
export { Clock } from 'three/src/core/Clock';
|
||||
export { Points } from 'three/src/objects/Points.js';
|
||||
export { LineSegments } from 'three/src/objects/LineSegments.js';
|
||||
|
|
|
@ -1,18 +1,34 @@
|
|||
import Base from '../core/base';
|
||||
import { scene } from '../global';
|
||||
import * as Theme from '../theme/index';
|
||||
import Util from '../util';
|
||||
import { scene } from '../global';
|
||||
const DEG2RAD = Math.PI / 180;
|
||||
export class MapProvider extends Base {
|
||||
export default class GaodeMap extends Base {
|
||||
getDefaultCfg() {
|
||||
return Util.assign(scene, {
|
||||
resizeEnable: true,
|
||||
viewMode: '3D'
|
||||
});
|
||||
}
|
||||
constructor(container, cfg) {
|
||||
static project(lnglat) {
|
||||
const maxs = 85.0511287798;
|
||||
const lat = Math.max(Math.min(maxs, lnglat[1]), -maxs);
|
||||
const scale = 256 << 20;
|
||||
let d = Math.PI / 180;
|
||||
let x = lnglat[0] * d;
|
||||
let y = lat * d;
|
||||
y = Math.log(Math.tan((Math.PI / 4) + (y / 2)));
|
||||
const a = 0.5 / Math.PI,
|
||||
b = 0.5,
|
||||
c = -0.5 / Math.PI;
|
||||
d = 0.5;
|
||||
x = scale * (a * x + b) - 215440491;
|
||||
y = -(scale * (c * y + d) - 106744817);
|
||||
return { x, y };
|
||||
}
|
||||
constructor(cfg) {
|
||||
super(cfg);
|
||||
this.container = container;
|
||||
this.container = this.get('id');
|
||||
this.initMap();
|
||||
this.addOverLayer();
|
||||
setTimeout(() => {
|
||||
|
@ -85,4 +101,31 @@ export class MapProvider extends Base {
|
|||
this.renderDom.id = 'l7_canvaslayer';
|
||||
canvasContainer.appendChild(this.renderDom);
|
||||
}
|
||||
mixMap(scene) {
|
||||
const map = this.map;
|
||||
scene.getZoom = () => { return map.getZoom(); };
|
||||
scene.getCenter = () => { return map.getCenter(); };
|
||||
scene.getSize = () => { return map.getSize(); };
|
||||
scene.getPitch = () => { return map.getPitch(); };
|
||||
scene.getRotation = () => { return map.getRotation(); };
|
||||
scene.getStatus = () => { return map.getStatus(); };
|
||||
scene.getScale = () => { return map.getScale(); };
|
||||
scene.getZoom = () => { return map.getZoom(); };
|
||||
scene.setZoom = () => { return map.setZoom(); };
|
||||
scene.setBounds = () => { return map.setBounds(); };
|
||||
scene.setRotation = () => { return map.setRotation(); };
|
||||
scene.zoomIn = () => { return map.zoomIn(); };
|
||||
scene.setRotation = () => { return map.setRotation(); };
|
||||
scene.zoomOut = () => { return map.zoomOut(); };
|
||||
scene.panTo = () => { return map.panTo(); };
|
||||
scene.panBy = () => { return map.panBy(); };
|
||||
scene.setPitch = () => { return map.setPitch(); };
|
||||
scene.pixelToLngLat = () => { return map.pixelToLngLat(); };
|
||||
scene.lngLatToPixel = () => { return map.lngLatToPixel(); };
|
||||
scene.setMapStyle = () => { return map.setMapStyle(); };
|
||||
scene.containerToLngLat = pixel => {
|
||||
const ll = new AMap.Pixel(pixel.x, pixel.y);
|
||||
return map.containerToLngLat(ll);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ export default class GaodeMap {
|
|||
return this.map.getStatus();
|
||||
}
|
||||
getScale() {
|
||||
return this.getScale();
|
||||
return this.map.getScale();
|
||||
}
|
||||
setZoom(zoom) {
|
||||
return this.map.setZoom(zoom);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import MapBox from './mapbox';
|
||||
import { default as AMap } from './AMap';
|
||||
export {
|
||||
AMap,
|
||||
MapBox
|
||||
};
|
||||
const MapType = {
|
||||
amap: AMap,
|
||||
mapbox: MapBox
|
||||
};
|
||||
export const getMap = type => {
|
||||
return MapType[type.toLowerCase()];
|
||||
};
|
||||
|
||||
export const registerMap = (type, map) => {
|
||||
if (getMap(type)) {
|
||||
throw new Error(`Map type '${type}' existed.`);
|
||||
}
|
||||
map.type = type;
|
||||
// 存储到 map 中
|
||||
MapType[type.toLowerCase()] = map;
|
||||
};
|
|
@ -3,22 +3,27 @@ import Util from '../util';
|
|||
import { scene } from '../global';
|
||||
import * as THREE from '../core/three';
|
||||
const WORLD_SIZE = 512;
|
||||
export class MapBoxProvider extends Base {
|
||||
const MERCATOR_A = 6378137.0;
|
||||
const WORLD_SCALE = 1.0;
|
||||
const PROJECTION_WORLD_SIZE = WORLD_SIZE / (MERCATOR_A * Math.PI) / 2;
|
||||
export default class MapBox extends Base {
|
||||
getDefaultCfg() {
|
||||
return Util.assign(scene, {
|
||||
resizeEnable: true,
|
||||
viewMode: '3D'
|
||||
});
|
||||
}
|
||||
constructor(container, cfg, engine) {
|
||||
static project(lnglat) {
|
||||
const d = Math.PI / 180;
|
||||
const x = -MERCATOR_A * lnglat[0] * d * PROJECTION_WORLD_SIZE;
|
||||
const y = -MERCATOR_A * Math.log(Math.tan((Math.PI * 0.25) + (0.5 * lnglat[1] * d))) * PROJECTION_WORLD_SIZE;
|
||||
return { x, y };
|
||||
}
|
||||
constructor(cfg) {
|
||||
super(cfg);
|
||||
this.container = container;
|
||||
this.engine = engine;
|
||||
const scene = engine._scene;
|
||||
this.container = this.get('container');
|
||||
this.initMap();
|
||||
this.addOverLayer();
|
||||
scene.position.x = scene.position.y = WORLD_SIZE / 2;
|
||||
scene.matrixAutoUpdate = false;
|
||||
setTimeout(() => {
|
||||
this.emit('mapLoad');
|
||||
}, 100);
|
||||
|
@ -28,15 +33,24 @@ export class MapBoxProvider extends Base {
|
|||
initMap() {
|
||||
mapboxgl.accessToken = 'pk.eyJ1IjoibHp4dWUiLCJhIjoiYnhfTURyRSJ9.Ugm314vAKPHBzcPmY1p4KQ';
|
||||
this.map = new mapboxgl.Map(this._attrs);
|
||||
}
|
||||
asyncCamera(engine) {
|
||||
this.engine = engine;
|
||||
const camera = engine._camera;
|
||||
const scene = engine.world;
|
||||
camera.matrixAutoUpdate = false;
|
||||
scene.position.x = scene.position.y = WORLD_SIZE / 2;
|
||||
scene.matrixAutoUpdate = false;
|
||||
scene.autoUpdate = false;
|
||||
this.updateCamera();
|
||||
this.map.on('move', () => {
|
||||
this.updateCamera();
|
||||
});
|
||||
this.updateCamera();
|
||||
}
|
||||
asyncCamera() {
|
||||
updateCamera() {
|
||||
const engine = this.engine;
|
||||
const scene = engine.world;
|
||||
const camera = engine._camera;
|
||||
const scene = engine._scene;
|
||||
// Build a projection matrix, paralleling the code found in Mapbox GL JS
|
||||
const fov = 0.6435011087932844;
|
||||
const cameraToCenterDistance = 0.5 / Math.tan(fov / 2) * this.map.transform.height;
|
||||
|
@ -49,25 +63,22 @@ export class MapBoxProvider extends Base {
|
|||
|
||||
// Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance`
|
||||
const farZ = furthestDistance * 1.01;
|
||||
|
||||
const { x, y } = this.map.transform.point;
|
||||
camera.projectionMatrix = this.makePerspectiveMatrix(fov, this.map.transform.width / this.map.transform.height, 1, farZ);
|
||||
|
||||
|
||||
const cameraWorldMatrix = new THREE.Matrix4();
|
||||
const cameraTranslateZ = new THREE.Matrix4().makeTranslation(0, 0, cameraToCenterDistance);
|
||||
const cameraRotateX = new THREE.Matrix4().makeRotationX(this.map.transform._pitch);
|
||||
const cameraRotateZ = new THREE.Matrix4().makeRotationZ(this.map.transform.angle);
|
||||
|
||||
// const cameraTranslateCenter = new THREE.Matrix4().makeTranslation(0, 0, cameraToCenterDistance);
|
||||
// Unlike the Mapbox GL JS camera, separate camera translation and rotation out into its world matrix
|
||||
// If this is applied directly to the projection matrix, it will work OK but break raycasting
|
||||
cameraWorldMatrix
|
||||
.premultiply(cameraTranslateZ)
|
||||
.premultiply(cameraRotateX)
|
||||
.premultiply(cameraRotateZ);
|
||||
|
||||
camera.matrixWorld.copy(cameraWorldMatrix);
|
||||
|
||||
|
||||
const zoomPow = this.map.transform.scale;
|
||||
// Handle scaling and translation of objects in the map in the world's matrix transform, not the camera
|
||||
const scale = new THREE.Matrix4();
|
||||
|
@ -82,7 +93,6 @@ export class MapBoxProvider extends Base {
|
|||
.makeTranslation(-this.map.transform.x, this.map.transform.y, 0);
|
||||
rotateMap
|
||||
.makeRotationZ(Math.PI);
|
||||
|
||||
scene.matrix = new THREE.Matrix4();
|
||||
scene.matrix
|
||||
.premultiply(rotateMap)
|
||||
|
@ -117,8 +127,15 @@ export class MapBoxProvider extends Base {
|
|||
const canvasContainer = document.getElementById(this.container);
|
||||
this.canvasContainer = canvasContainer;
|
||||
this.renderDom = document.createElement('div');
|
||||
this.renderDom.style.cssText += 'position: absolute;top: 0; z-index:1;height: 100%;width: 100%;pointer-events: none;';
|
||||
this.renderDom.style.cssText += 'position: absolute;top: 0; z-index:10;height: 100%;width: 100%;pointer-events: none;';
|
||||
this.renderDom.id = 'l7_canvaslayer';
|
||||
canvasContainer.appendChild(this.renderDom);
|
||||
}
|
||||
mixMap(scene) {
|
||||
const map = this.map;
|
||||
scene.getZoom = () => { return map.getZoom(); };
|
||||
scene.getCenter = () => { return map.getCenter(); };
|
||||
scene.getPitch = () => { return map.getPitch(); };
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue