Skip to content
目录

常见问题

图形透明的地方为何不能交互?

maptalks内部图形交互用的判断的依据是当前鼠标点出是否有颜色值来确定是否有图形被命中的,所以当透明度为0时,认为这里没有图形

怎么解决这个问题?将图形的透明度设为一个很小的值即可,比如0.001,这样可以做到从人眼视觉是透明的,计算机内部也能识别该处的颜色值

js
symbol:{
  polygonFill:'red',
  polygonOpacity:0.001
}

文字换行

文字换行使用\n而不是<br>,注意js语法里和html语法换行的区别

js
const textName = "hello\nworld";

设置了文字模板标注为什么读取不到值

文字标注maptalks内部从数据里动态读取属性的,一般用'{name}'这样的的表达式,如果渲染时读取不到对应的文字值可能:

  • 你的数据里不包含改属性值,请检查你的数据
  • 属性的key用了中文等特殊字符,比如这样的配置
js
symbol:{
    textName:'{名称}',
    ....
}

文字属性的动态读取用的是正则表达式,其是不支持中文等特殊字符的,所有请使用英文名称,最好使用符合标识符的的英文名称

矢量切片的样式里明明配置了文字的样式但是文字不渲染?

可能是因为你在不支持文字的样式插件里配置了文字样式,比如 line,fill等,比如这样的的样式配置:

js
symbol: {
        lineColor: [0.741176, 0.741176, 0.741176, 1],
        lineWidth: {
          type: "exponential",
          default: 4,
          stops: [
            [14, 4],
            [16, 20]
          ]
        },
        textName:'{name}`
      }

矢量切片的样式渲染插件支持文字有:

  • icon 为点,线或者面类型数据绘制图标和文字的插件
  • text 为点,线或者面类型数据绘制文字的插件

所以如果希望为线,面等做文字标注,应该为线面等添加一个独立的文字标注样式item,比如这样:

js
{
      filter: ["all", ["==", "$layer", "provincial-highway"],
        ["==", "$type", "LineString"]
      ],
      renderPlugin: {
        dataConfig: {
          type: "line"
        },
        sceneConfig: {},
        type: "line"
      },
      symbol: {
        lineColor: [0.741176, 0.741176, 0.741176, 1],
        lineWidth: {
          type: "exponential",
          default: 4,
          stops: [
            [14, 4],
            [16, 20]
          ]
        }
      }
    },
    {
      filter: ["all", ["==", "$layer", "provincial-highway"],
        ["==", "$type", "LineString"]
      ],
      renderPlugin: {
        dataConfig: {
          type: "point"
        },
        sceneConfig: {
          collision: true,
          fading: true,
          depthFunc: "always"
        },
        type: "text"
      },
      symbol: {
        textFaceName: "Microsoft YaHei,sans-serif",
        textFill: [1, 1, 1, 1],
        textHaloFill: [0.0392156, 0.0392156, 0.0392156, 1],
        textHaloOpacity: 1,
        textHaloRadius: 1,
        textName: "{name}",
        textPitchAlignment: "viewport",
        textPlacement: "line",
        textRotationAlignment: "viewport",
        textSize: 20,
        textWrapWidth: 240
      }
    }

TIP

从上面我们可以看到:两个样式他们的数据集(有filter过滤提供)都是一样的,但是分别采用不同的渲染插件,从而来完成一个整体性的事情

矢量切片的样式里怎样给区域面设置边框?

区域面对应的渲染插件是fill,其是不支持边框的的(line),所以如果需要给区域面(Polygon)设置个line渲染插件 即可 Markdown 官方教程

js
{
      name: 'area-fill',
      filter: true,
      renderPlugin: {
        dataConfig: {
          type: "fill"
        },
        sceneConfig: {},
        type: "fill"
      },
      symbol: {
        polygonFill: "#996247",
        polygonOpacity: 1
      }
    },
    {
      name: 'area-border',
      filter: true,
      renderPlugin: {
        dataConfig: {
          type: "line"
        },
        sceneConfig: {},
        type: "line"
      },
      symbol: {
        lineColor: "#E2E2E2",
        lineOpacity: 1,
        lineWidth: 2
      }
    }

