Files
OpenFlare/internal/apps/openflare/geoip/node.go
T
ryan 8751c0dee3 fix(openflare): mmdb 国家名节点在世界地图使用正确质心
- 从 world-geo 生成国家质心表,Server 在仅有 ISO/国家名时补全 geo 坐标
- 全球态势板在缺少经纬度时按 geo_name 解析质心,避免 fallback 到美国
2026-06-20 19:46:33 +08:00

73 lines
1.7 KiB
Go

// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
package geoip
import (
"context"
"net"
"strings"
"github.com/Rain-kl/Wavelet/internal/model"
pkggeoip "github.com/Rain-kl/Wavelet/pkg/geoip"
"github.com/Rain-kl/Wavelet/pkg/logger"
)
// ApplyNodeGeoFromIP resolves geographic metadata for node when geo is not manually locked.
func ApplyNodeGeoFromIP(ctx context.Context, node *model.OpenFlareNode, rawIP string) {
if node == nil || node.GeoManualOverride {
return
}
node.GeoName = ""
node.GeoLatitude = nil
node.GeoLongitude = nil
ip := net.ParseIP(strings.TrimSpace(rawIP))
if ip == nil {
return
}
info, err := GeoInfoFromIP(ip)
if err != nil {
logger.WarnF(ctx, "[GeoIP] resolve node geo failed: ip=%s error=%v", ip.String(), err)
return
}
if info == nil {
return
}
if strings.TrimSpace(info.Name) != "" {
node.GeoName = strings.TrimSpace(info.Name)
}
if info.Latitude != nil && info.Longitude != nil {
node.GeoLatitude = cloneCoordinate(info.Latitude)
node.GeoLongitude = cloneCoordinate(info.Longitude)
return
}
applyCountryCentroid(node, info.ISOCode, info.Name)
}
func applyCountryCentroid(node *model.OpenFlareNode, isoCode, name string) {
if lat, lon, ok := pkggeoip.CountryCentroidByISO(isoCode); ok {
node.GeoLatitude = cloneFloat(lat)
node.GeoLongitude = cloneFloat(lon)
return
}
if lat, lon, ok := pkggeoip.CountryCentroidByName(name); ok {
node.GeoLatitude = cloneFloat(lat)
node.GeoLongitude = cloneFloat(lon)
}
}
func cloneFloat(value float64) *float64 {
cloned := value
return &cloned
}
func cloneCoordinate(value *float64) *float64 {
if value == nil {
return nil
}
cloned := *value
return &cloned
}