基于JS实现《国家基本比例尺地形图分幅和编号》标准

1、标准

GB T 13989-2012国家基本比例尺地形图分幅和编号

地址:【高清版】GB T 13989-2012国家基本比例尺地形图分幅和编号 - 道客巴巴

2、1:100万比例尺

2.1 说明

2.2 计算公式

2.3 计算代码

2.3.1 元素数据定义

由于中国只到N层,所以只定义到O.

/**
   * 100万比例尺下的行号对应的代码
   */
  static mateData100 = [
    {
      rowCode: "A",
      rowNumber: 1,
    },
    {
      rowCode: "B",
      rowNumber: 2,
    },
    {
      rowCode: "C",
      rowNumber: 3,
    },
    {
      rowCode: "D",
      rowNumber: 4,
    },
    {
      rowCode: "E",
      rowNumber: 5,
    },
    {
      rowCode: "F",
      rowNumber: 6,
    },
    {
      rowCode: "G",
      rowNumber: 7,
    },
    {
      rowCode: "H",
      rowNumber: 8,
    },
    {
      rowCode: "I",
      rowNumber: 9,
    },
    {
      rowCode: "J",
      rowNumber: 10,
    },
    {
      rowCode: "K",
      rowNumber: 11,
    },
    {
      rowCode: "L",
      rowNumber: 12,
    },
    {
      rowCode: "M",
      rowNumber: 13,
    },
    {
      rowCode: "N",
      rowNumber: 14,
    },
    {
      rowCode: "O",
      rowNumber: 15,
    },
  ];
2.3.2 代码实现
/**
   * 根据经纬度计算100万比例尺的行列号
   * @param lon
   * @param lat
   * @return {{col: number, row: number, code: string}}
   */
  static calcMapFrameNumber100 = (lon, lat) => {
    let a = Math.trunc(lat / 4.0) + 1;
    let b = Math.trunc(lon / 6.0) + 31;
    let mateInfo = MapFrameUtils.mateData100.find(
      (item) => item.rowNumber === a
    );
    return {
      row: a,
      col: b,
      code: mateInfo.rowCode,
    };
  };

3、非100万比例尺

3.1 说明

3.1.1 2000到50万比例尺格式

3.1.2 500到1000比例尺格式

3.2 计算公式

3.3 代码

3.3.1 元数据
/**
   * 100万比例尺下的行号对应的代码
   */
  static mateData100 = [
    {
      rowCode: "A",
      rowNumber: 1,
    },
    {
      rowCode: "B",
      rowNumber: 2,
    },
    {
      rowCode: "C",
      rowNumber: 3,
    },
    {
      rowCode: "D",
      rowNumber: 4,
    },
    {
      rowCode: "E",
      rowNumber: 5,
    },
    {
      rowCode: "F",
      rowNumber: 6,
    },
    {
      rowCode: "G",
      rowNumber: 7,
    },
    {
      rowCode: "H",
      rowNumber: 8,
    },
    {
      rowCode: "I",
      rowNumber: 9,
    },
    {
      rowCode: "J",
      rowNumber: 10,
    },
    {
      rowCode: "K",
      rowNumber: 11,
    },
    {
      rowCode: "L",
      rowNumber: 12,
    },
    {
      rowCode: "M",
      rowNumber: 13,
    },
    {
      rowCode: "N",
      rowNumber: 14,
    },
    {
      rowCode: "O",
      rowNumber: 15,
    },
  ];
3.3.2 实现代码
/**
   * 根据比例尺,经纬度计算地图的行列号
   * @param scale
   * @param lon
   * @param lat
   * @return {{col: number, code: *, row: number, digit: (number|*)}|null}
   */
  static calcMapFrameNumberNot100 = (scale, lon, lat) => {
    let mateData = MapFrameUtils.mateData.find((item) => item.scale === scale);
    if (mateData) {
      let cStep = ((lat % 4) / mateData.latD).toPrecision(4);
      let c = Math.round(4 / mateData.latD - Math.trunc(Number(cStep)));
      let dStep = ((lon % 6) / mateData.lonD).toPrecision(4);
      let d = Math.trunc(Number(dStep)) + 1;
      return {
        row: c,
        col: d,
        code: mateData.code,
        digit: mateData.digit,
      };
    } else {
      return null;
    }
  };

4、综合代码

/**
 * 采用标准:国家基本比例尺地形图分幅和编号《GB/T 13989-2012》
 * 1、根据经纬度计算图幅号
 * 2、根据图幅号图幅范围计算
 * 3、定义图幅信息
 */
