mirror of https://gitee.com/antv-l7/antv-l7
feat: 支持动态配置坐标原点 (#1124)
* fix: 修复 mouseup 失效 * feat: 高德2 支持动态配置坐标原点 * style: lint style * feat: 提取高德 2.0 投影方法 * style: lint style * chore: change parameter name
This commit is contained in:
parent
00072e2d9d
commit
6f6396f0cd
|
@ -61,6 +61,7 @@ export type IJsonData = IJsonItem[];
|
|||
|
||||
export interface ISource {
|
||||
data: IParserData;
|
||||
center: [number, number];
|
||||
parser: IParserCfg;
|
||||
transforms: ITransform[];
|
||||
cluster: boolean;
|
||||
|
|
|
@ -73,17 +73,17 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
// 过滤数据
|
||||
if (filter?.needRemapping) {
|
||||
layer.setEncodedData(
|
||||
this.mapping(attributes, filterData, undefined, bottomColor, layer),
|
||||
this.mapping(layer, attributes, filterData, undefined, bottomColor),
|
||||
);
|
||||
filter.needRemapping = false;
|
||||
} else {
|
||||
layer.setEncodedData(
|
||||
this.mapping(
|
||||
layer,
|
||||
attributesToRemapping,
|
||||
filterData,
|
||||
layer.getEncodedData(),
|
||||
bottomColor,
|
||||
layer,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
});
|
||||
}
|
||||
layer.setEncodedData(
|
||||
this.mapping(attributes, filterData, undefined, bottomColor, layer),
|
||||
this.mapping(layer, attributes, filterData, undefined, bottomColor),
|
||||
);
|
||||
// 对外暴露事件
|
||||
layer.emit('dataUpdate', null);
|
||||
|
@ -127,17 +127,17 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
}
|
||||
|
||||
private mapping(
|
||||
layer: ILayer,
|
||||
attributes: IStyleAttribute[],
|
||||
data: IParseDataItem[],
|
||||
predata?: IEncodeFeature[],
|
||||
minimumColor?: string,
|
||||
layer?: ILayer,
|
||||
): IEncodeFeature[] {
|
||||
const {
|
||||
arrow = {
|
||||
enable: false,
|
||||
},
|
||||
} = layer?.getLayerConfig() as ILineLayerStyleOptions;
|
||||
} = layer.getLayerConfig() as ILineLayerStyleOptions;
|
||||
const mappedData = data.map((record: IParseDataItem, i) => {
|
||||
const preRecord = predata ? predata[i] : {};
|
||||
const encodeRecord: IEncodeFeature = {
|
||||
|
@ -187,7 +187,7 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
// console.log('mappedData', mappedData)
|
||||
|
||||
// 调整数据兼容 Amap2.0
|
||||
this.adjustData2Amap2Coordinates(mappedData);
|
||||
this.adjustData2Amap2Coordinates(mappedData, layer);
|
||||
|
||||
// 调整数据兼容 SimpleCoordinates
|
||||
this.adjustData2SimpleCoordinates(mappedData);
|
||||
|
@ -195,12 +195,16 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
return mappedData;
|
||||
}
|
||||
|
||||
private adjustData2Amap2Coordinates(mappedData: IEncodeFeature[]) {
|
||||
private adjustData2Amap2Coordinates(
|
||||
mappedData: IEncodeFeature[],
|
||||
layer: ILayer,
|
||||
) {
|
||||
// 根据地图的类型判断是否需要对点位数据进行处理, 若是高德2.0则需要对坐标进行相对偏移
|
||||
if (
|
||||
mappedData.length > 0 &&
|
||||
this.mapService.version === Version['GAODE2.x']
|
||||
) {
|
||||
const layerCenter = this.getLayerCenter(layer);
|
||||
if (typeof mappedData[0].coordinates[0] === 'number') {
|
||||
// 单个的点数据
|
||||
// @ts-ignore
|
||||
|
@ -212,7 +216,11 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
// @ts-ignore
|
||||
d.originCoordinates = cloneDeep(d.coordinates); // 为了兼容高德1.x 需要保存一份原始的经纬度坐标数据(许多上层逻辑依赖经纬度数据)
|
||||
// @ts-ignore
|
||||
d.coordinates = this.mapService.lngLatToCoord(d.coordinates);
|
||||
// d.coordinates = this.mapService.lngLatToCoord(d.coordinates);
|
||||
d.coordinates = this.mapService.lngLatToCoordByLayer(
|
||||
d.coordinates,
|
||||
layerCenter,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// 连续的线、面数据
|
||||
|
@ -225,12 +233,21 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
// @ts-ignore
|
||||
d.originCoordinates = cloneDeep(d.coordinates); // 为了兼容高德1.x 需要保存一份原始的经纬度坐标数据(许多上层逻辑依赖经纬度数据)
|
||||
// @ts-ignore
|
||||
d.coordinates = this.mapService.lngLatToCoords(d.coordinates);
|
||||
// d.coordinates = this.mapService.lngLatToCoords(d.coordinates);
|
||||
d.coordinates = this.mapService.lngLatToCoordsByLayer(
|
||||
d.coordinates,
|
||||
layerCenter,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getLayerCenter(layer: ILayer) {
|
||||
const source = layer.getSource();
|
||||
return source.center;
|
||||
}
|
||||
|
||||
private adjustData2SimpleCoordinates(mappedData: IEncodeFeature[]) {
|
||||
if (mappedData.length > 0 && this.mapService.version === Version.SIMPLE) {
|
||||
mappedData.map((d) => {
|
||||
|
|
|
@ -44,6 +44,11 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
|
|||
this.coordinateSystemService.refresh();
|
||||
|
||||
if (version === 'GAODE2.x') {
|
||||
const layerCenter = this.getLayerCenter(layer);
|
||||
// @ts-ignore
|
||||
this.mapService.map.customCoords.setCenter(layerCenter);
|
||||
// @ts-ignore
|
||||
this.mapService.setCustomCoordCenter(layerCenter);
|
||||
// @ts-ignore
|
||||
mvp = this.mapService.map.customCoords.getMVPMatrix();
|
||||
// mvp = amapCustomCoords.getMVPMatrix()
|
||||
|
@ -86,4 +91,9 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
|
|||
// TODO:脏检查,决定是否需要渲染
|
||||
});
|
||||
}
|
||||
|
||||
private getLayerCenter(layer: ILayer) {
|
||||
const source = layer.getSource();
|
||||
return source.center;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
Point,
|
||||
TYPES,
|
||||
} from '@antv/l7-core';
|
||||
import { DOM } from '@antv/l7-utils';
|
||||
import { amap2Project, DOM } from '@antv/l7-utils';
|
||||
import { mat4, vec2, vec3 } from 'gl-matrix';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import 'reflect-metadata';
|
||||
|
@ -102,30 +102,55 @@ export default class AMapService
|
|||
*/
|
||||
public setCustomCoordCenter(center: [number, number]) {
|
||||
this.sceneCenter = center;
|
||||
// @ts-ignore
|
||||
this.sceneCenterMKT = this.map
|
||||
// @ts-ignore
|
||||
.getProjection()
|
||||
.project(...this.sceneCenter);
|
||||
this.sceneCenterMKT = amap2Project(...center);
|
||||
}
|
||||
|
||||
public getCustomCoordCenter(): [number, number] {
|
||||
return this.sceneCenterMKT;
|
||||
}
|
||||
|
||||
public lngLatToCoordByLayer(
|
||||
lnglat: [number, number],
|
||||
layerCenter: [number, number],
|
||||
) {
|
||||
const layerCenterFlat = amap2Project(...layerCenter);
|
||||
return this._sub(amap2Project(lnglat[0], lnglat[1]), layerCenterFlat);
|
||||
}
|
||||
|
||||
public lngLatToCoordsByLayer(
|
||||
lnglatArray: number[][][] | number[][],
|
||||
layerCenter: [number, number],
|
||||
): number[][][] | number[][] {
|
||||
// @ts-ignore
|
||||
return lnglatArray.map((lnglats) => {
|
||||
if (typeof lnglats[0] === 'number') {
|
||||
return this.lngLatToCoordByLayer(
|
||||
lnglats as [number, number],
|
||||
layerCenter,
|
||||
);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
return lnglats.map((lnglat) => {
|
||||
return this.lngLatToCoordByLayer(
|
||||
lnglat as [number, number],
|
||||
layerCenter,
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据数据的绘制中心转换经纬度数据 高德2.0
|
||||
*/
|
||||
public lngLatToCoord(lnglat: [number, number]) {
|
||||
// @ts-ignore
|
||||
const proj = this.map.getProjection();
|
||||
const project = proj.project;
|
||||
// 单点
|
||||
if (!this.sceneCenter) {
|
||||
// @ts-ignore
|
||||
this.map.customCoords.setCenter(lnglat);
|
||||
this.setCustomCoordCenter(lnglat);
|
||||
}
|
||||
return this._sub(project(lnglat[0], lnglat[1]), this.sceneCenterMKT);
|
||||
return this._sub(amap2Project(lnglat[0], lnglat[1]), this.sceneCenterMKT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,7 +35,7 @@ function mergeCustomizer(objValue: any, srcValue: any) {
|
|||
|
||||
export default class Source extends EventEmitter implements ISource {
|
||||
public data: IParserData;
|
||||
|
||||
public center: [number, number];
|
||||
// 数据范围
|
||||
public extent: BBox;
|
||||
// 生命周期钩子
|
||||
|
@ -235,12 +235,17 @@ export default class Source extends EventEmitter implements ISource {
|
|||
this.data = sourceParser(this.originData, parser);
|
||||
// 计算范围
|
||||
this.extent = extent(this.data.dataArray);
|
||||
this.setCenter(this.extent);
|
||||
this.invalidExtent =
|
||||
this.extent[0] === this.extent[2] || this.extent[1] === this.extent[3];
|
||||
// 瓦片数据
|
||||
this.tileset = this.initTileset();
|
||||
}
|
||||
|
||||
private setCenter(bbox: BBox) {
|
||||
this.center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2];
|
||||
}
|
||||
|
||||
/**
|
||||
* 瓦片数据管理器
|
||||
*/
|
||||
|
|
|
@ -186,6 +186,19 @@ export function unProjectFlat(px: number[]): [number, number] {
|
|||
const lng = x / d;
|
||||
return [lng, lat];
|
||||
}
|
||||
|
||||
export function amap2Project(lng: number, lat: number): [number, number] {
|
||||
const r = 85.0511287798;
|
||||
const Rg = Math.PI / 180;
|
||||
const Tg = 6378137;
|
||||
|
||||
lat = Math.max(Math.min(r, lat), -r);
|
||||
lng *= Rg;
|
||||
lat *= Rg;
|
||||
lat = Math.log(Math.tan(Math.PI / 4 + lat / 2));
|
||||
return [lng * Tg, lat * Tg];
|
||||
}
|
||||
|
||||
export function lnglatDistance(
|
||||
coordinates1: [number, number],
|
||||
coordinates2: [number, number],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { PointLayer, Scene } from '@antv/l7';
|
||||
import { PointLayer, Scene, LineLayer } from '@antv/l7';
|
||||
import { GaodeMapV2 } from '@antv/l7-maps';
|
||||
import * as React from 'react';
|
||||
export default class Amap2demo extends React.Component {
|
||||
|
@ -13,147 +13,86 @@ export default class Amap2demo extends React.Component {
|
|||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new GaodeMapV2({
|
||||
center: [121.107846, 30.267069],
|
||||
// center: [121.107846, 30.267069],
|
||||
center: [120.692587367181758, 30.377451929339649],
|
||||
pitch: 0,
|
||||
style: 'normal',
|
||||
zoom: 20,
|
||||
animateEnable: false,
|
||||
zooms: [0, 23],
|
||||
}),
|
||||
});
|
||||
let originData = [
|
||||
{
|
||||
lng: 121.107846,
|
||||
lat: 30.267069,
|
||||
opacity2: 0.2,
|
||||
strokeOpacity2: 0.4,
|
||||
strokeColor: '#000',
|
||||
strokeWidth: 0.5,
|
||||
// offsets2: [0, 0]
|
||||
offsets2: [100, 100],
|
||||
},
|
||||
{
|
||||
lng: 121.107,
|
||||
lat: 30.267069,
|
||||
opacity2: 0.4,
|
||||
strokeOpacity2: 0.6,
|
||||
strokeColor: '#0f0',
|
||||
strokeWidth: 2,
|
||||
offsets2: [100, 100],
|
||||
},
|
||||
{
|
||||
lng: 121.107846,
|
||||
lat: 30.26718,
|
||||
opacity2: 0.6,
|
||||
strokeOpacity2: 0.8,
|
||||
strokeColor: '#f00',
|
||||
strokeWidth: 4,
|
||||
// offsets2: [200, 200]
|
||||
offsets2: [100, 100],
|
||||
},
|
||||
// {
|
||||
// lng: 38.54,
|
||||
// lat: 77.02,
|
||||
// opacity: 0.5
|
||||
// strokeColor: "#ff0"
|
||||
// },
|
||||
];
|
||||
this.scene = scene;
|
||||
// https://gw-office.alipayobjects.com/bmw-prod/61c3fca0-2991-48b4-bb6d-ecc2cbd682dd.json // 100 * 100
|
||||
let hunredMhunred =
|
||||
'https://gw-office.alipayobjects.com/bmw-prod/61c3fca0-2991-48b4-bb6d-ecc2cbd682dd.json';
|
||||
// https://gw-office.alipayobjects.com/bmw-prod/ccc91465-d3ea-4eda-a178-7c1815dac32b.json // 1000 * 100
|
||||
let thousandMhundred =
|
||||
'https://gw-office.alipayobjects.com/bmw-prod/ccc91465-d3ea-4eda-a178-7c1815dac32b.json';
|
||||
let data = {
|
||||
type: 'FeatureCollection',
|
||||
features: [
|
||||
{
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[122.692587367181758, 43.377451929339649],
|
||||
[122.692587367181758, 43.377465856847415],
|
||||
[122.692574277855613, 43.377465856847415],
|
||||
[122.692574277855613, 43.377451929339649],
|
||||
[122.692587367181758, 43.377451929339649],
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
// let cut = 0.0002;
|
||||
let data2 = {
|
||||
type: 'FeatureCollection',
|
||||
features: [
|
||||
{
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[120.692587367181758, 30.377451929339649],
|
||||
[120.692587367181758, 30.377465856847415],
|
||||
[120.692574277855613, 30.377465856847415],
|
||||
[120.692574277855613, 30.377451929339649],
|
||||
[120.692587367181758, 30.377451929339649],
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
scene.on('loaded', () => {
|
||||
for (let i = 0; i < 1; i++) {
|
||||
// fetch(thousandMhundred)
|
||||
// .then((res) => res.text())
|
||||
// .then((data) => {
|
||||
// // console.log('data', data)
|
||||
// // lng: Math.random() * 180, // 0 ~ 180
|
||||
// // lat: Math.random() * 100 - 50, // -50 ~ 50
|
||||
// // customOpacity: Math.random(),
|
||||
// // customStroke: `rgb(${Math.random()*255}, ${Math.random()*255}, ${Math.random()*255}, 1)`,
|
||||
// // customStrokeOpacity: Math.random(),
|
||||
// // customStrokeWidth: Math.random() * 5,
|
||||
// let layer = new PointLayer()
|
||||
// .source(JSON.parse(data), {
|
||||
// parser: {
|
||||
// type: 'json',
|
||||
// x: 'lng',
|
||||
// y: 'lat',
|
||||
// },
|
||||
// })
|
||||
// .shape('circle')
|
||||
// .color('rgba(255, 0, 0, 1.0)')
|
||||
// .size(10)
|
||||
// .style({
|
||||
// opacity: 'customOpacity',
|
||||
// // strokeOpacity: 'customStrokeOpacity',
|
||||
// // strokeWidth: 'customStrokeWidth',
|
||||
// // stroke: 'customStroke',
|
||||
// });
|
||||
// scene.addLayer(layer);
|
||||
// });
|
||||
let layer = new PointLayer()
|
||||
.source(originData, {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
})
|
||||
.shape('circle')
|
||||
// .shape('normal')
|
||||
// .color('rgba(255, 0, 0, 0.9)')
|
||||
// .shape('cylinder')
|
||||
.color('rgba(255, 0, 0, 1.0)')
|
||||
// .size(10)
|
||||
.size([10, 10, 100])
|
||||
// .offsets('123')
|
||||
.style({
|
||||
// stroke: '#000',
|
||||
// stroke: 'rgba(0, 255, 0, 1)',
|
||||
// stroke: 'strokeColor',
|
||||
// stroke: ['strokeColor', (d: any) => {
|
||||
// return d
|
||||
// }],
|
||||
// stroke: ['strokeColor', ["#f00", "#ff0"]],
|
||||
|
||||
strokeWidth: 4,
|
||||
// strokeWidth: "strokeWidth",
|
||||
// strokeWidth: ["strokeWidth", [1, 2]],
|
||||
// strokeWidth: ["strokeWidth", (d: any) => {
|
||||
// return d * 2
|
||||
// }],
|
||||
|
||||
// strokeOpacity: 0.5,
|
||||
// strokeOpacity: 'strokeOpacity2',
|
||||
// strokeOpacity: 1.0,
|
||||
// strokeOpacity: [
|
||||
// 'strokeOpacity2',
|
||||
// (d: any) => {
|
||||
// // console.log('strokeOpacity2', d)
|
||||
// return d*2;
|
||||
// },
|
||||
// ],
|
||||
// strokeOpacity: ['opacity2', [0.2, 0.6]],
|
||||
|
||||
// offsets: [100, 100],
|
||||
// offsets: 'offsets2',
|
||||
// offsets: ['offsets2', (d: any) => d],
|
||||
|
||||
opacity: 'opacity2',
|
||||
// opacity: 0.2
|
||||
// opacity: 0,
|
||||
// opacity: ['opacity2', (d: any) => {
|
||||
// return d
|
||||
// }]
|
||||
// opacity: ['opacity2', [0.2, 0.6]],
|
||||
})
|
||||
.active(true);
|
||||
scene.addLayer(layer);
|
||||
}
|
||||
let rect = new LineLayer()
|
||||
.source(data)
|
||||
.shape('line')
|
||||
.size(2)
|
||||
.color('#f00');
|
||||
scene.addLayer(rect);
|
||||
let rect2 = new LineLayer()
|
||||
.source(data2)
|
||||
.shape('line')
|
||||
.size(2)
|
||||
.color('#f00');
|
||||
scene.addLayer(rect2);
|
||||
const mapService = scene.getMapService();
|
||||
// setTimeout(() => {
|
||||
// scene.setCenter([122.692587367181758, 43.377451929339649]);
|
||||
// // // @ts-ignore
|
||||
// // mapService.map.customCoords?.setCenter([
|
||||
// // 122.692587367181758,
|
||||
// // 43.377451929339649,
|
||||
// // ]);
|
||||
// // // @ts-ignore
|
||||
// // mapService.setCustomCoordCenter([
|
||||
// // 122.692587367181758,
|
||||
// // 43.377451929339649,
|
||||
// // ]);
|
||||
// // rect.dataState.dataSourceNeedUpdate = true;
|
||||
// }, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue