UNPKG

@orca-fe/x-map

Version:
300 lines (299 loc) 12.8 kB
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, }); }); } } }); }());