export default class MapFrameUtils {
  /**
   * 根据经纬度计算100万比例尺的行列号
   * @param lon
   * @param lat
   * @return {{col: number, row: number, code: string}}
   */
  static calcMapFrameNumber100 = (lon, lat) => {
    let a = Math.trunc(lat / 4.0) + 1;
    let b = Math.trunc(lon / 6.0) + 31;
    let mateInfo = MapFrameUtils.mateData100.find(
      (item) => item.rowNumber === a
    );
    return {
      row: a,
      col: b,
      code: mateInfo.rowCode,
    };
  };
  /**
   * 根据比例尺,经纬度计算地图的行列号
   * @param scale
   * @param lon
   * @param lat
   * @return {{col: number, code: *, row: number, digit: (number|*)}|null}
   */
  static calcMapFrameNumberNot100 = (scale, lon, lat) => {
    let mateData = MapFrameUtils.mateData.find((item) => item.scale === scale);
    if (mateData) {
      let cStep = ((lat % 4) / mateData.latD).toPrecision(4);
      let c = Math.round(4 / mateData.latD - Math.trunc(Number(cStep)));
      let dStep = ((lon % 6) / mateData.lonD).toPrecision(4);
      let d = Math.trunc(Number(dStep)) + 1;
      return {
        row: c,
        col: d,
        code: mateData.code,
        digit: mateData.digit,
      };
    } else {
      return null;
    }
  };
  /**
   * 根据计算出来的行列号,比例尺,计算该格网在地图商的范围
   * @param frame100
   * @param frameNot100
   * @param scale
   * @return {{minY: number, minX: number, maxY: number, maxX: number}}
   */
  static calcMapFrameExtent = (frame100, frameNot100, scale) => {
    let mateData = MapFrameUtils.mateData.find((item) => item.scale === scale);
    let lon = (frame100.col - 31) * 6 + (frameNot100.col - 1) * mateData.lonD;
    let lat =
      (frame100.row - 1) * 4 +
      (4 / mateData.latD - frameNot100.row) * mateData.latD;

    return {
      minX: lon,
      minY: lat,
      maxX: lon + mateData.lonD,
      maxY: lat + mateData.latD,
    };
  };
  /**
   * 根据比例尺和经纬度,获取所在图幅范围的编号、行列号以及范围
   * @param scale
   * @param lon
   * @param lat
   * @return {null|{extent: {minY: number, minX: number, maxY: number, maxX: number}, col: number, code: string, row: number}}
   */
  static calcMapFrameNumber = (scale, lon, lat) => {
    let mapFrameNumber100 = MapFrameUtils.calcMapFrameNumber100(lon, lat);
    let mapFrameNumberNot100 = MapFrameUtils.calcMapFrameNumberNot100(
      scale,
      lon,
      lat
    );
    if (mapFrameNumberNot100) {
      let code =
        mapFrameNumber100.code +
        "" +
        mapFrameNumber100.col +
        "" +
        mapFrameNumberNot100.code +
        "" +
        mapFrameNumberNot100.row
          .toString()
          .padStart(mapFrameNumberNot100.digit, "0") +
        "" +
        mapFrameNumberNot100.col
          .toString()
          .padStart(mapFrameNumberNot100.digit, "0");
      let extent = MapFrameUtils.calcMapFrameExtent(
        mapFrameNumber100,
        mapFrameNumberNot100,
        scale
      );
      return {
        code: code,
        extent: extent,
        row: mapFrameNumberNot100.row,
        col: mapFrameNumberNot100.col,
      };
    } else {
      return null;
    }
  };
  /**
   * 100万比例尺下的行号对应的代码
   */
  static mateData100 = [
    {
      rowCode: "A",
      rowNumber: 1,
    },
    {
      rowCode: "B",
      rowNumber: 2,
    },
    {
      rowCode: "C",
      rowNumber: 3,
    },
    {
      rowCode: "D",
      rowNumber: 4,
    },
    {
      rowCode: "E",
      rowNumber: 5,
    },
    {
      rowCode: "F",
      rowNumber: 6,
    },
    {
      rowCode: "G",
      rowNumber: 7,
    },
    {
      rowCode: "H",
      rowNumber: 8,
    },
    {
      rowCode: "I",
      rowNumber: 9,
    },
    {
      rowCode: "J",
      rowNumber: 10,
    },
    {
      rowCode: "K",
      rowNumber: 11,
    },
    {
      rowCode: "L",
      rowNumber: 12,
    },
    {
      rowCode: "M",
      rowNumber: 13,
    },
    {
      rowCode: "N",
      rowNumber: 14,
    },
    {
      rowCode: "O",
      rowNumber: 15,
    },
  ];
  /**
   * 非100万情况下,不同比例尺的原始数据
   */
  static mateData = [
    {
      scale: 500000,
      label: "1:50万",
      lonD: 3,
      latD: 2,
      code: "B",
      digit: 3,
    },
    {
      scale: 250000,
      label: "1:25万",
      lonD: 1.5,
      latD: 1,
      code: "C",
      digit: 3,
    },
    {
      scale: 100000,
      label: "1:10万",
      lonD: 0.5,
      latD: 0.33333333,
      code: "D",
      digit: 3,
    },
    {
      scale: 50000,
      label: "1:5万",
      lonD: 0.25,
      latD: 0.16666667,
      code: "E",
      digit: 3,
    },
    {
      scale: 25000,
      label: "1:2.5万",
      lonD: 0.125,
      latD: 0.08333333,
      code: "F",
      digit: 3,
    },
    {
      scale: 10000,
      label: "1:1万",
      lonD: 0.0625,
      latD: 0.04166667,
      code: "G",
      digit: 3,
    },
    {
      scale: 5000,
      label: "1:5000",
      lonD: 0.03125,
      latD: 0.02083333,
      code: "H",
      digit: 3,
    },
    {
      scale: 2000,
      label: "1:2000",
      lonD: 0.01041667,
      latD: 0.006944444,
      code: "I",
      digit: 3,
    },
    {
      scale: 1000,
      label: "1:1000",
      lonD: 0.005208333,
      latD: 0.003472222,
      code: "J",
      digit: 4,
    },
    {
      scale: 500,
      label: "1:500",
      lonD: 0.002603889,
      latD: 0.001736111,
      code: "K",
      digit: 4,
    },
  ];
}

