Canvas中绘制Geojson数据示例详解

 更新时间:2022年11月17日 09:54:58   作者:uccs  
这篇文章主要为大家介绍了Canvas中绘制Geojson数据示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

需求分析

在做地图开发的时候遇到一个需求,是在 canvas 中绘制 Geojson 数据

数据格式为 EPSG:4326Polygon

  • 三维数组
  • 每一项都是由经纬度组成的
  • 第一个点和最后一个点相同,表示 Polygon 是闭合的
[
  [
    [109.54420471485196, 35.76192112844663],
    [109.54423617129702, 35.76132766033574],
    [109.54539219590997, 35.76155739029704],
    [109.54521918540507, 35.76241249100947],
    [109.54420471485196, 35.76192112844663],
  ],
];

需求分析:

  • 显示在 canvas 的中间
  • 地图 y 轴和屏幕的 y 轴是相反的,绘制出来的 Polygon 不能和实际反过来
    • 屏幕的原点在左上角,地图的原点在左下角

数据处理

widthheightcanvas 的宽高

将经度和纬度单独拆分出来

const getLongitudesAndLatitudes = (coordinates: number[][][]) => {
  return coordinates[0].reduce(
    (pre, cur) => {
      pre.longitudes.push(cur[0]);
      pre.latitudes.push(cur[1]);
      return pre;
    },
    { longitudes: [] as number[], latitudes: [] as number[] }
  );
};

得到的结果是:

const longitudes = [
  109.54420471485196, 109.54423617129702, 109.54539219590997,
  109.54521918540507, 109.54420471485196,
];
const latitudes = [
  35.76192112844663, 35.76132766033574, 35.76155739029704, 35.76241249100947,
  35.76192112844663,
];

计算缩放比例

width / (Math.max(longitudes) - Math.min(longitudes)) 的作用计算 Polygonx 轴缩放比例 xScale = 67369.49567346855

height 同理,计算出 y 轴的缩放比例 yScale = 12905.23981205731

总的缩放比例 scale 采用 xScaleyScale 谁小用谁,为 scale = 12905.23981205731,因为用小的缩放比例,才能在有限的空间下显示全

const calcScale = ({
  longitudes,
  latitudes,
}: {
  longitudes: number[];
  latitudes: number[];
}) => {
  const xScale =
    width / Math.abs(Math.max(...longitudes) - Math.min(...longitudes));
  const yScale =
    height / Math.abs(Math.max(...latitudes) - Math.min(...latitudes));
  return xScale < yScale ? xScale : yScale;
};

计算偏移度

(Math.max(longitudes) - Math.min(longitudes)) * scale 作用是将经度按照 scale 进行缩放,纬度也是同理

在用 widthheight 去减,分别得到要 x 轴和 y 轴需要偏移的空间

这些空间要分布在两边,也就是说要分布 Polygon的周围,所以左后需要除 2,最终得到 xOffset = 32.33763608704606yOffset = -8.881784197001252e-16

const calcOffset = (
  { longitudes, latitudes }: { longitudes: number[]; latitudes: number[] },
  scale: number
) => {
  const xOffset =
    (width -
      Math.abs(Math.max(...longitudes) - Math.min(...longitudes)) * scale) /
    2;
  const yOffset =
    (height -
      Math.abs(Math.max(...latitudes) - Math.min(...latitudes)) * scale) /
    2;
  return { xOffset, yOffset };
};

将 Coordinates 进行缩放

coordinates 缩放一共分为 3

比较难理解的是第一步,为什么要将每个点去减它的最小值 item[0] - Math.min(...longitudes)

这样做的目的是为了那个点无限接近于原点,接近原点后,再通过乘以缩放比例和加上偏移度,得到最终的的缩放值

在需求分析时说了,屏幕的原点在左上角,地图的原点在左下角,所以 y 轴是刚好是相反,y 轴就用 Math.max(...latitudes) - item[1]