TIP

从上面我们可以看到:两个样式他们的数据集(有filter过滤提供)都是一样的,但是分别采用不同的渲染插件,从而来完成一个整体性的事情

Polygon设置贴图

PO7ZKWH%7B1OB%7BA60%24D0DYX8C.png

js
const center = map.getCenter(),
    radius = 2000;

const circle = new maptalks.Circle(center, radius);
layer.addGeometry(circle);

const extent = circle.getExtent();
console.log(extent);

const coord = [extent.xmin, extent.ymax];
circle.setSymbol({
    lineColor: "#00FF00",
    lineWidth: 2,
    polygonFill: "#00FF00",
    polygonOpacity: 0.5,
    polygonPatternFile: "./../assets/image/icon_famen.png",
    polygonPatternFileOrigin: coord,
    // uvOffset: [0.9, 1],
    polygonPatternFileWidth: radius * 2, // 与圆直径相同
    polygonPatternFileHeight: radius * 2, // 与圆直径相同
});
  • polygonPatternFileOrigin图形左上角的坐标
  • polygonPatternFileWidth的宽度,米
  • polygonPatternFileHeight的高度,米

polygon-polygonPatternFile demo

WARNING

因为图形内部要计算图形的uv坐标,需要用到投影的信息,所以要把图形先添加到图层, 这样就可以才能获取投影信息(map的spatialReference)。当图形没有加到图层上时,这时是无法获取到投影的 信息的,会采用WGS84的标准来计算的,这样就会导致计算的uv坐标不对

图标旋转问题

当marker的样式使用图标时(markerFile),垂直方向默认是底部对其的,旋转时也是的旋转点也是底部的点,

YF_ZLHE%25(G3GC3N%24~B8%24BED.png

为啥默认要底部对齐呢?

typescript
export type MarkerCommonSymbol = {
    markerOpacity?: SymbolNumberType;
    markerWidth?: SymbolNumberType;
    markerHeight?: SymbolNumberType;
    markerDx?: SymbolNumberType;
    markerDy?: SymbolNumberType;
    markerHorizontalAlignment?: "left" | "middle" | "right";
    markerVerticalAlignment?: "top" | "middle" | "bottom";
    markerPlacement?:
        | "point"
        | "vertex"
        | "line"
        | "vertex-first"
        | "vertex-last";
    markerRotation?: number;
};

因为地图上的图标一般都是尖尖的带锚点的图标

AFBH0%5B%24A8%60%5BA%24)I%24G86BZ%5DW.png

默认底部对齐可以和地图更好的结合以免造成视觉误差

如果想图标按照中心点(图标的中心点)旋转

)N%7B3U%60KFJ2TT%7BD%60LWIF(%7DXY.png

设置图标的垂直方向对其为middle即可

js
const point2 = new maptalks.Marker(map.getCenter().add(0.1, 0), {
    symbol: {
        markerFile: "./../assets/icon/avatar-women.png",
        markerVerticalAlignment: "middle",
    },
}).addTo(layer);

marker-rotation demo

如果你技艺高超你也可以利用canvas的api等来旋转图标,然后生成新的图标赋值给symbol也可

图片的资源最好不要使用base64

因为base64是个非常长的字符串,js层面维护大的字符串很占内存和性能,即使简单的读取该值速度也很慢,所以会导致整个地图的性能比较差,所以建议最好用图片地址

js
symbol: {
    markerFile: "./assets/images/poi.png";
}

VectorLayer图层内的图形少用阴影

js
symbol: {
    shadowBlur: 20;
    shadowColor: "red";
}

VectorLayer底层是canvas渲染的,canvas的阴影渲染时非常吃性能的,大面积的阴影会导致这个地图的性能急剧下降

maptalks教程 document auto generated by mdpress