数据源;https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json
// 判断点是否在多边形(外环/内洞)内
function isPointInPolygon(point, polygon) {
const [outerRing, ...holes] = polygon; // 外环和内洞
const isInOuterRing = isPointInRing(point, outerRing);
if (!isInOuterRing) return false; // 点不在外环内,直接返回 false
// 判断点是否在内洞内
for (const hole of holes) {
if (isPointInRing(point, hole)) {
return false; // 点在内洞内,返回 false
}
}
return true; // 点在外环内且不在任何内洞内
}
// 判断点是否在一个环(简单多边形)内
function isPointInRing(point, ring) {
const x = point.lng;
const y = point.lat;
let isInside = false;
for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
const xi = ring[i][0], yi = ring[i][1];
const xj = ring[j][0], yj = ring[j][1];
const intersect =
yi > y !== yj > y &&
x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
if (intersect) isInside = !isInside;
}
return isInside;
}
// 根据经纬度获取省份(支持 Polygon 类型)
export function getProvinceByCoordinates(point) {
for (const feature of geoData.features) {
const { name } = feature.properties;
const coordinates = feature.geometry.coordinates;
// Geometry Type 是 Polygon
if (feature.geometry.type === "Polygon") {
if (isPointInPolygon(point, coordinates)) {
return name;
}
}
// Geometry Type 是 MultiPolygon
if (feature.geometry.type === "MultiPolygon") {
for (const polygon of coordinates) {
if (isPointInPolygon(point, polygon)) {
return name;
}
}
}
}
return null;
}
// 示例数据(你的 GeoJSON 数据)
const geoData = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"adcode": 110000,
"name": "北京市",
"center": [116.405285, 39.904989],
"centroid": [116.41995, 40.18994],
"childrenNum": 16,
"level": "province",
"parent": { "adcode": 100000 },
"subFeatureIndex": 0,
"acroutes": [100000],
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[117.348611, 40.581141],
[117.389879, 40.561593],
[117.429915, 40.576141],
[117.412669, 40.605226],
[117.467487, 40.649738],
[117.467487, 40.649738],
[117.501364, 40.636569],
[117.514914, 40.660181],
[117.493973, 40.675161],
[117.408973, 40.686961],
[117.342451, 40.673799],
[117.319662, 40.657911],
[117.278394, 40.664267],
[117.208177, 40.694675],
[117.117018, 40.70012],
[117.11209, 40.707379],
[117.012308, 40.693767],
[116.964881, 40.709647],
[116.926692, 40.745022],
[116.924229, 40.773581],
[116.848468, 40.839264],
[116.81336, 40.848319],
[116.759773, 40.889954],
[116.713577, 40.909858],
[116.722201, 40.927495],
[116.677853, 40.970888],
[116.698795, 41.021477],
[116.688324, 41.044501],
[116.647672, 41.059394],
[116.615643, 41.053076],
[116.623034, 41.021026],
[116.598397, 40.974503],
[116.5676, 40.992574],
[116.519557, 40.98128],
[116.519557, 40.98128],
[116.455499, 40.980828],
[116.447492, 40.953715],
[116.477057, 40.899907],
[116.398216, 40.90624],
[116.370499, 40.94377],
[116.339702, 40.929303],
[116.334159, 40.90443],
[116.438253, 40.81934],
[116.46597, 40.774487],
[116.453651, 40.765876],
[116.316912, 40.772221],
[116.311369, 40.754996],
[116.273181, 40.762703],
[116.247311, 40.791707],
[116.22021, 40.744115],
[116.204812, 40.740035],
[116.171551, 40.695582],
],
],
],
},
},
// 其他省份数据...
],
};
// 测试点
const point = { lat: 39.9, lng: 116.4 }; // 北京的经纬度
const province = getProvinceByCoordinates(point, geoData);
console.log(province); // 输出: 北京市
json快捷转ts类型的扩展:https://marketplace.visualstudio.com/items?itemName=GregorBiswanger.json2ts
vscode安装之后 ctrl+alt+V
即可生成类型
评论区