5、测试结果

5.1 测试代码

MapFrameUtils.mateData.forEach((item) => {
  let mapFrame = MapFrameUtils.calcMapFrameNumber(item.scale, 114.5625, 39.375);
  console.log(item.scale, mapFrame);
});

5.2 测试结果

与标准中结果一致

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/681649.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自动控制:控制系统的灵敏度分析

自动控制:控制系统的灵敏度分析 引言 灵敏度问题在控制系统设计中至关重要。灵敏度衡量的是系统对参数变化和扰动的响应程度。本文将详细探讨灵敏度函数的概念,并推导出开环和闭环控制系统在前向路径和反馈路径元素扰动下的灵敏度表达式。 灵敏度概念…

8款监控电脑屏幕的软件排名(屏幕监控软件TOP8)

8款监控电脑屏幕的软件排名(屏幕监控软件TOP8) 作为企业管理者都想对企业的员工和电脑设备了如指掌,毕竟日防夜防家贼难防,利用电脑泄密者数不胜数,为此需要对电脑屏幕实施监控,小编为你推荐几个屏幕监控软…

vue3中 window绑定scroll事件滚动页面获取不到e.target.scrollTop

遇到的问题 vue3项目 onMounted(() > {window.addEventListener(scroll, (e) > {console.log(e.target.scrollTop)}) })想要监听页面中的滚动,然后获取滚动距离实现一些功能,发现event参数中获取不到e.target.scrollTop(印象中以前使…

Java Web学习笔记2——Web开发介绍

什么是Web? Web:全球广域网,也称为万维网(WWW World Wide Web),能够通过浏览器访问的网站。 1)淘宝、京东、唯品会等电商系统; 2)CRM、OA、ERP企业管理系统&#xff1…

Wi-Fi 6E vs. Wi-Fi 7: Which is the Best Fit for Your Infrastructure?

Wi-Fi 6E vs. Wi-Fi 7: Which is the Best Fit for Your Infrastructure? With the rapid advancement of wireless technology, organizations face a critical decision: should they adopt Wi-Fi 6E now or wait for Wi-Fi 7? This decision impacts various aspects of …

isp效果库相关参数——镜像翻转

前言 之前一直比较忙着接触新工作内容,所以有一段搁置期,但是工作中的知识点还是有一直记录的,只是没空发出来,毕竟需要先熟悉才能总结内容,接下来的几天会连着发布 不同的产品数据手册有着不同的叫法但是统一的意思离…

【成品设计】基于IAP15W4K的久坐提醒器

《基于IAP15W4K的久坐提醒器》 整体功能: 作品名称:《基于IAP15W4K61S4的久坐提醒器》 作品器件: 单片机:IAP15W4K61S4 2.人体感应模块: 引脚连接: 1.VCC:正极 3.3-5V供电 2.GND:…

为什么要选择软件开发外包?降本增效共创共赢

