mirror of https://gitee.com/antv-l7/antv-l7
Feat map (#1515)
* fix: 多地图模式 * fix: getcustomdata 数据为空 * fix: map 支持 threejs 图层 * fix: lint error * chore: add vercel-build * chore: add vercel.json * chore: add vercel.json
This commit is contained in:
parent
1aa296f931
commit
6f3d043a7b
|
@ -0,0 +1,87 @@
|
|||
// @ts-ignore
|
||||
import { PointLayer, Scene,Popup } from '@antv/l7';
|
||||
// @ts-ignore
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
export default () => {
|
||||
// @ts-ignore
|
||||
useEffect( async () => {
|
||||
const response = await fetch(
|
||||
'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json',
|
||||
);
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new GaodeMap({
|
||||
center: [121.4, 31.258134],
|
||||
zoom: 12,
|
||||
pitch: 0,
|
||||
style: 'normal',
|
||||
doubleClickZoom:false,
|
||||
}),
|
||||
});
|
||||
scene.addImage(
|
||||
'00',
|
||||
'https://gw.alipayobjects.com/mdn/rms_fcd5b3/afts/img/A*g8cUQ7pPT9YAAAAAAAAAAAAAARQnAQ',
|
||||
);
|
||||
scene.addImage(
|
||||
'01',
|
||||
'https://gw.alipayobjects.com/mdn/rms_fcd5b3/afts/img/A*LTcXTLBM7kYAAAAAAAAAAAAAARQnAQ',
|
||||
);
|
||||
scene.addImage(
|
||||
'02',
|
||||
'https://gw.alipayobjects.com/zos/bmw-prod/904d047a-16a5-461b-a921-98fa537fc04a.svg',
|
||||
);
|
||||
const data = await response.json();
|
||||
const newData = data.map((item: any) => {
|
||||
item.type = ['00', '01', '02'][Math.floor(Math.random() * 3)];
|
||||
return item;
|
||||
});
|
||||
const imageLayer = new PointLayer({
|
||||
autoFit:false
|
||||
})
|
||||
.source(newData, {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'longitude',
|
||||
y: 'latitude',
|
||||
},
|
||||
})
|
||||
.shape('type', (v: any) => {
|
||||
return v;
|
||||
})
|
||||
.active(false)
|
||||
.size(20);
|
||||
scene.addLayer(imageLayer);
|
||||
setInterval(()=>{
|
||||
scene.addImage(
|
||||
'00',
|
||||
'https://gw.alipayobjects.com/mdn/rms_fcd5b3/afts/img/A*g8cUQ7pPT9YAAAAAAAAAAAAAARQnAQ',
|
||||
);
|
||||
scene.addImage(
|
||||
'01',
|
||||
'https://gw.alipayobjects.com/mdn/rms_fcd5b3/afts/img/A*LTcXTLBM7kYAAAAAAAAAAAAAARQnAQ',
|
||||
);
|
||||
scene.addImage(
|
||||
'02',
|
||||
'https://gw.alipayobjects.com/zos/bmw-prod/904d047a-16a5-461b-a921-98fa537fc04a.svg',
|
||||
);
|
||||
const data = newData.slice(0,5+ Math.round(Math.random()*10));
|
||||
imageLayer.setData(data)
|
||||
console.log(imageLayer)
|
||||
console.log('更新')
|
||||
},3000)
|
||||
|
||||
|
||||
}, []);
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
height: '500px',
|
||||
position: 'relative',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
### Point - image
|
||||
<code src="./demos/image.tsx"></code>
|
|
@ -0,0 +1,66 @@
|
|||
// @ts-ignore
|
||||
import {
|
||||
LineLayer,
|
||||
Scene,
|
||||
Source,
|
||||
lineAtOffset,
|
||||
lineAtOffsetAsyc,
|
||||
PointLayer,
|
||||
// @ts-ignore
|
||||
} from '@antv/l7';
|
||||
// @ts-ignore
|
||||
import { GaodeMapV1 } from '@antv/l7-maps';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
export default () => {
|
||||
useEffect(() => {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new GaodeMapV1({
|
||||
style: 'light',
|
||||
center: [-96, 37.8],
|
||||
zoom: 3,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
|
||||
});
|
||||
|
||||
const scene2 = new Scene({
|
||||
id: 'map2',
|
||||
map: new GaodeMapV1({
|
||||
style: 'dark',
|
||||
center: [-96, 37.8],
|
||||
zoom: 3,
|
||||
}),
|
||||
});
|
||||
scene2.on('loaded', () => {
|
||||
|
||||
});
|
||||
|
||||
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
float:'left',
|
||||
width:'50%',
|
||||
height: '500px',
|
||||
position: 'relative',
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
id="map2"
|
||||
style={{
|
||||
float:'right',
|
||||
width:'50%',
|
||||
height: '500px',
|
||||
position: 'relative',
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
### multiMap 地图
|
||||
|
||||
<code src="./demos/multiMap.tsx"></code>
|
|
@ -1,7 +1,7 @@
|
|||
### threejs - amap2
|
||||
```tsx
|
||||
import { Scene } from '@antv/l7';
|
||||
import { GaodeMap } from '@antv/l7-maps';
|
||||
import { Scene,RasterLayer } from '@antv/l7';
|
||||
import { GaodeMap, } from '@antv/l7-maps';
|
||||
import React, { useEffect } from 'react';
|
||||
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
|
||||
import * as THREE from 'three';
|
||||
|
@ -20,6 +20,31 @@ export default () => {
|
|||
}),
|
||||
});
|
||||
scene.registerRenderService(ThreeRender);
|
||||
const url1 =
|
||||
'https://tiles{1-3}.geovisearth.com/base/v1/ter/{z}/{x}/{y}?format=webp&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788';
|
||||
const url2 =
|
||||
'https://tiles{1-3}.geovisearth.com/base/v1/cat/{z}/{x}/{y}?format=png&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788';
|
||||
const layer1 = new RasterLayer({
|
||||
zIndex: 1,
|
||||
}).source(url1, {
|
||||
parser: {
|
||||
type: 'rasterTile',
|
||||
tileSize: 256,
|
||||
zoomOffset: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const layer2 = new RasterLayer({
|
||||
zIndex: 1,
|
||||
}).source(url2, {
|
||||
parser: {
|
||||
type: 'rasterTile',
|
||||
tileSize: 256,
|
||||
zoomOffset: 0,
|
||||
},
|
||||
});
|
||||
scene.addLayer(layer1);
|
||||
scene.addLayer(layer2);
|
||||
scene.on('loaded', () => {
|
||||
const threeJSLayer = new ThreeLayer({
|
||||
enableMultiPassRenderer: false,
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
### threejs - Map
|
||||
|
||||
```tsx
|
||||
import { Scene, RasterLayer } from '@antv/l7';
|
||||
import { Map } from '@antv/l7-maps';
|
||||
import React, { useEffect } from 'react';
|
||||
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
|
||||
import * as THREE from 'three';
|
||||
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||
import { animate, easeInOut } from 'popmotion';
|
||||
|
||||
export default () => {
|
||||
useEffect(() => {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Map({
|
||||
center: [111.4453125, 32.84267363195431],
|
||||
pitch: 45,
|
||||
rotation: 30,
|
||||
zoom: 12,
|
||||
token:
|
||||
'pk.eyJ1IjoiMTg5Njk5NDg2MTkiLCJhIjoiY2w3dHk3dnN4MDYzaDNycDkyMDl2bzh6NiJ9.YIrG9kwUpayLj01f6W23Gw',
|
||||
}),
|
||||
});
|
||||
|
||||
scene.on('loaded', () => {
|
||||
scene.registerRenderService(ThreeRender);
|
||||
const url1 =
|
||||
'https://tiles{1-3}.geovisearth.com/base/v1/ter/{z}/{x}/{y}?format=webp&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788';
|
||||
const url2 =
|
||||
'https://tiles{1-3}.geovisearth.com/base/v1/cat/{z}/{x}/{y}?format=png&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788';
|
||||
const layer1 = new RasterLayer({
|
||||
zIndex: 1,
|
||||
}).source(url1, {
|
||||
parser: {
|
||||
type: 'rasterTile',
|
||||
tileSize: 256,
|
||||
zoomOffset: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const layer2 = new RasterLayer({
|
||||
zIndex: 1,
|
||||
}).source(url2, {
|
||||
parser: {
|
||||
type: 'rasterTile',
|
||||
tileSize: 256,
|
||||
zoomOffset: 0,
|
||||
},
|
||||
});
|
||||
scene.addLayer(layer1);
|
||||
scene.addLayer(layer2);
|
||||
const threeJSLayer = new ThreeLayer({
|
||||
enableMultiPassRenderer: false,
|
||||
onAddMeshes: (threeScene, layer) => {
|
||||
threeScene.add(new THREE.AmbientLight(0xffffff));
|
||||
const sunlight = new THREE.DirectionalLight(0xffffff, 0.25);
|
||||
sunlight.position.set(0, 80000000, 100000000);
|
||||
sunlight.matrixWorldNeedsUpdate = true;
|
||||
threeScene.add(sunlight);
|
||||
|
||||
const center = scene.getCenter();
|
||||
|
||||
const cubeGeometry = new THREE.BoxBufferGeometry(10000, 10000, 10000);
|
||||
const cubeMaterial = new THREE.MeshNormalMaterial({
|
||||
side: THREE.DoubleSide,
|
||||
});
|
||||
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
|
||||
layer.setObjectLngLat(cube, [center.lng + 0.05, center.lat], 0);
|
||||
threeScene.add(cube);
|
||||
|
||||
// 使用 Three.js glTFLoader 加载模型
|
||||
const loader = new GLTFLoader();
|
||||
loader.load(
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/3ca0a546-92d8-4ba0-a89c-017c218d5bea.gltf',
|
||||
(gltf) => {
|
||||
const gltfScene = gltf.scene;
|
||||
setDouble(gltfScene);
|
||||
layer.adjustMeshToMap(gltfScene);
|
||||
// gltfScene.scale.set(1000, 1000, 1000)
|
||||
layer.setMeshScale(gltfScene, 100, 100, 100);
|
||||
|
||||
layer.setObjectLngLat(gltfScene, [center.lng, center.lat], 0);
|
||||
|
||||
const animations = gltf.animations;
|
||||
if (animations && animations.length) {
|
||||
const mixer = new THREE.AnimationMixer(gltfScene);
|
||||
|
||||
const animation = animations[2];
|
||||
|
||||
const action = mixer.clipAction(animation);
|
||||
|
||||
action.play();
|
||||
layer.addAnimateMixer(mixer);
|
||||
}
|
||||
let t = 0;
|
||||
setInterval(() => {
|
||||
t += 0.01;
|
||||
layer.setObjectLngLat(
|
||||
gltfScene,
|
||||
[center.lng, center.lat + Math.sin(t) * 0.1],
|
||||
0,
|
||||
);
|
||||
}, 16);
|
||||
|
||||
// 向场景中添加模型
|
||||
threeScene.add(gltfScene);
|
||||
// 重绘图层
|
||||
layer.render();
|
||||
},
|
||||
);
|
||||
},
|
||||
}).animate(true);
|
||||
scene.addLayer(threeJSLayer);
|
||||
});
|
||||
|
||||
function setDouble(object) {
|
||||
if (
|
||||
object.children &&
|
||||
object.children.length &&
|
||||
object.children.length > 0
|
||||
) {
|
||||
object.children.map((child) => setDouble(child));
|
||||
} else if (object.material) {
|
||||
object.material.side = THREE.DoubleSide;
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
height: '500px',
|
||||
position: 'relative',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
|
@ -16,7 +16,7 @@ export default () => {
|
|||
center: [127.471855, 46.509622], // 绥化市-北林区
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 10,
|
||||
zoom: 7,
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
"lint:css": "stylelint 'packages/**/src/**/*.js{,x}'",
|
||||
"lint": "run-p -c lint:*",
|
||||
"commit": "git-cz",
|
||||
"vercel-build": "yarn global add node-gyp",
|
||||
"version": "lerna version --force-publish --conventional-commits --exact --no-changelog",
|
||||
"version:prerelease": "lerna version --force-publish --exact --conventional-prerelease",
|
||||
"prerelease": "yarn build && yarn bundle",
|
||||
|
|
|
@ -18,6 +18,9 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
|
|||
|
||||
public async buildModels() {
|
||||
const modelType = this.getModelType();
|
||||
if (this.layerModel) {
|
||||
this.layerModel.clearModels();
|
||||
}
|
||||
this.layerModel = new PointModels[modelType](this);
|
||||
await this.initLayerModels();
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import pointImageFrag from '../shaders/image_frag.glsl';
|
|||
import pointImageVert from '../shaders/image_vert.glsl';
|
||||
export default class ImageModel extends BaseModel {
|
||||
private texture: ITexture2D;
|
||||
|
||||
public getUninforms(): IModelUniform {
|
||||
const {
|
||||
opacity = 1,
|
||||
|
@ -81,10 +80,8 @@ export default class ImageModel extends BaseModel {
|
|||
};
|
||||
}
|
||||
|
||||
public async initModels():Promise<IModel[]> {
|
||||
this.iconService.off('imageUpdate', this.updateTexture);
|
||||
public async initModels(): Promise<IModel[]> {
|
||||
this.iconService.on('imageUpdate', this.updateTexture);
|
||||
// this.registerBuiltinAttributes();
|
||||
this.updateTexture();
|
||||
|
||||
return await this.buildModels();
|
||||
|
@ -96,7 +93,7 @@ export default class ImageModel extends BaseModel {
|
|||
this.iconService.off('imageUpdate', this.updateTexture);
|
||||
}
|
||||
|
||||
public async buildModels():Promise<IModel[]> {
|
||||
public async buildModels(): Promise<IModel[]> {
|
||||
const {
|
||||
mask = false,
|
||||
maskInside = true,
|
||||
|
@ -176,7 +173,7 @@ export default class ImageModel extends BaseModel {
|
|||
});
|
||||
// 更新完纹理后在更新的图层的时候需要更新所有的图层
|
||||
// this.layer.layerModelNeedUpdate = true;
|
||||
setTimeout(()=>{ // 延迟渲染
|
||||
setTimeout(() => { // 延迟渲染
|
||||
this.layerService.throttleRenderLayers();
|
||||
})
|
||||
|
||||
|
|
|
@ -180,10 +180,7 @@ export default class TextModel extends BaseModel {
|
|||
public async initModels():Promise<IModel[]> {
|
||||
|
||||
// 绑定事件
|
||||
if(!this.layer.inited) {
|
||||
this.bindEvent();
|
||||
}
|
||||
|
||||
this.extent = this.textExtent();
|
||||
const {
|
||||
textAnchor = 'center',
|
||||
|
|
|
@ -89,3 +89,5 @@ export default class MercatorCoordinate {
|
|||
return (1 / earthCircumfrence) * mercatorScale(latFromMercatorY(this.y));
|
||||
}
|
||||
}
|
||||
|
||||
export { MercatorCoordinate };
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from './map';
|
||||
export * from './earthmap';
|
||||
export * from './geo/mercator';
|
||||
export * from './interface';
|
|
@ -12,10 +12,9 @@ import { mat4, vec3 } from 'gl-matrix';
|
|||
import { injectable } from 'inversify';
|
||||
import 'reflect-metadata';
|
||||
import { IAMapEvent, IAMapInstance } from '../../typings/index';
|
||||
import AMapBaseService from '../utils/amap/AMapBaseService';
|
||||
import AMapLoader from '../utils/amaploader';
|
||||
import { Version } from '../version';
|
||||
|
||||
import AMapBaseService from '../utils/amap/AMapBaseService';
|
||||
import Viewport from './Viewport';
|
||||
// @ts-ignore
|
||||
window.forceWebGL = true;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* AMapService
|
||||
*/
|
||||
import AMapLoader from '../utils/amaploader';
|
||||
import AMapLoader from '@amap/amap-jsapi-loader';
|
||||
|
||||
import {
|
||||
Bounds,
|
||||
|
@ -246,6 +246,7 @@ export default class AMapService extends AMapBaseService {
|
|||
this.viewport = new Viewport();
|
||||
if (!(window.AMap || mapInstance)) {
|
||||
plugin.push('Map3D');
|
||||
// if (AMapLoader.status.AMap === 'notload') {
|
||||
await AMapLoader.load({
|
||||
key: token, // 申请好的Web端开发者Key,首次调用 load 时必填
|
||||
version: AMAP_VERSION, // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
* MapboxService
|
||||
*/
|
||||
import { CoordinateSystem, IMercator } from '@antv/l7-core';
|
||||
import { Map } from '@antv/l7-map';
|
||||
import { Map, MercatorCoordinate } from '@antv/l7-map';
|
||||
import { $window } from '@antv/l7-utils';
|
||||
import { mat4, vec3 } from 'gl-matrix';
|
||||
import { injectable } from 'inversify';
|
||||
import 'reflect-metadata';
|
||||
import BaseMapService from '../utils/BaseMapService';
|
||||
|
@ -18,15 +19,69 @@ const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12;
|
|||
@injectable()
|
||||
export default class DefaultMapService extends BaseMapService<Map> {
|
||||
public version: string = Version.DEFUALT;
|
||||
/**
|
||||
* 将经纬度转成墨卡托坐标
|
||||
* @param lnglat
|
||||
* @returns
|
||||
*/
|
||||
public lngLatToCoord(
|
||||
lnglat: [number, number],
|
||||
origin: IMercator = { x: 0, y: 0, z: 0 },
|
||||
) {
|
||||
// @ts-ignore
|
||||
const { x, y } = this.lngLatToMercator(lnglat, 0);
|
||||
return [x - origin.x, y - origin.y] as [number, number];
|
||||
}
|
||||
|
||||
public lngLatToMercator(
|
||||
lnglat: [number, number],
|
||||
altitude: number,
|
||||
): IMercator {
|
||||
throw new Error('Method not implemented.');
|
||||
const {
|
||||
x = 0,
|
||||
y = 0,
|
||||
z = 0,
|
||||
} = MercatorCoordinate.fromLngLat(lnglat, altitude);
|
||||
return { x, y, z };
|
||||
}
|
||||
public getModelMatrix(): number[] {
|
||||
throw new Error('Method not implemented.');
|
||||
public getModelMatrix(
|
||||
lnglat: [number, number],
|
||||
altitude: number,
|
||||
rotate: [number, number, number],
|
||||
scale: [number, number, number] = [1, 1, 1],
|
||||
origin: IMercator = { x: 0, y: 0, z: 0 },
|
||||
): number[] {
|
||||
const modelAsMercatorCoordinate = MercatorCoordinate.fromLngLat(
|
||||
lnglat,
|
||||
altitude,
|
||||
);
|
||||
// @ts-ignore
|
||||
const meters = modelAsMercatorCoordinate.meterInMercatorCoordinateUnits();
|
||||
const modelMatrix = mat4.create();
|
||||
|
||||
mat4.translate(
|
||||
modelMatrix,
|
||||
modelMatrix,
|
||||
vec3.fromValues(
|
||||
modelAsMercatorCoordinate.x - origin.x,
|
||||
modelAsMercatorCoordinate.y - origin.y,
|
||||
modelAsMercatorCoordinate.z || 0 - origin.z,
|
||||
),
|
||||
);
|
||||
|
||||
mat4.scale(
|
||||
modelMatrix,
|
||||
modelMatrix,
|
||||
vec3.fromValues(meters * scale[0], -meters * scale[1], meters * scale[2]),
|
||||
);
|
||||
|
||||
mat4.rotateX(modelMatrix, modelMatrix, rotate[0]);
|
||||
mat4.rotateY(modelMatrix, modelMatrix, rotate[1]);
|
||||
mat4.rotateZ(modelMatrix, modelMatrix, rotate[2]);
|
||||
|
||||
return modelMatrix as unknown as number[];
|
||||
}
|
||||
|
||||
public viewport: Viewport;
|
||||
|
||||
public async init(): Promise<void> {
|
||||
|
|
|
@ -17,8 +17,10 @@ export const getCustomData = async (
|
|||
y: tile.y,
|
||||
z: tile.z
|
||||
}, (err, data) => {
|
||||
if(err){
|
||||
|
||||
if(err || data.length ===0){
|
||||
reject(err)
|
||||
return;
|
||||
}
|
||||
if (data) {
|
||||
processRasterData([{data,bands:[0]}], rasterFormat, operation, (err: any, img: any) => {
|
||||
|
|
|
@ -82,6 +82,8 @@ export class ThreeRenderService implements IThreeRenderService {
|
|||
return this.AMap2Camera();
|
||||
case 'MAPBOX':
|
||||
return this.mapboxCamera();
|
||||
case 'DEFAULTMAP':
|
||||
return this.mapboxCamera();
|
||||
default:
|
||||
return this.AMapCamera();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{
|
||||
"src": "package.json",
|
||||
"use": "@vercel/node"
|
||||
},
|
||||
{
|
||||
"src": "nuxt.config.js",
|
||||
"use": "@nuxtjs/vercel-builder",
|
||||
"config": {
|
||||
"serverFiles": ["server-middleware/**"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue