[3D ГИС визуализация] Реализация умного города на основе Vue+Cesium+Supermap (4)

GIS
[3D ГИС визуализация] Реализация умного города на основе Vue+Cesium+Supermap (4)

В первых трех статьях нам удалось добиться эффекта загрузки земли, загрузки карты и загрузки точек, линий и поверхностей. Базовые знания также были введены соответствующим образом.Следующие статьи могут быть в основном сосредоточены на конкретной реализации определенной функции или конкретной реализации определенного стиля. Приветствую всех, чтобы обсудить в области комментариев.

предисловие

В настоящее время в стране активно продвигается управление сетью, и многие системы также были созданы на основе управления сетью.В современных умных или цифровых городах незаменимой функцией является отображение сетки и связанные с ним функции. Сегодня давайте рассмотрим стили и операции, связанные с сеткой.polygonнажмите действие. Точно так же административные подразделения также могут использовать такие эффекты и операции для снижения.

Давайте сначала взглянем на эффект и реализуем стиль градиентной заливки поверхности, эффект наведения мыши и эффект щелчка.

grid.gif

идеи и реализация

Мы хотим добиться щелчка по лицу, эффекта наведения и модификации стиля. В основном все, что вам нужно, это цезийScreenSpaceEventHandlerследить за работой мыши, а модификация стиля может повлиять на заливку изображения илиmaterialдля обработки. Что ж, теперь, когда мы разобрались, как это реализовать, давайте приступим!

получить данные

Сетки, по сути, тоже лица, поэтому сначала нам нужны данные о лицах для сетки, мы можем перейти кDataV.GeoatlasПолучите данные geojson полигона на карте. Здесь мы используем данные административного деления Пекина, а адрес я размещу здесь, друзья, которые хотят найти другие данные, могут найти его сами.

https://geo.datav.aliyun.com/areas_v2/bound/110000_full.json

Загрузить данные в формате geoJSON

Использование цезияGeoJsonDataSourceЧтобы загрузить данные geoJSON, обратите внимание: он возвращает объект обещания, поэтому вам нужно использовать.then(cb).

var promise=Cesium.GeoJsonDataSource.load('https://geo.datav.aliyun.com/areas_v2/bound/110000_full.json')
promise.then((datasource) => {
    viewer.dataSources.add(datasource);
    var entities = datasource.entities.values;
    for (var i = 0; i < entities.length; i++){
      var entity = entities[i];
      entity.polygon.material = Cesium.Color.RED;
      entity.polygon.extrudedHeight = 100
    }
})

Здесь мы видим, что источником данных является набор данных, который мы получили через URL-адрес. После загрузки нам нужно изменить стиль каждой сущности, перебирая набор сущностей в наборе данных. Здесь мы временно устанавливаем его цвет на красный, тянем высота расширения 100.

image.png

Вы можете видеть, что наша поверхность с высотой была визуализирована.Теперь мы можем подумать о том, как сделать ее полупрозрачным градиентом, как наши исходные визуализации?

polygonмодификация стиля

мы знаем,entityчерезmatrialИзмените стиль материала. Прозрачность, которую мы можем пройтиCesium.ColorСобственныйwithAlphaСделайте модификации, но эффект, который мы хотим показать, является региональным градиентом и прозрачностью. Моя первая мысль в то время было это, так какmaterialИзображение может быть загружено, поэтому можем ли мы заполнить его изображением с региональным градиентом? Вывод да. нам просто нужно entity.polygon.material = require('./images/color.jpg');Вы можете заполнить его фотографиями.

image.png

В настоящее время, вы можете сказать, с этим легко справиться, нельзя ли сделать изображение полупрозрачным? Что в этом сложного. Да, но давайте подумаем.Если клиент сказал в это время: нет, этот цвет некрасивый, дайте мне еще немного, и я увижу эффект, что вы должны делать? Вам нужно заменить несколько картинок одну за другой, это слишком хлопотно. Поэтому нам нужен способ указать цвета и быстро генерировать изображения для использования.canvasПришло время встать и использоватьcanvas, мы можем использовать код для быстрой генерации картинок в указанном стиле, что ненамного быстрее, чем рисование.