►开发外包是什么? 软件开发外包就是将企业的软件开发项目交给外部的专业团队或个人来完成,这些外包团队通常具备丰富的技术经验和专业的开发能力,能够根据企业的需求,提供定制化的软件开发服务。通过外包,企业可以节…

FarmersWorld农民世界源码开发:0撸卷轴+潮玩模式

一、引言 随着科技的发展,游戏产业日益壮大,一种新型的游戏形式——零撸游戏应运而生。本文将深入探讨FarmersWorld农民世界源码开发,以其独特的0撸卷轴潮玩模式,为玩家带来全新的游戏体验。 二、源码开发的专业性和深度 Farmer…

会声会影2024官方旗舰版最新版评测

随着数字内容创作的兴起,越来越多的人开始关注视频制作领域。对于初学者和专业人士来说,选择一款适合自己的视频编辑软件是非常重要的。今天,我将为大家全面而深入地评测会声会影2024最新版,从易用性、功能性以及性价比方面进行评…

2022.9.26DAY678

课程学习:《数据处理技术》讲了“数据查询”的语法格式,语法格式也算是简单,就是没能跟之前的内容联系起来,之前的内容没有及时回顾。 高等数学:“ 函数的概念”,讲了函数的概念,反函数&#…

ant-design vue3 中上传图片组件的回传图片显示问题

最近在做web端的上传图片 有一个数据列表中的编辑功能 是之前上传的图片 点击编辑进入编辑页面 会显示之前写的数据 现在需要把原来上传的图片 显示出来 因为之前给后端上传的 图片格式 是一个数组 ["图片链接",“图片链接”。。。] 后端给我返回的数据也…

AI菜鸟向前飞 — LangChain系列之十六 - Agent系列:从现象看机制(下篇)一款“无需传递中间步骤“的Agent

前言 AI菜鸟向前飞 — LangChain系列之十四 - Agent系列:从现象看机制(上篇) AI菜鸟向前飞 — LangChain系列之十五 - Agent系列:从现象看机制(中篇)一个Agent的“旅行” 回顾前两篇文章,大家会…

Java实现一个公共方法解析不同类型的表格

首先是公共方法 private String getCellValueAsString(Cell cell) {if (cell null) {return "";}String value "";switch (cell.getCellType()) {case STRING:value cell.getStringCellValue();break;case NUMERIC:if (DateUtil.isCellDateFormatted(ce…

D435相机结合Yolo V8识别出目标物体,并转点云出抓取位姿。

最近项目上需要完成整个识别、定位、到最后的抓取流程。 分享一下,通过使用D435相机并结合Yolo V8识别出目标物体后,抠取出目标物体部分的有效深度图,最后将前景物体部分的RGB D435相机结合Yolo V8识别出目标物体,并转点云出抓取位…

mac虚拟光驱工具:Daemon Tools for Mac

Daemon Tools for Mac是一款功能强大的虚拟光驱工具,它为用户提供了在Mac上模拟物理光驱的能力,从而方便用户处理各种光盘映像文件。以下是关于Daemon Tools for Mac的详细介绍: 守护进程工具:Daemon Tools不仅是一个简单的虚拟光…

废品回收小程序开发,助力商家拓展回收市场

随着互联网的快速发展,废品回收行业也走向了数字化发展,废品回收小程序成为了拓展市场的重要方式。在当下万亿元下的回收市场中,废品回收小程序的发展也能够发挥重要作用,提高市场回收效率,提高大众的回收意识&#xf…

前端 Web 与原生应用端 WebView 通信交互 - HarmonyOS Next

基于鸿蒙 HarmonyOS Next 与前端 Vue 通信交互相关小结; DevEco Studio NEXT Developer Preview2 Vue js 两端相互拟定好协议后,通过前端页面的点击事件,将所需的数据传输给原生移动端组件方法中,处理后将消息回传至前端. 根据官方文档的案例尝试,但没成功 ... 后经过几经尝试…

github删除某个仓库

在GitHub上删除一个仓库,按照以下步骤操作: 1、登录到GitHub账户。 2、导航到想要删除的仓库页面。 3、点击仓库页面上的"Settings"(设置)选项卡。 4、向下滚动到页面底部,找到"Danger Zone"&…

【Linux多线程】LWP和pthread_t

文章目录 LWPclone系统调用查看线程LWP理解LWP与TID pthread_id LWP LWP是Linux中线程的具体实现形式,在linux中,进程和线程本质上都是相同的,都是通过task_struct结构体来表示的。LWP是内核级线程,TID是其唯一标识符&#xff0c…