本地/离线/无网络情况下 Node.js 根据经纬度转地址 和 行政编码 Adcode

发布于 2024-09-02 10:58:34 字数 4311 浏览 12 评论 0

在 Node.js 中,根据经纬度查找对应的区域信息,通常需要以下几个步骤:

  1. 加载 GeoJSON 数据 :首先,你需要将 GeoJSON 数据加载到你的 Node.js 应用中。
  2. 解析经纬度 :然后,你需要解析输入的经纬度信息。
  3. 点在多边形内的判断 :使用一个点在多边形内的算法来判断给定的经纬度是否在某个区域内。这通常使用射线法或其他算法来实现。

以下是一个示例代码,展示了如何完成这些步骤:

安装必要的库

你可以使用 geojsonturf 这些库来处理 GeoJSON 数据和空间分析。在终端中运行以下命令安装这些库:

npm install @turf/turf geojson

示例代码

const turf = require('@turf/turf');
const fs = require('fs');

// 读取 GeoJSON 数据(假设存储在 "data.geojson" 文件中)
const geojsonData = JSON.parse(fs.readFileSync('data.geojson', 'utf8'));

// 经纬度
const lon = -122.431297;
const lat = 37.773972;

// 创建点对象
const point = turf.point([lon, lat]);

// 遍历 GeoJSON 数据中的每个区域
geojsonData.features.forEach(feature => {
  if (feature.geometry.type === 'Polygon' || feature.geometry.type === 'MultiPolygon') {
    const polygon = feature.geometry;

    let isInside = false;
    if (polygon.type === 'Polygon') {
      isInside = turf.booleanPointInPolygon(point, polygon);
    } else if (polygon.type === 'MultiPolygon') {
      isInside = polygon.coordinates.some(poly => turf.booleanPointInPolygon(point, turf.polygon(poly)));
    }

    if (isInside) {
      console.log('The point is inside the region:', feature.properties);
    }
  }
});

代码解释

  1. 读取 GeoJSON 数据 :从文件中读取 GeoJSON 数据,假设数据是一个有效的 GeoJSON 对象。
  2. 创建点对象 :使用 turf.point() 方法创建一个点对象,这里经纬度为 [lon, lat]
  3. 判断点是否在区域内
  • 对于 Polygon 类型的区域,直接使用 turf.booleanPointInPolygon() 方法来判断点是否在区域内。
  • 对于 MultiPolygon 类型的区域,遍历每个多边形,检查点是否在其中的任意一个多边形内。
  1. 输出结果 :如果点在某个区域内,打印相关区域的属性信息。

注意事项

  • 确保 GeoJSON 数据是有效的,并且包含 PolygonMultiPolygon 类型的几何数据。
  • turf.booleanPointInPolygon() 方法用于检查点是否在给定的多边形内。

你可以根据具体需求对这段代码进行调整,例如处理不同类型的 GeoJSON 数据或添加更多的错误处理。

性能优化

在处理点是否在多边形内的判断时,性能优化是很重要的,尤其是当有大量的点和区域时。 turf.booleanPointInPolygon 已经是一个相对高效的方法,但如果你需要进一步优化性能,可以考虑以下方法:

使用空间索引

空间索引(如 R-树)能够显著提高查询效率,特别是当你有大量的多边形和点时。 rbush 是一个实现 R-树的库,可以在 Node.js 中使用。以下是如何结合 rbushturf 来进行优化的示例:

安装必要的库

npm install @turf/turf

示例代码

const rbush = require('./rbush.js');
const turf = require('@turf/turf');
const fs = require('fs');

// 读取 GeoJSON 数据
const geojsonData = JSON.parse(fs.readFileSync('data.geojson', 'utf8'));

// 创建空间索引
const index = rbush();

// 准备数据
const indexedPolygons = geojsonData.features
  .filter(feature => feature.geometry.type === 'Polygon' || feature.geometry.type === 'MultiPolygon')
  .map(feature => {
    const bbox = turf.bbox(feature);
    return { minX: bbox[0], minY: bbox[1], maxX: bbox[2], maxY: bbox[3], feature };
  });

index.load(indexedPolygons);

// 经纬度
const lon = -122.431297;
const lat = 37.773972;

// 创建点对象
const point = turf.point([lon, lat]);

// 查找可能的区域
const bbox = turf.bbox(turf.point([lon, lat]));
const possibleRegions = index.search({ minX: bbox[0], minY: bbox[1], maxX: bbox[2], maxY: bbox[3] });

// 检查点是否在这些区域内
possibleRegions.forEach(region => {
  const polygon = region.feature.geometry;
  let isInside = false;

  if (polygon.type === 'Polygon') {
    isInside = turf.booleanPointInPolygon(point, polygon);
  } else if (polygon.type === 'MultiPolygon') {
    isInside = polygon.coordinates.some(poly => turf.booleanPointInPolygon(point, turf.polygon(poly)));
  }

  if (isInside) {
    console.log('The point is inside the region:', region.feature.properties);
  } });

源码下载:https://www.wenjiangs.com/wp-content/uploads/2024/08/find-local.zip

GeoJSON 数据下载: https://datav.aliyun.com/portal/school/atlas/area_selector

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
22 人气
更多

推荐作者

安静被遗忘

文章 0 评论 0

喔爱吃橙子

文章 0 评论 0

草莓味的萝莉

文章 0 评论 0

梦里兽

文章 0 评论 0

mb_83J3Cyxa

文章 0 评论 0

时间海

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文