@orca-fe/x-map
Version:
300 lines (299 loc) • 12.8 kB
JavaScript
import { __awaiter } from "tslib";
import { RepeatWrapping, Shape, ShapeBufferGeometry, TextureLoader, Vector2 } from 'three';
import Map from './core/Map';
import BaseLayer from './layers/BaseLayer';
import PointMarker from './layers/markers/PointMarker';
import ThreeLayer from './layers/ThreeLayer';
import SvgLayer from './layers/SvgLayer';
import SvgPolyline from './layers/svg/SvgPolyline';
import SvgArcLine from './layers/svg/SvgArcLine';
import AMapInstance from './instance/AMapInstance';
import loadScript from './utils/load-script';
import MapBoxGLInstance from './instance/MapBoxGLInstance';
import BuildingObject from './layers/markers/BuildingObject';
import PolygonObject from './layers/markers/PolygonObject';
import ThreeHeatmapLayer from './layers/ThreeHeatmapLayer';
import heatmapData from './gaode-heatmap-data';
import TextureObject from './layers/markers/TextureObject';
import { lonLat2Mercator, mercator2LonLat } from './utils/coord';
import IconObject from './layers/markers/IconObject';
(function () {
return __awaiter(this, void 0, void 0, function* () {
const mapDom = document.getElementById('map');
const viewport = {
center: [113.042363, 23.09061],
lng: 113.042363,
lat: 23.09061,
pitch: 0,
rotate: 0,
zoom: 10,
};
if (mapDom) {
const gaode = false;
let instance;
if (gaode) {
yield loadScript('http://webapi.amap.com/maps?v=1.4.15&key=fc4ade9c195bc7ff4f45f5b90c438328');
instance = new AMapInstance();
}
else {
instance = new MapBoxGLInstance({
style: 'mapbox://styles/nicokam/ckrwwvr9345rb17qk4aezrmnv',
accessToken: 'pk.eyJ1Ijoibmljb2thbSIsImEiOiJjazA3dWNwdGs0MnV5M251dDhqN3FhNGV6In0.Wtu8Lw9TzpEpYbb1TY_XGw',
});
}
const centerLng = 113.03;
const centerLat = 23.05;
const lngLimit = 100;
const latLimit = 20.4;
const centerMercator = lonLat2Mercator([centerLng, centerLat]);
const map = new Map(mapDom, {
limit: [
[centerLng - lngLimit, centerLat - latLimit],
[centerLng + lngLimit, centerLat + latLimit],
],
motion: true,
mapInstance: instance,
// mapInstance: new EmptyInstance(),
defaultViewport: viewport,
threeCenter: [113.203775, 23.109852],
});
const layer = new BaseLayer();
mapDom.addEventListener('click', (e) => {
console.warn(map.pixelToLnglat([e.clientX, e.clientY]));
});
// for (let lng = 0; lng < 40 * gap; lng += gap)
// for (let lat = 0; lat < 20 * gap; lat += gap) {
// const p = new PointMarker(mercator2LonLat([lng, lat]));
// layer.add(p);
// }
// }
const p = new PointMarker([121, 31]);
layer.add(p);
map.add(layer);
const threeLayer = new ThreeLayer();
map.add(threeLayer);
// polygon
const polygon = new PolygonObject({
pointerEvents: true,
z: 200,
polygonGeoJson: {
type: 'Polygon',
coordinates: [
[
[113 + 0, 23 + 0],
[113 + 0, 23 + 1],
[113 + 1, 23 + 1],
[113 + 1, 23 + 0],
[113 + 0, 23 + 0],
],
],
},
fill: {
color: 0xffcccc,
opacity: 0.3,
},
});
polygon.on('mouseenter', () => {
polygon.updateFill({ color: 0xffcccc, opacity: 1 });
});
polygon.on('mouseleave', () => {
polygon.updateFill({ color: 0xffcccc, opacity: 0.3 });
});
// threeLayer.add(polygon);
const textureSize = 100000;
// Texture
fetch('/nanhai-border-simple.json')
.then(resp => resp.json())
.then((json) => {
const hole = new Shape();
json.geometry.coordinates[0].forEach((points, index) => {
let [x, y] = lonLat2Mercator(points);
x -= centerMercator[0];
y -= centerMercator[1];
x /= textureSize * 2;
y /= textureSize * 2;
if (index === 0)
hole.moveTo(x, y);
else
hole.lineTo(x, y);
});
const shape = new Shape();
shape.moveTo(-0.5, -0.5);
shape.lineTo(-0.5, 0.5);
shape.lineTo(0.5, 0.5);
shape.lineTo(0.5, -0.5);
shape.lineTo(-0.5, -0.5);
shape.holes.push(hole);
const texture = new TextureLoader().load('/map-cross-line.png');
texture.wrapS = RepeatWrapping;
texture.wrapT = RepeatWrapping;
texture.center = new Vector2(0.5, 0.5);
texture.repeat = new Vector2((textureSize * 2) / 10000, (textureSize * 2) / 10000);
const textureObject = new TextureObject({
geometry: new ShapeBufferGeometry(shape),
src: texture,
z: 0,
bounds: [
mercator2LonLat([centerMercator[0] - textureSize, centerMercator[1] - textureSize]),
mercator2LonLat([centerMercator[0] + textureSize, centerMercator[1] + textureSize]),
],
});
threeLayer.add(textureObject);
});
// 加载 建筑物
// fetch('/building.json').then(resp => resp.json())
// .then((json) => {
// const res = json.features.slice(0).map(({ geometry, properties }) => ({
// path: geometry.coordinates[0].map(gcj02towgs84).map(lonLat2Mercator),
// height: properties.floor,
// }));
// const buildings = new BuildingObject({
// buildings: res,
// fill: {
// color: 0x58699b,
// // color: 0xff0000,
// opacity: 0.8,
// },
// });
// threeLayer.add(buildings);
// });
fetch('/china.txt')
.then(resp => resp.text())
.then((res) => {
const list = res.split('|').map(p => ({
height: 10,
path: p.split(';').map((p) => {
const [lng, lat] = p.split(',');
const point = [Number(lng), Number(lat)];
return point;
}),
}));
const buildings = new BuildingObject({
pointerEvents: false,
// polygonGeoJson: {
// type: 'MultiPolygon',
// coordinates: list,
// },
buildings: list,
fill: {
color: 0x1199ff,
opacity: 0.2,
},
});
threeLayer.add(buildings);
});
// const p2 = [
// new PointMarker(limit[0] as Point, { color: 'blue', size: '50' }),
// new PointMarker(limit[1] as Point, { color: 'blue', size: '50' }),
// ];
// const p4 = [new PointMarker([0, 0]), new PointMarker([0, 0]), new PointMarker([0, 0]), new PointMarker([0, 0])];
// p2.forEach((p) => {
// layer.add(p);
// });
// p4.forEach((p) => {
// layer.add(p);
// });
// setInterval(() => {
// const { bounds } = map.controller.getLimitViewport();
// p2[0].setPosition(bounds[0] as [number, number]);
// p2[1].setPosition(bounds[1] as [number, number]);
// // p4[0].setPosition(r[0] as [number, number]);
// // p4[1].setPosition(r[1] as [number, number]);
// // p4[2].setPosition(r[2] as [number, number]);
// // p4[3].setPosition(r[3] as [number, number]);
// map.updateLayers();
// }, 3000);
// svg
const svgLayer = new SvgLayer();
const svgPolygon = new SvgPolyline({
path: [
[121.1, 31.1],
[121.2, 31.2],
[121.3, 31.1],
],
});
const svgLine = new SvgArcLine({
from: [120, 30],
to: [121, 31],
style: {
stroke: '#FF0000',
},
});
svgLayer.add(svgPolygon);
svgLayer.add(svgLine);
// map.add(svgLayer);
// window.c = map;
const btnFlyTo = document.getElementById('btnFlyTo');
if (btnFlyTo) {
btnFlyTo.addEventListener('click', () => {
// map.panTo([121.1, 31.1]);
map.flyTo({
lng: 110 + Math.random() * 10,
lat: 25 + Math.random() * 10,
zoom: 2 + Math.random() * 6,
rotate: Math.random() * 360,
pitch: Math.random() * 60,
});
// map.mapInstance.map.flyTo({
// center: [110 + Math.random() * 10, 25 + Math.random() * 10],
// zoom: 6 + Math.random() * 6,
// bearing: Math.random() * 360,
// pitch: Math.random() * 60,
// });
});
}
const heatmapLayer = new ThreeHeatmapLayer({
minZoom: 10,
maxZoom: 13,
data: heatmapData,
});
heatmapLayer.setOpacity(0.8);
// map.add(heatmapLayer);
const iconObject = new IconObject({
src: '/icon.png',
checkedSrc: '/icon-check.png',
hoverSrc: '/icon-check.png',
width: 50,
height: 50,
minZoom: 10,
maxZoom: 18,
pointerEvents: true,
z: 2,
data: new Array(10000)
.fill(0)
.map((_, index) => [Math.random() * 5 + viewport.center[0], Math.random() * 5 + viewport.center[1]]),
});
// iconObject.on('click', (event, intersection) => {
// console.log(event, intersection, intersection.instanceId);
// });
threeLayer.add(iconObject);
threeLayer.startAnimate();
const btnTest = document.getElementById('btnTest');
if (btnTest) {
const polygon = new PolygonObject({
border: {
color: 0x1199ff,
opacity: 1,
},
});
threeLayer.add(polygon);
btnTest.addEventListener('click', () => {
const bounds = map.getBounds();
const coordinates = [
[
[bounds[0][0], bounds[0][1]],
[bounds[0][0], bounds[1][1]],
[bounds[1][0], bounds[1][1]],
[bounds[1][0], bounds[0][1]],
[bounds[0][0], bounds[0][1]],
],
];
polygon.setPolygon({
type: 'Polygon',
coordinates,
});
});
}
}
});
}());