mirror of https://gitee.com/antv-l7/antv-l7
fix(map): mapbox
This commit is contained in:
commit
cb153f639e
|
@ -69,7 +69,6 @@ lib
|
||||||
|
|
||||||
*.sw*
|
*.sw*
|
||||||
*.un~
|
*.un~
|
||||||
demos/mapbox.html
|
|
||||||
demos/gd.html
|
demos/gd.html
|
||||||
demos/data
|
demos/data
|
||||||
demos/image
|
demos/image
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<meta name="geometry" content="diagram">
|
||||||
|
<link rel="stylesheet" href="./assets/common.css">
|
||||||
|
<link rel="stylesheet" href="./assets/info.css">
|
||||||
|
<title>point_circle</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
#map { position:absolute; top:0; bottom:0; width:100%; margin:0; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="map"></div>
|
||||||
|
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.34.0/mapbox-gl.js'></script>
|
||||||
|
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.34.0/mapbox-gl.css' rel='stylesheet' />
|
||||||
|
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||||
|
<script src="./assets/dat.gui.min.js"></script>
|
||||||
|
<script src="../build/L7.js"></script>
|
||||||
|
<script>
|
||||||
|
const colorObj ={
|
||||||
|
blue: ["#E8FCFF", "#CFF6FF", "#A1E9ff", "#65CEF7", "#3CB1F0", "#2894E0", "#1772c2", "#105CB3", "#0D408C", "#002466"].reverse(),
|
||||||
|
red: ["#FFF4F2", "#FFDFDB", "#FAADAA", "#F77472", "#F04850", "#D63147", "#BD223E", "#A81642", "#820C37", "#5C0023"].reverse(),
|
||||||
|
orange:["#FFF7EB", "#FFECD4", "#FAD09D", "#F7B16A", "#F08D41", "#DB6C2C", "#C2491D", "#AD2B11", "#871D0C", "#610800"].reverse(),
|
||||||
|
green:["#FAFFF0", "#EBF7D2", "#C8E695", "#A5D660", "#7DC238", "#59A616", "#3F8C0B", "#237804", "#125200", "#082B00"].reverse(),
|
||||||
|
yellow:["#FFFFE8", "#FFFECC", "#FAF896", "#F7E463", "#F0CE3A", "#DBB125", "#C29117", "#AD7410", "#87500C", "#613000"].reverse(),
|
||||||
|
purple:["#FCF2FF", "#F5DEFF", "#DDB3F2", "#BE7BE3", "#9B4ECF", "#7737B3", "#5B2899", "#411C85", "#270F5E", "#100338"].reverse()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const scene = new L7.Scene({
|
||||||
|
container: 'map',
|
||||||
|
mapType:'mapbox',
|
||||||
|
style: 'mapbox://styles/mapbox/streets-v9', // stylesheet location
|
||||||
|
center: [ 120.19382669582967, 30.258134 ],
|
||||||
|
pitch: 0,
|
||||||
|
hash:true,
|
||||||
|
zoom: 1,
|
||||||
|
});
|
||||||
|
window.scene = scene;
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
var colors = ["#FFF5B8","#FFDC7D","#FFAB5C","#F27049","#D42F31","#730D1C"];
|
||||||
|
$.getJSON('https://gw.alipayobjects.com/os/rmsportal/JToMOWvicvJOISZFCkEI.json', city => {
|
||||||
|
const citylayer = scene.PolygonLayer()
|
||||||
|
.source(city)
|
||||||
|
//.color('pm2_5_24h',["#FFF5B8","#FFDC7D","#FFAB5C","#F27049","#D42F31","#730D1C"])
|
||||||
|
.color('pm2_5_24h',(p)=>{
|
||||||
|
if(p>120){
|
||||||
|
return colors[5];
|
||||||
|
} else if(p>65){
|
||||||
|
return colors[4];
|
||||||
|
} else if(p>30) {
|
||||||
|
return colors[3];
|
||||||
|
} else if(p>15){
|
||||||
|
return colors[2];
|
||||||
|
} else if(p>8){
|
||||||
|
return colors[1];
|
||||||
|
}else {
|
||||||
|
return colors[0];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.shape('fill')
|
||||||
|
.active(true)
|
||||||
|
.style({
|
||||||
|
opacity: 1
|
||||||
|
})
|
||||||
|
.render();
|
||||||
|
console.log('success');
|
||||||
|
});
|
||||||
|
$.get('https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json', data => {
|
||||||
|
citylayer = scene.PolygonLayer({
|
||||||
|
zIndex: 2
|
||||||
|
})
|
||||||
|
.source(data)
|
||||||
|
.shape('extrude')
|
||||||
|
.active({fill:'red'})
|
||||||
|
.size('floor',[0.1,1])
|
||||||
|
.color('#aaa')
|
||||||
|
.render();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -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._camera = new Camera(container).camera;
|
||||||
this._renderer = new Renderer(container).renderer;
|
this._renderer = new Renderer(container).renderer;
|
||||||
this._world = world;
|
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._picking = Picking(this._world, this._renderer, this._camera, this._scene);
|
||||||
this.clock = new THREE.Clock();
|
this.clock = new THREE.Clock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ class Picking {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this._raycaster.linePrecision = 10;
|
this._raycaster.linePrecision = 10;
|
||||||
this._pickingScene = PickingScene;
|
this._pickingScene = PickingScene;
|
||||||
|
this.world = new THREE.Group();
|
||||||
|
this._pickingScene.add(this.world);
|
||||||
const size = this._renderer.getSize();
|
const size = this._renderer.getSize();
|
||||||
this._width = size.width;
|
this._width = size.width;
|
||||||
this._height = size.height;
|
this._height = size.height;
|
||||||
|
@ -60,12 +62,12 @@ class Picking {
|
||||||
|
|
||||||
}
|
}
|
||||||
_filterObject(id) {
|
_filterObject(id) {
|
||||||
this._pickingScene.children.forEach((object, index) => {
|
this.world.children.forEach((object, index) => {
|
||||||
index === id ? object.visible = true : object.visible = false;
|
index === id ? object.visible = true : object.visible = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_pickAllObject(point, normalisedPoint) {
|
_pickAllObject(point, normalisedPoint) {
|
||||||
this._pickingScene.children.forEach((object, index) => {
|
this.world.children.forEach((object, index) => {
|
||||||
this._filterObject(index);
|
this._filterObject(index);
|
||||||
const item = this._pick(point, normalisedPoint, object.name);
|
const item = this._pick(point, normalisedPoint, object.name);
|
||||||
item.type = point.type;
|
item.type = point.type;
|
||||||
|
@ -85,7 +87,6 @@ class Picking {
|
||||||
id = -999;
|
id = -999;
|
||||||
// return;
|
// return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._raycaster.setFromCamera(normalisedPoint, this._camera);
|
this._raycaster.setFromCamera(normalisedPoint, this._camera);
|
||||||
|
|
||||||
const intersects = this._raycaster.intersectObjects(this._pickingScene.children, true);
|
const intersects = this._raycaster.intersectObjects(this._pickingScene.children, true);
|
||||||
|
@ -110,13 +111,14 @@ class Picking {
|
||||||
//
|
//
|
||||||
// Picking ID should already be added as an attribute
|
// Picking ID should already be added as an attribute
|
||||||
add(mesh) {
|
add(mesh) {
|
||||||
this._pickingScene.add(mesh);
|
this.world.add(mesh);
|
||||||
|
|
||||||
this._needUpdate = true;
|
this._needUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove mesh from picking scene
|
// Remove mesh from picking scene
|
||||||
remove(mesh) {
|
remove(mesh) {
|
||||||
this._pickingScene.remove(mesh);
|
this.world.remove(mesh);
|
||||||
this._needUpdate = true;
|
this._needUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,8 @@ export default class Layer extends Base {
|
||||||
const layerId = this._getUniqueId();
|
const layerId = this._getUniqueId();
|
||||||
this.layerId = layerId;
|
this.layerId = layerId;
|
||||||
this._activeIds = null;
|
this._activeIds = null;
|
||||||
scene._engine._scene.add(this._object3D);
|
const world = scene._engine.world;
|
||||||
|
world.add(this._object3D);
|
||||||
this.layerMesh = null;
|
this.layerMesh = null;
|
||||||
this.layerLineMesh = null;
|
this.layerLineMesh = null;
|
||||||
this._initEvents();
|
this._initEvents();
|
||||||
|
@ -107,8 +108,7 @@ export default class Layer extends Base {
|
||||||
}
|
}
|
||||||
source(data, cfg = {}) {
|
source(data, cfg = {}) {
|
||||||
cfg.data = data;
|
cfg.data = data;
|
||||||
cfg.mapType = this.get('mapType');
|
cfg.mapType = this.scene.mapType;
|
||||||
|
|
||||||
this.layerSource = new source(cfg);
|
this.layerSource = new source(cfg);
|
||||||
// this.scene.workerPool.runTask({
|
// this.scene.workerPool.runTask({
|
||||||
// command: 'geojson',
|
// command: 'geojson',
|
||||||
|
|
|
@ -3,8 +3,8 @@ import { LAYER_MAP } from '../layer';
|
||||||
import Base from './base';
|
import Base from './base';
|
||||||
import LoadImage from './image';
|
import LoadImage from './image';
|
||||||
import WorkerPool from './worker';
|
import WorkerPool from './worker';
|
||||||
import { MapProvider } from '../map/provider';
|
// import { MapProvider } from '../map/AMap';
|
||||||
import GaodeMap from '../map/gaodeMap';
|
import { getMap } from '../map/index';
|
||||||
import Global from '../global';
|
import Global from '../global';
|
||||||
import { compileBuiltinModules } from '../geom/shader';
|
import { compileBuiltinModules } from '../geom/shader';
|
||||||
export default class Scene extends Base {
|
export default class Scene extends Base {
|
||||||
|
@ -31,16 +31,14 @@ export default class Scene extends Base {
|
||||||
}
|
}
|
||||||
_initMap() {
|
_initMap() {
|
||||||
this.mapContainer = this.get('id');
|
this.mapContainer = this.get('id');
|
||||||
this._container = document.getElementById(this.mapContainer);
|
this.mapType = this.get('mapType') || 'amap';
|
||||||
const Map = new MapProvider(this.mapContainer, this._attrs);
|
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', () => {
|
Map.on('mapLoad', () => {
|
||||||
this._initEngine(Map.renderDom);
|
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;
|
this.map = Map.map;
|
||||||
Map.asyncCamera(this._engine);
|
Map.asyncCamera(this._engine);
|
||||||
this.initLayer();
|
this.initLayer();
|
||||||
|
@ -104,6 +102,7 @@ export default class Scene extends Base {
|
||||||
|
|
||||||
this._container.addEventListener(event, e => {
|
this._container.addEventListener(event, e => {
|
||||||
// 要素拾取
|
// 要素拾取
|
||||||
|
e.pixel || (e.pixel = e.point);
|
||||||
this._engine._picking.pickdata(e);
|
this._engine._picking.pickdata(e);
|
||||||
}, false);
|
}, false);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
/*
|
|
||||||
* @Author: ThinkGIS
|
|
||||||
* @Date: 2018-06-08 11:19:06
|
|
||||||
* @Last Modified by: mikey.zhaopeng
|
|
||||||
* @Last Modified time: 2019-02-25 20:58:08
|
|
||||||
*/
|
|
||||||
import Base from './base';
|
import Base from './base';
|
||||||
const Controller = require('./controller/index');
|
const Controller = require('./controller/index');
|
||||||
import { aProjectFlat } from '../geo/project';
|
|
||||||
import { getTransform, getParser } from '../source';
|
import { getTransform, getParser } from '../source';
|
||||||
|
import { getMap } from '../map/index';
|
||||||
export default class Source extends Base {
|
export default class Source extends Base {
|
||||||
getDefaultCfg() {
|
getDefaultCfg() {
|
||||||
return {
|
return {
|
||||||
|
@ -67,6 +62,8 @@ export default class Source extends Base {
|
||||||
}
|
}
|
||||||
_initControllers() {
|
_initControllers() {
|
||||||
const defs = this.get('defs');
|
const defs = this.get('defs');
|
||||||
|
const mapType = this.get('mapType');
|
||||||
|
this.projectFlat = getMap(mapType).project;
|
||||||
const scaleController = new Controller.Scale({
|
const scaleController = new Controller.Scale({
|
||||||
defs
|
defs
|
||||||
});
|
});
|
||||||
|
@ -100,8 +97,8 @@ export default class Source extends Base {
|
||||||
}
|
}
|
||||||
_coorConvert(geo) {
|
_coorConvert(geo) {
|
||||||
|
|
||||||
const ll = aProjectFlat(geo);
|
const ll = this.projectFlat(geo);
|
||||||
return [ ll.x, -ll.y, geo[2] || 0 ];
|
return [ ll.x, ll.y, geo[2] || 0 ];
|
||||||
|
|
||||||
}
|
}
|
||||||
getSelectFeature(featureId) {
|
getSelectFeature(featureId) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ export { Scene } from 'three/src/scenes/Scene.js';
|
||||||
export { WebGLRenderer } from 'three/src/renderers/WebGLRenderer.js';
|
export { WebGLRenderer } from 'three/src/renderers/WebGLRenderer.js';
|
||||||
export { CanvasTexture } from 'three/src/textures/CanvasTexture.js';
|
export { CanvasTexture } from 'three/src/textures/CanvasTexture.js';
|
||||||
export { Object3D } from 'three/src/core/Object3D.js';
|
export { Object3D } from 'three/src/core/Object3D.js';
|
||||||
|
export { Group } from 'three/src/objects/Group';
|
||||||
export { Clock } from 'three/src/core/Clock';
|
export { Clock } from 'three/src/core/Clock';
|
||||||
export { Points } from 'three/src/objects/Points.js';
|
export { Points } from 'three/src/objects/Points.js';
|
||||||
export { LineSegments } from 'three/src/objects/LineSegments.js';
|
export { LineSegments } from 'three/src/objects/LineSegments.js';
|
||||||
|
|
|
@ -15,7 +15,7 @@ varying float v_size;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float scale = pow(2.0,(20.0 - u_zoom));
|
float scale = pow(2.0,(20.0 - u_zoom));
|
||||||
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
|
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix * 100.;
|
||||||
vec3 newposition = position;
|
vec3 newposition = position;
|
||||||
// newposition.x -= 128.0;
|
// newposition.x -= 128.0;
|
||||||
#ifdef SHAPE
|
#ifdef SHAPE
|
||||||
|
|
|
@ -1,18 +1,34 @@
|
||||||
import Base from '../core/base';
|
import Base from '../core/base';
|
||||||
|
import { scene } from '../global';
|
||||||
import * as Theme from '../theme/index';
|
import * as Theme from '../theme/index';
|
||||||
import Util from '../util';
|
import Util from '../util';
|
||||||
import { scene } from '../global';
|
|
||||||
const DEG2RAD = Math.PI / 180;
|
const DEG2RAD = Math.PI / 180;
|
||||||
export class MapProvider extends Base {
|
export default class GaodeMap extends Base {
|
||||||
getDefaultCfg() {
|
getDefaultCfg() {
|
||||||
return Util.assign(scene, {
|
return Util.assign(scene, {
|
||||||
resizeEnable: true,
|
resizeEnable: true,
|
||||||
viewMode: '3D'
|
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);
|
super(cfg);
|
||||||
this.container = container;
|
this.container = this.get('id');
|
||||||
this.initMap();
|
this.initMap();
|
||||||
this.addOverLayer();
|
this.addOverLayer();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -85,4 +101,31 @@ export class MapProvider extends Base {
|
||||||
this.renderDom.id = 'l7_canvaslayer';
|
this.renderDom.id = 'l7_canvaslayer';
|
||||||
canvasContainer.appendChild(this.renderDom);
|
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();
|
return this.map.getStatus();
|
||||||
}
|
}
|
||||||
getScale() {
|
getScale() {
|
||||||
return this.getScale();
|
return this.map.getScale();
|
||||||
}
|
}
|
||||||
setZoom(zoom) {
|
setZoom(zoom) {
|
||||||
return this.map.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;
|
||||||
|
};
|
|
@ -0,0 +1,154 @@
|
||||||
|
import Base from '../core/base';
|
||||||
|
import Util from '../util';
|
||||||
|
import { scene } from '../global';
|
||||||
|
import * as THREE from '../core/three';
|
||||||
|
const WORLD_SIZE = 512;
|
||||||
|
const MERCATOR_A = 6378137.0;
|
||||||
|
const WORLD_SCALE = 1 / 100;
|
||||||
|
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'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
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 = this.get('container');
|
||||||
|
this.initMap();
|
||||||
|
this.addOverLayer();
|
||||||
|
setTimeout(() => {
|
||||||
|
this.emit('mapLoad');
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
const pickScene = engine._picking.world;
|
||||||
|
camera.matrixAutoUpdate = false;
|
||||||
|
scene.position.x = scene.position.y = WORLD_SIZE / 2;
|
||||||
|
scene.matrixAutoUpdate = false;
|
||||||
|
pickScene.position.x = pickScene.position.y = WORLD_SIZE / 2;
|
||||||
|
pickScene.matrixAutoUpdate = false;
|
||||||
|
this.updateCamera();
|
||||||
|
this.map.on('move', () => {
|
||||||
|
this.updateCamera();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updateCamera() {
|
||||||
|
const engine = this.engine;
|
||||||
|
const scene = engine.world;
|
||||||
|
const pickScene = engine._picking.world;
|
||||||
|
const camera = engine._camera;
|
||||||
|
// 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 * WORLD_SCALE;
|
||||||
|
const halfFov = fov / 2;
|
||||||
|
const groundAngle = Math.PI / 2 + this.map.transform._pitch;
|
||||||
|
const topHalfSurfaceDistance = Math.sin(halfFov) * cameraToCenterDistance / Math.sin(Math.PI - groundAngle - halfFov);
|
||||||
|
|
||||||
|
// Calculate z distance of the farthest fragment that should be rendered.
|
||||||
|
const furthestDistance = Math.cos(Math.PI / 2 - this.map.transform._pitch) * topHalfSurfaceDistance + cameraToCenterDistance;
|
||||||
|
|
||||||
|
// Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance`
|
||||||
|
let farZ = furthestDistance * 1.1;
|
||||||
|
if (this.pitch > 50) {
|
||||||
|
farZ = 1000;
|
||||||
|
}
|
||||||
|
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 cameraTranslateXY = new THREE.Matrix4().makeTranslation(x * WORLD_SCALE, -y * WORLD_SCALE, 0);
|
||||||
|
// 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)
|
||||||
|
.premultiply(cameraTranslateXY);
|
||||||
|
|
||||||
|
camera.matrixWorld.copy(cameraWorldMatrix);
|
||||||
|
|
||||||
|
const zoomPow = this.map.transform.scale * WORLD_SCALE;
|
||||||
|
// Handle scaling and translation of objects in the map in the world's matrix transform, not the camera
|
||||||
|
const scale = new THREE.Matrix4();
|
||||||
|
const translateCenter = new THREE.Matrix4();
|
||||||
|
const translateMap = new THREE.Matrix4();
|
||||||
|
const rotateMap = new THREE.Matrix4();
|
||||||
|
scale
|
||||||
|
.makeScale(zoomPow, zoomPow, 1.0);
|
||||||
|
translateCenter
|
||||||
|
.makeTranslation(WORLD_SIZE / 2, -WORLD_SIZE / 2, 0);
|
||||||
|
translateMap
|
||||||
|
.makeTranslation(-this.map.transform.x, this.map.transform.y, 0);
|
||||||
|
rotateMap
|
||||||
|
.makeRotationZ(Math.PI);
|
||||||
|
scene.matrix = new THREE.Matrix4();
|
||||||
|
scene.matrix
|
||||||
|
.premultiply(rotateMap)
|
||||||
|
.premultiply(translateCenter)
|
||||||
|
.premultiply(scale);
|
||||||
|
pickScene.matrix = new THREE.Matrix4();
|
||||||
|
pickScene.matrix
|
||||||
|
.premultiply(rotateMap)
|
||||||
|
.premultiply(translateCenter)
|
||||||
|
.premultiply(scale);
|
||||||
|
}
|
||||||
|
makePerspectiveMatrix(fovy, aspect, near, far) {
|
||||||
|
const out = new THREE.Matrix4();
|
||||||
|
const f = 1.0 / Math.tan(fovy / 2),
|
||||||
|
nf = 1 / (near - far);
|
||||||
|
const newMatrix = [
|
||||||
|
f / aspect, 0, 0, 0,
|
||||||
|
0, f, 0, 0,
|
||||||
|
0, 0, (far + near) * nf, -1,
|
||||||
|
0, 0, (2 * far * near) * nf, 0
|
||||||
|
];
|
||||||
|
out.elements = newMatrix;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
projectFlat(lnglat) {
|
||||||
|
return this.map.lngLatToGeodeticCoord(lnglat);
|
||||||
|
}
|
||||||
|
getCenter() {
|
||||||
|
return this.map.getCenter();
|
||||||
|
}
|
||||||
|
getCenterFlat() {
|
||||||
|
return this.projectFlat(this.getCenter());
|
||||||
|
}
|
||||||
|
addOverLayer() {
|
||||||
|
const canvasContainer = document.getElementById(this.container);
|
||||||
|
this.canvasContainer = canvasContainer;
|
||||||
|
this.renderDom = document.createElement('div');
|
||||||
|
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(); };
|
||||||
|
scene.containerToLngLat = point => { return map.unproject(point); };
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue