GeoJSONcn
GeoJSONcn / 技术专栏 / 用 point-in-polyg…

用 point-in-polygon 判断经纬度落在哪个区县

发布于 2026-07-18 · GeoJSONcn 技术团队 · 阅读约 5 分钟

拿到一组 GPS 经纬度,想知道它落在哪个省、哪个市、哪个区县,这是 LBS 围栏、快递分区、人口统计里最常见的需求。思路其实很直接:做一次"点在多边形内"判定(point-in-polygon)。本文用全国四级行政区划 GeoJSON 边界数据,给出能直接跑的代码。

原理:射线法

对多边形和一点,从点向右引一条水平射线,数它穿过边界边的次数。奇数次说明点在里面,偶数次在外面。这就是 ray casting 算法,对凹多边形一样成立。

数据从哪来

本站提供全国省、市、区县、乡镇四级行政区划的 GeoJSON 边界数据,预览免费、下载付费。在线就能看每个区县的轮廓,下载原始数据做离线计算。

实战:用 turf.js 判定

安装:

npm install @turf/turf

代码:

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

// 读取全国区县 GeoJSON(FeatureCollection)
const districts = JSON.parse(fs.readFileSync('districts.geojson', 'utf8'));

// 待判定的 GPS 坐标 [经度, 纬度]
const point = turf.point([116.397, 39.908]);

let found = null;
for (const f of districts.features) {
  if (turf.booleanPointInPolygon(point, f)) {
    found = f.properties; // { name: '东城区', adcode: '110101', ... }
    break;
  }
}
console.log(found ? `命中:${found.name}(${found.adcode})` : '未命中任何区县');

booleanPointInPolygon 内部就是 ray casting。遍历一遍 FeatureCollection 就能定位坐标所属的区县。

性能:别硬遍历 3000 个多边形

全国有 3000 多个区县,每次请求都全量遍历并不划算。两个办法:

1. 逐级判定。先用省级边界过滤出所在省,再用该省市边界缩到市,最后在市内判定区县。候选集逐级缩小,判定次数从 3000 多降到几十。 2. 空间索引。turf 不自带索引,可以先用 rbush 给所有多边形 bbox 建 R-tree,用 bbox 粗筛,再对少数候选做精确判定。

坐标系要统一

GPS 设备输出的是 WGS84,天地图、高德这类国内底图用的是 GCJ-02(火星坐标系)。边界数据若是 WGS84、坐标却是 GCJ-02,判定会偏出几百米,直接落进隔壁区县。判定前把坐标和边界对齐到同一坐标系,做法见 WGS84 与 GCJ-02 一文。GeoJSON 基本结构可回顾 格式基础;手上是 Shapefile 或 KML 的,先看 格式批量转换 统一成 GeoJSON。

在线预览

不想自己搭环境,本站每个区县页面都能在线预览边界轮廓,预览免费、下载付费,对照行政区划代码就能核对。详见 Leaflet 渲染 GeoJSON。