const scaleCoordinates = (
  coordinates: number[][][],
  scale: number,
  offset: ReturnType<typeof calcOffset>,
  { longitudes, latitudes }: { longitudes: number[]; latitudes: number[] }
) => {
  return coordinates[0]
    .map((item) => {
      item[0] = item[0] - Math.min(...longitudes);
      item[1] = Math.max(...latitudes) - item[1];
      return item;
    })
    .map((item) => {
      item[0] = item[0] * scale;
      item[1] = item[1] * scale;
      return item;
    })
    .map((item) => {
      item[0] = item[0] + offset.xOffset;
      item[1] = item[1] + offset.yOffset;
      return item;
    });
};

使用 Canvas 进行绘制

const canvas = document.getElementById("canvas");
if (!canvas.getContext) return;
const ctx = canvas!.getContext("2d")!;
ctx.fillStyle = "rgba(32, 210, 255, 0.3)";
ctx.strokeStyle = "rgba(32, 210, 255, 1)";
ctx.beginPath();
ctx.moveTo(coordinates[0][0], coordinates[0][1]);
for (let i = 1; i < coordinates.length; i++) {
  ctx.lineTo(coordinates[i][0], coordinates[i][1]);
}
ctx.closePath();
ctx.stroke();
ctx.fill();

存在问题

无法区分 Polygon 大小,所以这个方案适用于绘制缩略图

以上就是Canvas中绘制Geojson数据示例详解的详细内容,更多关于Canvas绘制Geojson数据的资料请关注脚本之家其它相关文章!

相关文章

  • JS使用AudioContext实现音频流实时播放

    JS使用AudioContext实现音频流实时播放

    这篇文章主要为大家详细介绍了JavaScript如何使用AudioContext实现音频流实时播放功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • 输入密码时检测大写是否锁定的js代码

    输入密码时检测大写是否锁定的js代码

    网站登录为了更好的用户体验都会在输入密码的时候检测是否开启大写。提醒用户。
    2011-02-02
  • JavaScript正则表达式实例详解

    JavaScript正则表达式实例详解

    在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
    2016-10-10
  • webpack4.x CommonJS模块化浅析

    webpack4.x CommonJS模块化浅析

    这篇文章主要介绍了webpack4.x CommonJS模块化浅析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • javaScript矢量图表库-gRaphael几行代码实现精美的条形图/饼图/点图/曲线图

    javaScript矢量图表库-gRaphael几行代码实现精美的条形图/饼图/点图/曲线图

    gRaphael是一个致力于帮助开发人员在网页中绘制各种精美图表的 Javascript库,你只需要编写几行简单的代码就能创建出精美的条形图、饼图、点图和曲线图,感兴趣的朋友可以了解下
    2013-01-01
  • Three.js加载外部模型的教程详解

    Three.js加载外部模型的教程详解

    这篇文章主要介绍了Three.js外部模型加载的教程详解,在文章给大家补充介绍了three.js 外部模型加载json的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-11-11
  • js propertychange和oninput事件

    js propertychange和oninput事件

    项目中常遇到输入框检查的需求,比如即时搜索,用change事件?change事件失去焦点才发生,无法做到即时。keypresss事件?能监听到键盘,但监听不到鼠标复制粘贴,不完美
    2014-09-09
  • Next.js应用转换为TypeScript方法demo

    Next.js应用转换为TypeScript方法demo

    这篇文章主要为大家介绍了Next.js应用转换为TypeScript方法demo,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • JS实现拖动模态框案例

    JS实现拖动模态框案例

    这篇文章主要为大家详细介绍了JS实现拖动模态框案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • 小程序实现页面跳转与数据传递方案

    小程序实现页面跳转与数据传递方案

    在开发过程中经常会遇到在微信小程序的页面跳转以及数据传递的知识点,所以下面这篇文章主要给大家介绍了关于小程序实现页面跳转与数据传递的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09

最新评论