canvasЗнания о градиентах и ​​углах здесь вводить не будем, их много в интернете, и мы объясним их прямо через код.

getColorRamp(rampColor,centerColor) {
    var ramp = document.createElement("canvas");
    ramp.width = 50;
    ramp.height = 50;
    var ctx = ramp.getContext("2d");

    var grd = ctx.createRadialGradient(25, 25, 0, 25, 25, 50);
    grd.addColorStop(0, centerColor); // "rgba(255,255,255,0)"
    grd.addColorStop(1, rampColor);

    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, 50, 50);

    // return ramp;

    return new Cesium.ImageMaterialProperty({
      image: ramp,
      transparent: true
    });
}

Вы видите, что мы инкапсулировали функцию, а входными параметрами являются цвета на обоих концах градиента (конечно, если вам нужно изменить угол, направление и т. д., вы можете настроить параметры в соответствии с вашими потребностями), генерировать50*50холст холст,createRadialGradientСоздайте объект градиента, укажите цвет и положение градиента, нарисуйте его на холсте и, наконец, верните объект Cesium.ImageMaterialPropertyКласс материала изображения, не забудьте настроитьtransparentдляtrue.

Таким образом, мы можем настроить цвет для создания материала с эффектом полупрозрачного градиента, посмотрите на эффект!

image.png

Желтая линия по краю — это лицоoutline, мы можем установить его наnullпоказать лучшие результаты.

Наведение мыши и события щелчка

Эффект, которого мы хотим добиться, это нажать на блик и подвести мышь, а эффект динамической линии на периферии поверхности на самом деле очень прост, то есть, когда мы нажимаем на эту поверхность, мы получаем эту поверхность , измените материал этой поверхности и используйте периферию этой поверхности.Набор координат генерируетpolyline, добавить материал для динамических линий. Теперь давайте посмотрим на код.

handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((e) => {
  var pick = viewer.scene.pick(e.position);
  if (Cesium.defined(pick) && pick.id) {
    var feature = pick.id;
    viewer.entities.removeById("select_grid");
    viewer.entities.removeById(`line_${feature.id}`);
    let positions = feature.polygon.hierarchy.getValue(
        Cesium.JulianDate.now()
    ).positions;
    viewer.entities.add({
    id: "select_grid",
    polygon: {
      hierarchy: positions,
      material: this.getColorRamp(
        "rgba(0, 255, 255,1)",
        "rgba(255,0,0,0.3)"
      ),
      height: 499,
    },
    });
  }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

handler.setInputAction((movement) => {
    var pickFeature =
      viewer.scene.pick(movement.endPosition) &&
      viewer.scene.pick(movement.endPosition).id;
    if (Cesium.defined(pickFeature) && this.preLineId !== pickFeature.id) {
      this.preLineId &&viewer.entities.removeById(`line_${this.preLineId}`);
      this.preLineId = pickFeature.id;
      viewer.entities.add({
        id: "line_" + pickFeature.id,
        name: "line_" + pickFeature.name,
        polyline: {
          positions: pickFeature.polygon.hierarchy.getValue(
            Cesium.JulianDate.now()
          ).positions,
          width: 8,
          material: new Cesium.PolylineTrailMaterialProperty({
            // 尾迹线材质
            color: Cesium.Color.AQUA,
            trailLength: 0.9,
            period: 1,
          }),
        },
      });
    } else {
      this.preLineId && viewer.entities.removeById(`line_${this.preLineId}`);
      this.preLineId = null;
    }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

Эффект:

6.gif

Фактически, чтобы подвести итог, нужно получить текущую позицию мыши.entity, генерирует новое лицо и новую линию на основе набора периферийных координат лица, добавленного к сфере. Это наш первый эффект.

приложение

серия статей

[3D ГИС-визуализация] Реализация умного города на основе Vue+Cesium+Supermap (1)

[3D ГИС-визуализация] Реализация умного города на основе Vue+Cesium+Supermap (2)

[3D ГИС визуализация] Реализация умного города на основе Vue+Cesium+Supermap (3)