支持分层地图

This commit is contained in:
KimigaiiWuyi 2023-10-18 00:32:39 +08:00
parent 18a6380078
commit 6ded28d5bc
12 changed files with 58 additions and 18 deletions

1
.gitignore vendored
View File

@ -131,4 +131,5 @@ dmypy.json
# 地图资源
fastapi_genshin_map/GetMapImage/map_data
fastapi_genshin_map/GetMapImage/resource_data
fastapi_genshin_map/GetMapImage/icon_data
fastapi_genshin_map/GetMapImage/genshinmap.log

View File

@ -43,4 +43,4 @@
+ [GPL-3.0 License](https://github.com/KimigaiiWuyi/GenshinUID/blob/main/LICENSE) ©[@KimigaiiWuyi](https://github.com/KimigaiiWuyi)
## 丨返回图示例
![测试.jpg](https://s2.loli.net/2022/10/17/D2cI5tQdgVk3Uuz.jpg)
![测试.jpg](https://s2.loli.net/2023/10/18/Khd5LRQF3HqrEVD.jpg)

View File

@ -6,7 +6,7 @@ import numpy as np
from sklearn.cluster import KMeans
from shapely.geometry import Point, Polygon
from .models import XYPoint
from .models import XYPoint, XYZPoint
Pos = Tuple[float, float]
Poses = List[XYPoint]
@ -14,8 +14,8 @@ Points = List[Point]
def k_means_points(
points: List[XYPoint], length: int = 500, clusters: int = 3
) -> List[Tuple[XYPoint, XYPoint, Poses]]:
points: List[XYZPoint], length: int = 500, clusters: int = 3
) -> List[Tuple[XYZPoint, XYZPoint, Poses]]:
"""
通过 K-Means 获取集群坐标列表

View File

@ -59,6 +59,10 @@ class Point(BaseModel):
author_name: str
ctime: str
display_state: int
area_id: int
ext_attrs: str
z_level: int
icon_sign: int
class Slice(BaseModel):
@ -100,6 +104,12 @@ class XYPoint(NamedTuple):
y: float
class XYZPoint(NamedTuple):
x: float
y: float
z: int
class Kind(BaseModel):
id: int
name: str

View File

@ -8,7 +8,7 @@ from asyncio import gather, create_task
from PIL import Image
from httpx import AsyncClient
from .models import Maps, Point, XYPoint
from .models import Maps, Point, XYPoint, XYZPoint
CLIENT = AsyncClient()
@ -76,7 +76,7 @@ async def get_map_by_pos(
return await get_img(map.slices[_pos_to_index(x, y)])
def get_points_by_id(id_: int, points: List[Point]) -> List[XYPoint]:
def get_points_by_id(id_: int, points: List[Point]) -> List[XYZPoint]:
"""
根据 Label ID 获取坐标点
@ -91,13 +91,13 @@ def get_points_by_id(id_: int, points: List[Point]) -> List[XYPoint]:
`list[XYPoint]`
"""
return [
XYPoint(point.x_pos, point.y_pos)
XYZPoint(point.x_pos, point.y_pos, point.z_level)
for point in points
if point.label_id == id_
]
def convert_pos(points: List[XYPoint], origin: List[int]) -> List[XYPoint]:
def convert_pos(points: List[XYZPoint], origin: List[int]) -> List[XYZPoint]:
"""
将米游社资源坐标转换为以左上角为原点的坐标系的坐标
@ -118,7 +118,7 @@ def convert_pos(points: List[XYPoint], origin: List[int]) -> List[XYPoint]:
>>> convert_pos(points, origin)
[XYPoint(x=6044, y=9335), XYPoint(x=644, y=6135)]
"""
return [XYPoint(x + origin[0], y + origin[1]) for x, y in points]
return [XYZPoint(x + origin[0], y + origin[1], z) for x, y, z in points]
def convert_pos_crop(

View File

@ -0,0 +1,10 @@
import aiofiles
import aiohttp
async def download_file(url, save_path):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
async with aiofiles.open(save_path, "wb") as f:
await f.write(await response.read())

View File

@ -9,6 +9,7 @@ from PIL import Image
from .GenshinMap.genshinmap import img, models, request, utils
from .logger import logger
from .download import download_file
Image.MAX_IMAGE_PIXELS = 333120000
router = APIRouter(prefix="/get_map")
@ -16,6 +17,7 @@ TEXT_PATH = Path(__file__).parent / "texture2d"
mark_quest = Image.open(TEXT_PATH / "mark_quest.png").resize((32, 32))
MAP = Path(__file__).parent / "map_data"
RESOURCE_PATH = Path(__file__).parent / "resource_data"
ICON_PATH = Path(__file__).parent / "icon_data"
CHASM_PATH = MAP / "chasm.png"
ENKANOMIYA_PATH = MAP / "enkanomiya.png"
TEYVAT_PATH = MAP / "teyvat.png"
@ -30,6 +32,9 @@ MAP_ID_DICT = {
# MapID.golden_apple_archipelago, # 金苹果群岛
}
if not ICON_PATH.exists():
ICON_PATH.mkdir(exist_ok=True)
@router.on_event("startup")
async def create_genshin_map():
@ -89,15 +94,16 @@ async def get_map_response(
return save_path
maps = await request.get_maps(map_id)
labels = await request.get_labels(map_id)
trees = await request.get_labels(map_id)
# 请求资源ID
resource_id = 0
for label in labels:
for child in label.children:
if resource_name == child.name:
resource_id = child.id
resource_name = child.name
for tree in trees:
for label in tree.children:
if resource_name == label.name:
resource_id = label.id
resource_name = label.name
icon = label.icon
break
if resource_id == 0:
@ -109,6 +115,7 @@ async def get_map_response(
# 转换坐标
transmittable_converted = utils.convert_pos(transmittable, maps.detail.origin)
print(transmittable_converted)
# 进行最密点获取
if is_cluster:
@ -167,9 +174,20 @@ async def get_map_response(
int(point.x) - int(lt_point.x),
int(point.y) - int(lt_point.y),
)
genshin_map.paste(
mark_quest, (point_trans[0] - 16, point_trans[1] - 16), mark_quest
)
icon_path = ICON_PATH / f"{resource_name}.png"
if not icon_path.exists():
await download_file(icon, icon_path)
icon_pic = Image.open(icon_path).resize((52, 52))
if point.z <= 3:
mark = Image.open(TEXT_PATH / f"mark_{point.z}.png")
else:
mark = Image.open(TEXT_PATH / f"mark_B.png")
mark.paste(icon_pic, (25, 17), icon_pic)
genshin_map.paste(mark, (point_trans[0] - 50, point_trans[1] - 100), mark)
# 转换RGB图
genshin_map = genshin_map.convert("RGB")
@ -199,6 +217,7 @@ async def get_map_by_point(
if resource_name == a or resource_name in resource_aliases[m][a]:
return a
return resource_name
# 判断别名
resource_name = resource_aliases_to_name(resource_name)

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB