hn-map 1.1.14 → 1.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/map.ts CHANGED
@@ -21,7 +21,13 @@ export default (hnMap: any) => {
21
21
  sj_app_key: "",
22
22
  sj_app_secret: "",
23
23
  sj_style: "aegis://styles/aegis/Streets-Raster512",
24
- sj_route_net:true,
24
+ sj_route_net: true,
25
+ // Cesium配置
26
+ cesium_accessToken: "",
27
+ cesium_baseUrl: "",
28
+ cesium_terrainProvider: null,
29
+ cesium_imageryProvider: null,
30
+ cesium_options: {},
25
31
  };
26
32
 
27
33
  class mars3d_map {
@@ -43,7 +49,6 @@ export default (hnMap: any) => {
43
49
  deepMerge(this.option, option);
44
50
  this.config = this.formatConfig(this.option);
45
51
  this.map = new mars3d.Map(id, this.config);
46
-
47
52
  this.map.on("cameraMoveEnd", (e: any) => {
48
53
  const height = this.map.getCameraView().alt;
49
54
  this.level = getHeightToLevel(height);
@@ -287,24 +292,21 @@ export default (hnMap: any) => {
287
292
  await new Promise((resolve) => {
288
293
  instance.map.on("load", (e: any) => {
289
294
  // 路况展示
290
- if(option.sj_route_net){
295
+ if (option.sj_route_net) {
291
296
  let roadNetLayer = new SGMap.RoadNetLayer({ map: instance.map });
292
297
  roadNetLayer.render();
293
298
  }
294
299
 
295
300
  //添加天空图层
296
301
  instance.map.addLayer({
297
- "id": "sky",
298
- "type": "sky",
299
- "paint": {
302
+ id: "sky",
303
+ type: "sky",
304
+ paint: {
300
305
  "sky-type": "atmosphere",
301
- "sky-atmosphere-sun": [
302
- 0,
303
- 0
304
- ],
305
- "sky-atmosphere-sun-intensity": 15
306
- }
307
- })
306
+ "sky-atmosphere-sun": [0, 0],
307
+ "sky-atmosphere-sun-intensity": 15,
308
+ },
309
+ });
308
310
 
309
311
  // 加载地形(需要v3.1.0,且需要新的key和secret)
310
312
  // !instance.map.getSource('terrain') && instance.map.addSource('terrain',{
@@ -386,11 +388,14 @@ export default (hnMap: any) => {
386
388
  switch (eventType) {
387
389
  case "click":
388
390
  this.event[eventType] = (event: any) => {
389
- callback({
390
- lng: event.lngLat.lng,
391
- lat: event.lngLat.lat,
392
- alt: event.lngLat.alt || 0,
393
- });
391
+ callback(
392
+ {
393
+ lng: event.lngLat.lng,
394
+ lat: event.lngLat.lat,
395
+ alt: event.lngLat.alt || 0,
396
+ },
397
+ event
398
+ );
394
399
  };
395
400
  break;
396
401
  case "dblclick":
@@ -460,10 +465,405 @@ export default (hnMap: any) => {
460
465
  }
461
466
  }
462
467
 
468
+ class cesium_map {
469
+ map: any = null;
470
+ option: any = JSON.parse(JSON.stringify(defaultOption));
471
+ config: any = null;
472
+ layerList: any = [];
473
+ event: any = {};
474
+ level: any = null;
475
+ // 数据源集合
476
+ dataSources: any = new Cesium.CustomDataSource("hnMap_dataSources");
477
+ private constructor(id: any, option: any) {
478
+ this.layerList = [];
479
+ this.level = 10;
480
+ deepMerge(this.option, option);
481
+ this.config = this.formatConfig(this.option);
482
+ this.map = new Cesium.Viewer(id, this.config);
483
+
484
+ // 监听相机移动事件
485
+ this.map.camera.moveEnd.addEventListener(() => {
486
+ const camera = this.map.camera;
487
+ const cartographic = Cesium.Cartographic.fromCartesian(camera.position);
488
+ const height = cartographic.height;
489
+ this.level = getHeightToLevel(height);
490
+
491
+ // 触发cameraMoveEnd事件
492
+ if (this.event.cameraMoveEnd) {
493
+ this.event.cameraMoveEnd();
494
+ }
495
+ });
496
+ // 添加自定义数据源
497
+ this.map.dataSources.add(this.dataSources);
498
+
499
+ // 设置初始视图
500
+ const { lat, lng, level, heading, pitch, roll } = this.option;
501
+ const alt = getLevelMiddleHeight(level);
502
+
503
+ // 设置相机位置
504
+ const initialPosition = Cesium.Cartesian3.fromDegrees(lng, lat, alt);
505
+ const initialOrientation = new Cesium.HeadingPitchRoll(
506
+ Cesium.Math.toRadians(heading),
507
+ Cesium.Math.toRadians(pitch),
508
+ Cesium.Math.toRadians(roll)
509
+ );
510
+
511
+ this.map.camera.setView({
512
+ destination: initialPosition,
513
+ orientation: initialOrientation,
514
+ });
515
+ }
516
+ static async create(id: string, option: any) {
517
+ const instance = new cesium_map(id, option);
518
+
519
+ // 返回一个 Promise,等待地图的 'ready' 事件
520
+ await new Promise<void>((resolve) => {
521
+ resolve();
522
+ });
523
+
524
+ return instance;
525
+ }
526
+ // 格式化配置
527
+ formatConfig(option: any) {
528
+ const config: any = {
529
+ ...option.cesium_options,
530
+ // 设置不显示商标
531
+ imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
532
+ url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
533
+ enablePickFeatures: false,
534
+ }),
535
+ };
536
+
537
+ // 设置地形 - 兼容性处理
538
+ if (option.cesium_terrainProvider) {
539
+ config.terrainProvider = option.cesium_terrainProvider;
540
+ } else {
541
+ config.terrainProvider = this.createTerrainProvider();
542
+ }
543
+
544
+ // 设置影像 - 兼容性处理
545
+ if (option.cesium_imageryProvider) {
546
+ config.imageryProvider = option.cesium_imageryProvider;
547
+ } else {
548
+ config.imageryProvider = this.createImageryProvider();
549
+ }
550
+
551
+ return config;
552
+ }
553
+
554
+ // 创建地形提供者(兼容各版本)
555
+ createTerrainProvider() {
556
+ // 检查是否支持createWorldTerrain
557
+ if (typeof Cesium.createWorldTerrain === "function") {
558
+ // 1.107及以上版本
559
+ return Cesium.createWorldTerrain({
560
+ requestWaterMask: true,
561
+ requestVertexNormals: true,
562
+ });
563
+ } else if (Cesium.CesiumTerrainProvider) {
564
+ // 1.106及以下版本
565
+ const terrainUrl = this.getTerrainUrl();
566
+ return new Cesium.CesiumTerrainProvider({
567
+ url: terrainUrl,
568
+ requestWaterMask: true,
569
+ requestVertexNormals: true,
570
+ });
571
+ } else {
572
+ // 没有地形
573
+ console.warn("Cesium地形不可用,使用无地形模式");
574
+ return new Cesium.EllipsoidTerrainProvider();
575
+ }
576
+ }
577
+
578
+ // 获取地形URL(兼容处理)
579
+ getTerrainUrl() {
580
+ // 根据不同版本的API获取地形URL
581
+ if (Cesium.IonResource && Cesium.IonResource.fromAssetId) {
582
+ return Cesium.IonResource.fromAssetId(1);
583
+ } else if (Cesium.Ion && Cesium.Ion.defaultServer) {
584
+ return `${Cesium.Ion.defaultServer.url}/assets/1/quantized-mesh`;
585
+ } else {
586
+ // 使用Cesium官方的地形服务
587
+ return "https://assets.cesium.com/1/";
588
+ }
589
+ }
590
+
591
+ // 创建影像提供者(兼容各版本)
592
+ createImageryProvider() {
593
+ // 默认使用Bing地图或ArcGIS
594
+ try {
595
+ // 尝试创建Bing地图
596
+ if (Cesium.BingMapsImageryProvider) {
597
+ return new Cesium.BingMapsImageryProvider({
598
+ url: "https://dev.virtualearth.net",
599
+ key: this.option.cesium_bing_key || "", // 需要Bing Maps Key
600
+ mapStyle: Cesium.BingMapsStyle.AERIAL,
601
+ });
602
+ }
603
+ } catch (e) {
604
+ console.warn("Bing地图不可用,尝试其他影像源", e);
605
+ }
606
+
607
+ // 使用ArcGIS作为备选
608
+ if (Cesium.ArcGisMapServerImageryProvider) {
609
+ return new Cesium.ArcGisMapServerImageryProvider({
610
+ url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
611
+ });
612
+ }
613
+
614
+ // 使用OpenStreetMap作为最后备选
615
+ if (Cesium.OpenStreetMapImageryProvider) {
616
+ return new Cesium.OpenStreetMapImageryProvider({
617
+ url: "https://a.tile.openstreetmap.org/",
618
+ });
619
+ }
620
+
621
+ // 没有可用影像提供者
622
+ console.warn("没有可用的影像提供者");
623
+ return undefined;
624
+ }
625
+ // 添加图层
626
+ addLayer(layer: any) {
627
+ if (this.layerList.find((v: any) => v.id === layer.id)) {
628
+ console.error("已存在同名图层" + layer.id);
629
+ return null;
630
+ }
631
+
632
+ this.layerList.push(layer);
633
+
634
+ // 如果是数据源图层,添加到数据源集合
635
+ if (layer.layerEntity && layer.layerEntity.entities) {
636
+ this.map.dataSources.add(layer.layerEntity);
637
+ }
638
+
639
+ // 如果是Primitive图层,添加到Primitive集合
640
+ if (
641
+ layer.layerEntity &&
642
+ layer.layerEntity instanceof Cesium.PrimitiveCollection
643
+ ) {
644
+ this.map.scene.primitives.add(layer.layerEntity);
645
+ }
646
+
647
+ return layer;
648
+ }
649
+
650
+ // 获取图层
651
+ getLayer(layerId: any) {
652
+ return this.layerList.find((v: any) => v.id === layerId);
653
+ }
654
+
655
+ // 删除图层
656
+ removeLayer(layerId: any) {
657
+ const layer = this.getLayer(layerId);
658
+ if (layer) {
659
+ this.layerList = this.layerList.filter((v: any) => v.id !== layerId);
660
+ layer.destroy();
661
+ }
662
+ }
663
+
664
+ // 清空图层
665
+ clearLayer(layerId: any) {
666
+ const layer = this.getLayer(layerId);
667
+ if (layer) {
668
+ layer.children = [];
669
+ layer.clearEntity();
670
+ }
671
+ }
672
+
673
+ // 事件监听
674
+ on(eventType: any, callback: any) {
675
+ this.off(eventType);
676
+
677
+ switch (eventType) {
678
+ case "click":
679
+ this.event[eventType] = (movement: any) => {
680
+ // 获取点击位置
681
+ const ray = this.map.camera.getPickRay(movement.position);
682
+ if (!ray) return;
683
+
684
+ const cartesian = this.map.scene.globe.pick(ray, this.map.scene);
685
+ if (!cartesian) return;
686
+
687
+ const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
688
+ const position = {
689
+ lng: Cesium.Math.toDegrees(cartographic.longitude),
690
+ lat: Cesium.Math.toDegrees(cartographic.latitude),
691
+ alt: cartographic.height,
692
+ };
693
+
694
+ callback(position);
695
+ };
696
+
697
+ // 使用屏幕空间事件处理器
698
+ this.map.screenSpaceEventHandler.setInputAction((movement: any) => {
699
+ this.event[eventType](movement);
700
+ }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
701
+ break;
702
+
703
+ case "cameraMoveEnd":
704
+ this.event[eventType] = () => {
705
+ callback();
706
+ };
707
+ break;
708
+
709
+ case "mouseMove":
710
+ this.event[eventType] = (movement: any) => {
711
+ callback(movement);
712
+ };
713
+
714
+ this.map.screenSpaceEventHandler.setInputAction((movement: any) => {
715
+ this.event[eventType](movement);
716
+ }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
717
+ break;
718
+ }
719
+ }
720
+
721
+ // 取消事件监听
722
+ off(eventType: any) {
723
+ if (this.event[eventType]) {
724
+ // 移除事件处理器
725
+ this.map.screenSpaceEventHandler.removeInputAction(
726
+ Cesium.ScreenSpaceEventType.LEFT_CLICK
727
+ );
728
+ delete this.event[eventType];
729
+ }
730
+ }
731
+
732
+ /**
733
+ * 获取当前视口的经纬度范围
734
+ */
735
+ getExtent() {
736
+ const camera = this.map.camera;
737
+ const frustum = camera.frustum;
738
+
739
+ // 计算视锥体的四个角点
740
+ const corners = [
741
+ new Cesium.Cartesian2(0, 0),
742
+ new Cesium.Cartesian2(this.map.canvas.width, 0),
743
+ new Cesium.Cartesian2(this.map.canvas.width, this.map.canvas.height),
744
+ new Cesium.Cartesian2(0, this.map.canvas.height),
745
+ ];
746
+
747
+ let minLon = 180;
748
+ let maxLon = -180;
749
+ let minLat = 90;
750
+ let maxLat = -90;
751
+
752
+ corners.forEach((corner) => {
753
+ const ray = camera.getPickRay(corner);
754
+ if (!ray) return;
755
+
756
+ const cartesian = this.map.scene.globe.pick(ray, this.map.scene);
757
+ if (!cartesian) return;
758
+
759
+ const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
760
+ const lon = Cesium.Math.toDegrees(cartographic.longitude);
761
+ const lat = Cesium.Math.toDegrees(cartographic.latitude);
762
+
763
+ minLon = Math.min(minLon, lon);
764
+ maxLon = Math.max(maxLon, lon);
765
+ minLat = Math.min(minLat, lat);
766
+ maxLat = Math.max(maxLat, lat);
767
+ });
768
+
769
+ return {
770
+ xmin: minLon,
771
+ xmax: maxLon,
772
+ ymin: minLat,
773
+ ymax: maxLat,
774
+ };
775
+ }
776
+
777
+ /**
778
+ * 获取当前相机视图
779
+ */
780
+ getCameraView() {
781
+ const camera = this.map.camera;
782
+ const position = camera.positionWC;
783
+ const cartographic = Cesium.Cartographic.fromCartesian(position);
784
+
785
+ return {
786
+ lng: Cesium.Math.toDegrees(cartographic.longitude),
787
+ lat: Cesium.Math.toDegrees(cartographic.latitude),
788
+ alt: cartographic.height,
789
+ heading: Cesium.Math.toDegrees(camera.heading),
790
+ pitch: Cesium.Math.toDegrees(camera.pitch),
791
+ roll: Cesium.Math.toDegrees(camera.roll),
792
+ };
793
+ }
794
+
795
+ /**
796
+ * 飞向指定点
797
+ */
798
+ flyToPoint(position: any) {
799
+ const [lng, lat, alt] = position;
800
+ const cartesian = Cesium.Cartesian3.fromDegrees(lng, lat, alt); // 创建经纬度坐标点
801
+
802
+ this.map.camera.flyTo({
803
+ destination: cartesian,
804
+ duration: 2,
805
+ complete: () => {
806
+ console.log("飞行动画完成");
807
+ },
808
+ });
809
+ }
810
+
811
+ /**
812
+ * 飞向指定区域
813
+ */
814
+ flyToExtent(extent: any) {
815
+ const rectangle = Cesium.Rectangle.fromDegrees(
816
+ extent.xmin,
817
+ extent.ymin,
818
+ extent.xmax,
819
+ extent.ymax
820
+ );
821
+
822
+ this.map.camera.flyTo({
823
+ destination: rectangle,
824
+ duration: 2,
825
+ });
826
+ }
827
+
828
+ /**
829
+ * 关闭所有弹窗
830
+ */
831
+ closePopup() {
832
+ this.map.selectedEntity = null;
833
+ this.map.trackedEntity = null;
834
+ }
835
+
836
+ /**
837
+ * 设置投影模式 2d/3d
838
+ */
839
+ setMode(mode: string) {
840
+ const modes: any = {
841
+ "2d": Cesium.SceneMode.SCENE2D,
842
+ "3d": Cesium.SceneMode.SCENE3D,
843
+ columbus: Cesium.SceneMode.COLUMBUS_VIEW,
844
+ };
845
+
846
+ if (modes[mode.toLowerCase()]) {
847
+ this.map.scene.mode = modes[mode.toLowerCase()];
848
+ }
849
+ }
850
+
851
+ /**
852
+ * 销毁地图
853
+ */
854
+ destroy() {
855
+ if (this.map) {
856
+ this.map.destroy();
857
+ this.map = null;
858
+ }
859
+ }
860
+ }
861
+
463
862
  const map: any = {
464
863
  mars3d: mars3d_map,
465
864
  gaode: gaode_map,
466
865
  siji: siji_map,
866
+ cesium: cesium_map,
467
867
  };
468
868
  return map[hnMap.mapType];
469
869
  };
@@ -1,6 +1,6 @@
1
1
  import { deepMerge, wgs84ToGcj02Format } from "../util";
2
2
 
3
- import siji_entity from "../base/siji_entity";
3
+ import SijiEntity from "../base/siji_entity";
4
4
  export default (hnMap: any) => {
5
5
  const defaultOption = {
6
6
  id: "",
@@ -242,7 +242,7 @@ export default (hnMap: any) => {
242
242
  }
243
243
  }
244
244
 
245
- class siji_class extends siji_entity {
245
+ class siji_class extends SijiEntity {
246
246
  type: any = "route";
247
247
  id: any = null;
248
248
  option: any = JSON.parse(JSON.stringify(defaultOption));