fix(api): 替换所有接口请求的域名为 guilixu-api.websoft.top
- 将获取 STS Token 的接口地址由 paopao-api 改为 guilixu-api - 更新图片上传接口地址为新的 guilixu-api 域名 - 修改用户推广页面中邀请码链接和二维码接口的域名 - 更改注册页微信登录接口请求的域名为 guilixu-api
This commit is contained in:
131
src/utils/geofence.ts
Normal file
131
src/utils/geofence.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
export type LngLat = { lng: number; lat: number }
|
||||
|
||||
function normalizeLngLat(a: number, b: number): LngLat | null {
|
||||
if (!Number.isFinite(a) || !Number.isFinite(b)) return null
|
||||
const looksLikeLngLat = Math.abs(a) <= 180 && Math.abs(b) <= 90
|
||||
const looksLikeLatLng = Math.abs(a) <= 90 && Math.abs(b) <= 180
|
||||
if (looksLikeLngLat) return { lng: a, lat: b }
|
||||
if (looksLikeLatLng) return { lng: b, lat: a }
|
||||
return null
|
||||
}
|
||||
|
||||
function parsePointLike(v: any): LngLat | null {
|
||||
if (!v) return null
|
||||
if (Array.isArray(v) && v.length >= 2) {
|
||||
return normalizeLngLat(Number(v[0]), Number(v[1]))
|
||||
}
|
||||
if (typeof v === 'object') {
|
||||
const a = v.lng ?? v.lon ?? v.longitude ?? v.x
|
||||
const b = v.lat ?? v.latitude ?? v.y
|
||||
if (a !== undefined && b !== undefined) {
|
||||
return normalizeLngLat(Number(a), Number(b))
|
||||
}
|
||||
}
|
||||
if (typeof v === 'string') {
|
||||
return parseLngLatFromText(v)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function parseLngLatFromText(raw: string | undefined): LngLat | null {
|
||||
const text = (raw || '').trim()
|
||||
if (!text) return null
|
||||
const parts = text.split(/[,\s]+/).filter(Boolean)
|
||||
if (parts.length < 2) return null
|
||||
const a = parts[0]
|
||||
const b = parts[1]
|
||||
if (!a || !b) return null
|
||||
return normalizeLngLat(parseFloat(a), parseFloat(b))
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse fence "points" into a polygon point list.
|
||||
*/
|
||||
export function parseFencePoints(pointsRaw: string | undefined): LngLat[] {
|
||||
const text = (pointsRaw || '').trim()
|
||||
if (!text) return []
|
||||
|
||||
if (text.startsWith('[') || text.startsWith('{')) {
|
||||
try {
|
||||
const parsed = JSON.parse(text)
|
||||
if (Array.isArray(parsed)) {
|
||||
const list = parsed.map(parsePointLike).filter(Boolean) as LngLat[]
|
||||
if (list.length) return list
|
||||
if (Array.isArray(parsed[0])) {
|
||||
const inner = (parsed[0] as any[]).map(parsePointLike).filter(Boolean) as LngLat[]
|
||||
if (inner.length) return inner
|
||||
}
|
||||
}
|
||||
} catch (_e) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
|
||||
const segments = text.split(/[;|\n\r]+/).map(s => s.trim()).filter(Boolean)
|
||||
if (segments.length > 1) {
|
||||
const list = segments.map(seg => {
|
||||
const nums = seg.match(/-?\d+(\.\d+)?/g) || []
|
||||
if (nums.length < 2) return null
|
||||
const a = nums[0]
|
||||
const b = nums[1]
|
||||
if (!a || !b) return null
|
||||
return normalizeLngLat(parseFloat(a), parseFloat(b))
|
||||
}).filter(Boolean) as LngLat[]
|
||||
if (list.length) return list
|
||||
}
|
||||
|
||||
const nums = text.match(/-?\d+(\.\d+)?/g) || []
|
||||
if (nums.length >= 6 && nums.length % 2 === 0) {
|
||||
const list: LngLat[] = []
|
||||
for (let i = 0; i < nums.length; i += 2) {
|
||||
const a = nums[i]
|
||||
const b = nums[i + 1]
|
||||
if (!a || !b) continue
|
||||
const p = normalizeLngLat(parseFloat(a), parseFloat(b))
|
||||
if (p) list.push(p)
|
||||
}
|
||||
if (list.length) return list
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
function pointOnSegment(p: LngLat, a: LngLat, b: LngLat, eps = 1e-9): boolean {
|
||||
const cross = (b.lat - a.lat) * (p.lng - a.lng) - (b.lng - a.lng) * (p.lat - a.lat)
|
||||
if (Math.abs(cross) > eps) return false
|
||||
const dot = (p.lng - a.lng) * (b.lng - a.lng) + (p.lat - a.lat) * (b.lat - a.lat)
|
||||
if (dot < -eps) return false
|
||||
const lenSq = (b.lng - a.lng) ** 2 + (b.lat - a.lat) ** 2
|
||||
return dot <= lenSq + eps
|
||||
}
|
||||
|
||||
export function pointInPolygon(p: LngLat, polygon: LngLat[]): boolean {
|
||||
if (!polygon || polygon.length < 3) return false
|
||||
|
||||
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
||||
const a = polygon[j]
|
||||
const b = polygon[i]
|
||||
if (pointOnSegment(p, a, b)) return true
|
||||
}
|
||||
|
||||
let inside = false
|
||||
const x = p.lng
|
||||
const y = p.lat
|
||||
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
||||
const xi = polygon[i].lng
|
||||
const yi = polygon[i].lat
|
||||
const xj = polygon[j].lng
|
||||
const yj = polygon[j].lat
|
||||
|
||||
const intersect = (yi > y) !== (yj > y) && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi
|
||||
if (intersect) inside = !inside
|
||||
}
|
||||
return inside
|
||||
}
|
||||
|
||||
export function pointInAnyPolygon(p: LngLat, polygons: LngLat[][]): boolean {
|
||||
for (const poly of polygons) {
|
||||
if (pointInPolygon(p, poly)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user