release: bump version to 0.47.0
This commit is contained in:
@@ -210,7 +210,7 @@ export const PATHS = {
|
||||
|
||||
export const VESSEL_CONFIG = {
|
||||
altitudeOffset: 0.2,
|
||||
maxRenderedMarkers: 5000,
|
||||
maxRenderedMarkers: 0,
|
||||
marker: {
|
||||
baseScale: 7.5,
|
||||
baseOpacity: 0.88,
|
||||
|
||||
@@ -787,12 +787,13 @@ function formatVesselStatus(navStatus) {
|
||||
|
||||
function showVesselInfo(marker, coords) {
|
||||
setLegendMode("vessels");
|
||||
const vesselType = marker.userData?.vessel_type_display || marker.userData?.vessel_type_name || "-";
|
||||
showInfoCard("vessel", {
|
||||
name: marker.userData?.name || `MMSI ${marker.userData?.mmsi}`,
|
||||
mmsi: marker.userData?.mmsi,
|
||||
imo: marker.userData?.imo || "-",
|
||||
flag: marker.userData?.flag || "-",
|
||||
vessel_type: marker.userData?.vessel_type_name || "-",
|
||||
vessel_type: vesselType,
|
||||
speed: marker.userData?.sog ?? "-",
|
||||
course: marker.userData?.cog ?? marker.userData?.heading ?? "-",
|
||||
status: formatVesselStatus(marker.userData?.nav_status),
|
||||
@@ -806,7 +807,8 @@ function showVesselInfo(marker, coords) {
|
||||
function getVesselBriefHtml(marker) {
|
||||
const name = marker.userData?.name || `MMSI ${marker.userData?.mmsi}`;
|
||||
const speed = marker.userData?.sog ?? "-";
|
||||
return `<strong>${name}</strong><br>${marker.userData?.vessel_type_name || "Vessel"} · ${speed} kn`;
|
||||
const vesselType = marker.userData?.vessel_type_display || marker.userData?.vessel_type_name || "Vessel";
|
||||
return `<strong>${name}</strong><br>${vesselType} · ${speed} kn`;
|
||||
}
|
||||
|
||||
function getComputeCenterBriefHtml(marker) {
|
||||
@@ -1390,6 +1392,7 @@ function resolveEarthSearchResults(query) {
|
||||
marker.userData?.mmsi,
|
||||
marker.userData?.imo,
|
||||
marker.userData?.flag,
|
||||
marker.userData?.vessel_type_display,
|
||||
marker.userData?.vessel_type_name,
|
||||
"船只 船舶 ais vessel ship maritime",
|
||||
);
|
||||
@@ -1401,7 +1404,7 @@ function resolveEarthSearchResults(query) {
|
||||
typeLabel: "船只",
|
||||
title: marker.userData?.name || `MMSI ${marker.userData?.mmsi}`,
|
||||
subtitle: [
|
||||
marker.userData?.vessel_type_name,
|
||||
marker.userData?.vessel_type_display || marker.userData?.vessel_type_name,
|
||||
marker.userData?.flag,
|
||||
marker.userData?.sog !== undefined ? `${marker.userData.sog} kn` : null,
|
||||
].filter(Boolean).join(" · ") || "AIS 船只",
|
||||
|
||||
@@ -24,6 +24,17 @@ function normalizeVesselType(value, code) {
|
||||
return "other";
|
||||
}
|
||||
|
||||
function formatVesselTypeLabel(type, fallback = "") {
|
||||
const rawFallback = String(fallback || "").trim();
|
||||
const normalized = String(type || "").trim().toLowerCase();
|
||||
if (normalized === "cargo") return "Cargo";
|
||||
if (normalized === "tanker") return "Tanker";
|
||||
if (normalized === "passenger") return "Passenger";
|
||||
if (normalized === "fishing") return "Fishing";
|
||||
if (normalized === "military") return "Military";
|
||||
return rawFallback && rawFallback.toLowerCase() !== "other" ? rawFallback : "Other";
|
||||
}
|
||||
|
||||
function drawVesselShape(context, anchored, glow, color = "#ffffff") {
|
||||
context.fillStyle = color;
|
||||
context.globalAlpha = anchored ? 0.55 : 0.96;
|
||||
@@ -52,6 +63,7 @@ function buildVesselMarkerData(feature) {
|
||||
if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) return null;
|
||||
|
||||
const type = normalizeVesselType(props.vessel_type_name, props.vessel_type);
|
||||
const vesselTypeLabel = formatVesselTypeLabel(type, props.vessel_type_name);
|
||||
const navStatus = Number(props.nav_status);
|
||||
const speed = Number(props.sog);
|
||||
const anchored = navStatus === 1 || navStatus === 5 || (Number.isFinite(speed) && speed < 0.5);
|
||||
@@ -61,6 +73,7 @@ function buildVesselMarkerData(feature) {
|
||||
latitude,
|
||||
longitude,
|
||||
type,
|
||||
vessel_type_display: vesselTypeLabel,
|
||||
anchored,
|
||||
course: Number(props.cog ?? props.heading ?? 0),
|
||||
};
|
||||
@@ -191,7 +204,10 @@ export function clearVesselData(earth) {
|
||||
|
||||
export async function loadVessels(_scene, earth, options = {}) {
|
||||
const params = new URLSearchParams();
|
||||
params.set("limit", String(options.limit || VESSEL_CONFIG.maxRenderedMarkers));
|
||||
const requestedLimit = Number(options.limit ?? VESSEL_CONFIG.maxRenderedMarkers);
|
||||
if (Number.isFinite(requestedLimit) && requestedLimit > 0) {
|
||||
params.set("limit", String(requestedLimit));
|
||||
}
|
||||
const response = await fetch(`${PATHS.vesselsApi}?${params.toString()}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Vessels HTTP ${response.status}`);
|
||||
@@ -200,10 +216,12 @@ export async function loadVessels(_scene, earth, options = {}) {
|
||||
const features = Array.isArray(payload?.features) ? payload.features : [];
|
||||
|
||||
clearVesselData(earth);
|
||||
const markerData = features
|
||||
let markerData = features
|
||||
.map((feature) => buildVesselMarkerData(feature))
|
||||
.filter(Boolean)
|
||||
.slice(0, VESSEL_CONFIG.maxRenderedMarkers);
|
||||
.filter(Boolean);
|
||||
if (Number.isFinite(requestedLimit) && requestedLimit > 0) {
|
||||
markerData = markerData.slice(0, requestedLimit);
|
||||
}
|
||||
vesselIconLayer.setData(markerData);
|
||||
|
||||
vesselIconLayer.attach(earth);
|
||||
|
||||
Reference in New Issue
Block a user