Skip to content

OD 动态线


ts
import { Viewer, ODLineLayer, ODLineMaterialProperty } from "joDVF";
import { Pane } from "tweakpane";
import { MapboxStyleImageryProvider, Cartesian3, Color } from "joCesium";

const { mapContainer, uiContainer } = createContainer();

const viewer = new Viewer(mapContainer);
viewer.imageryLayers.removeAll(false);

// 加载自定义 mapbox 地图
const layers = viewer.imageryLayers;
layers.addImageryProvider(
  new MapboxStyleImageryProvider({
    url: "https://api.mapbox.com/styles/v1",
    username: "jiegisergg",
    styleId: "ck4c5mpq30xuq1ctgesmlehij",
    accessToken:
      "pk.eyJ1IjoiamllZ2lzZXJnZyIsImEiOiJjanExcmJjMTYxMGlxM3hueG9lZjQ4eng5In0.F4Ia4OCMj8HZV8scGQvSfQ",
    scaleFactor: true
  })
);

let odLayer;
fetch("./assets/json/bus.json")
  .then((r) => r.json())
  .then((data) => {
    let timeDuration = 10.0;
    let moveDuration = 4.0;

    const busLines: any[] = [];
    data.map(function (busLine, idx) {
      let prevPt;
      const points = [];
      for (let i = 0; i < busLine.length; i += 2) {
        let pt = [busLine[i], busLine[i + 1]];
        if (i > 0) {
          pt = [prevPt[0] + pt[0], prevPt[1] + pt[1]];
        }
        prevPt = pt;

        const longitude = pt[0] / 1e4;
        var latitude = pt[1] / 1e4;
        const cart = Cartesian3.fromDegrees(longitude, latitude, 80.0);
        points.push(cart);
      }

      busLines.push({
        positions: points,
        startTime: timeDuration * Math.random(),
        duration: moveDuration + 1.0 * Math.random()
      });
    });

    const paths = busLines;
    let time = 0;

    const disposeListener = viewer.scene.preUpdate.addEventListener(
      function () {
        time += 0.01;
        if (time >= timeDuration) {
          time = 0.0;
        }
      }
    );

    // 初始化图层
    odLayer = new ODLineLayer(viewer, {
      paths: busLines,
      width: 3.0,
      timeRatio: function (index, frameState) {
        const st = paths[index].startTime;
        const dr = paths[index].duration;
        const diff = time > st ? time - st : time + timeDuration - st;
        const timeRatio = Math.min(diff / dr, 1.0);
        return timeRatio;
      }
    });
    odLayer.flyTo();
  });

// 动态线
const entity = viewer.entities.add({
  name: "DynamicPolyline",
  polyline: {
    positions: Cartesian3.fromDegreesArrayHeights([
      104.067162, 30.544676, 10.1, 104.067631, 30.539976, 4, 104.070885,
      30.540023, 22, 104.07218, 30.540295, 14, 104.073215, 30.540353, 8,
      104.073078, 30.544402, 9
    ]),
    width: 2,
    material: new ODLineMaterialProperty({
      color: Color.WHITE
    })
  }
});

addUI();
function addUI() {
  const pane = new Pane({
    container: uiContainer,
    title: "参数"
  });

  const singleBtn = pane.addButton({
    title: "OD 单条线"
  });

  singleBtn.on("click", () => {
    viewer.flyTo(entity, {
      duration: 1.0
    });
  });

  const collectionBtn = pane.addButton({
    title: "北京 bus OD线路"
  });

  collectionBtn.on("click", () => {
    odLayer && odLayer.flyTo();
  });
}

function createContainer() {
  const container = document.createElement("div");
  container.style.width = "100%";
  container.style.height = "100%";

  const uiContainer = document.createElement("div");
  uiContainer.style.position = "fixed";
  uiContainer.style.top = "5px";
  uiContainer.style.left = "5px";
  document.body.appendChild(container);
  document.body.appendChild(uiContainer);

  return {
    mapContainer: container,
    uiContainer
  };
}