feat: 支持动态配置坐标原点 (#1124)

* fix: 修复 mouseup 失效

* feat: 高德2 支持动态配置坐标原点

* style: lint style

* feat: 提取高德 2.0 投影方法

* style: lint style

* chore: change parameter name
This commit is contained in:
YiQianYao 2022-05-25 18:50:54 +08:00 committed by GitHub
parent 00072e2d9d
commit 6f6396f0cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 165 additions and 155 deletions

View File

@ -61,6 +61,7 @@ export type IJsonData = IJsonItem[];
export interface ISource {
data: IParserData;
center: [number, number];
parser: IParserCfg;
transforms: ITransform[];
cluster: boolean;

View File

@ -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) => {

View File

@ -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;
}
}

View File

@ -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);
}
/**

View File

@ -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];
}
/**
*
*/

View File

@ -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],

View File

@ -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);
});
}