OpenLayers Workshop(二)Vector Data

Making it look nice 让地图好看些

此时,我们有一个具有基本导入、编辑和导出功能的特征编辑器。 但是我们没有花任何时间试图使这些功能看起来不错。 当您在 OpenLayers 中创建矢量图层时,您将获得一组默认样式。 编辑交互(绘制和修改)也带有自己的默认样式。 您可能已经注意到几何图形在编辑过程中如何具有更粗的笔划。 可以通过为矢量图层和编辑交互提供style选项来控制此行为。

首先,我们将导入所需的构造函数:

import {Style, Fill, Stroke} from 'ol/style';

Static style 静态的样式

如果我们想给所有特征相同的风格,我们可以像这样配置我们的矢量图层:

const layer = new VectorLayer({
  source: source,
  style: new Style({
    fill: new Fill({
      color: 'red'
    }),
    stroke: new Stroke({
      color: 'white'
    })
  })
});

也可以将 style 属性设置为样式数组。 例如,这允许渲染一条套管线(下方的宽笔划和顶部的较窄笔划)。

虽然这里没有很好的理由,但为了这个练习,我们将利用动态样式。

Dynamic style 动态的样式

当您想根据有关特征或当前视图分辨率的某些内容来决定如何渲染每个特征时,您可以使用样式函数配置矢量图层。 这个函数在每个渲染帧的每个特性都会被调用,所以如果你有很多特性并且想要保持良好的渲染性能,那么编写一个高效的函数很重要。

这是一个示例,该示例根据“name”属性是以“A-M”还是“N-Z”开头(完全人为的示例)使用两种样式之一来呈现特征。

const layer = new VectorLayer({
  source: source,
  style: function(feature, resolution) {
    const name = feature.get('name').toUpperCase();
    return name < "N" ? style1 : style2; // assuming these are created elsewhere
  }
});

根据这个例子我进行了实践,即按照国家名称,首字母在N之前的用红色,其它的用蓝色:

const style1=new Style({
  fill: new Fill({
    color: 'red'
  }),
  stroke: new Stroke({
    color: 'white'
  })
});
const style2=new Style({
  fill: new Fill({
    color: 'blue'
  }),
  stroke: new Stroke({
    color: 'white'
  })
});
const layer = new VectorLayer({
  source: source,
  style: function(feature, resolution) {
    const name = feature.get('name').toUpperCase();
    return name < "N" || name == "TAIWAN" ? style1 : style2;
  }
});

Styling based on geometry area 基于几何面积的样式

为了了解动态样式的工作原理,我们将创建一个样式函数,该函数根据几何区域呈现特征。 为此,我们将使用 npm 上的colormap package 颜色映射包。 我们可以像这样将它添加到我们的依赖项中:

npm install colormap

然后导入colormap类和计算球面积的ol/sphere类:

import {getArea} from 'ol/sphere';
import colormap from 'colormap';

然后编写一系列根据几何面积大小来决定颜色的方法:

const min = 1e8; // the smallest area
const max = 2e13; // the biggest area
const steps = 50;
// 一个颜色区间,共有50种颜色
const ramp = colormap({
  colormap: 'blackbody',
  nshades: steps
});

// 将面积收缩在low和high之间
function clamp(value, low, high) {
  return Math.max(low, Math.min(value, high));
}

// 根据面积找到其颜色下标
function getColor(feature) {
  const area = getArea(feature.getGeometry());
  const f = Math.pow(clamp((area - min) / (max - min), 0, 1), 1 / 2);
  const index = Math.round(f * (steps - 1));
  return ramp[index];
}

现在我们可以添加一个函数来创建一个基于几何区域的填充颜色的样式。 将此函数设置为矢量图层的style属性:

const layer = new VectorLayer({
  source: source,
  style: function(feature) {
    if (feature.get("name")=="Taiwan"){
      const cnFeature=source.getFeatureById("CHN");
      return new Style({
        fill: new Fill({
          color: getColor(cnFeature)
        }),
        stroke: new Stroke({
          color: 'rgba(255,255,255,0.8)'
        })
      });
    }
    return new Style({
      fill: new Fill({
        color: getColor(feature)
      }),
      stroke: new Stroke({
        color: 'rgba(255,255,255,0.8)'
      })
    });
  }
});

发表评论