feat: initialize sunrise with 100-player shared rooms
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
export const BUILDINGS = {
|
||||
url: '/buildings/gwacheon.geojson',
|
||||
assetManifestUrl: '/buildings/gwacheon.baked.json',
|
||||
assetBufferUrl: '/buildings/gwacheon.baked.bin',
|
||||
assetVersion: 1,
|
||||
metersPerLevel: 3,
|
||||
// Visual placeholders only: not a claim about actual floors.
|
||||
fallbackHeight: { apartments: 15, residential: 9, house: 6, commercial: 12, greenhouse: 3, roof: 3, school: 12, default: 9 } as Record<string, number>,
|
||||
baseSampleRadius: 45,
|
||||
overviewHeight: 180,
|
||||
target: { latitude: 37.429, longitude: 126.991 },
|
||||
colors: { tagged: '#c5c7bf', levels: '#b4bdc1', fallback: '#a99b85' },
|
||||
// Illustrative exterior lighting, not surveyed fixtures or light transport.
|
||||
lighting: {
|
||||
fadeStartAltitude: -6, fadeEndAltitude: 5, facadeFadeHeight: 24,
|
||||
spillMapSize: 1024, spillDistance: 14, spillSpacing: 18, spillIntensity: 0.9,
|
||||
bloomStrength: 0.22, bloomRadius: 0.15, bloomThreshold: 1.2,
|
||||
},
|
||||
} as const;
|
||||
@@ -0,0 +1,19 @@
|
||||
export const CHARACTER = {
|
||||
url: '/characters/red-sheep.glb?v=rounded-v10',
|
||||
scale: 0.62,
|
||||
outline: 0.018,
|
||||
ink: '#352724',
|
||||
lighting: {
|
||||
nightBrightness: 0.12,
|
||||
minimumBrightness: 0.08,
|
||||
nightAltitude: -8,
|
||||
dayAltitude: 15,
|
||||
},
|
||||
waveSeconds: 3,
|
||||
prayerWindowMs: 5 * 60 * 1000,
|
||||
cameraDistance: 5,
|
||||
cameraLift: 1.15,
|
||||
cameraClearance: 0.35,
|
||||
cameraTurnRate: 1.8,
|
||||
turnSpeed: 4,
|
||||
} as const;
|
||||
@@ -0,0 +1,15 @@
|
||||
export const COAST = {
|
||||
// OSM node/12019797394: Hajodae Pavilion.
|
||||
latitude: 38.020813,
|
||||
longitude: 128.7352564,
|
||||
radiusMeters: 1500,
|
||||
spacingMeters: 10,
|
||||
maskSpacingMeters: 2,
|
||||
distanceRangeMeters: 32,
|
||||
oceanRadiusMeters: 30000,
|
||||
oceanSegments: 240,
|
||||
overviewHeight: 900,
|
||||
cape: { latitude: 38.021987, longitude: 128.7355911 },
|
||||
// Protected-tree reference coordinates; approximate viewing bearing only.
|
||||
pine: { latitude: 38 + 1.252 / 60, longitude: 128 + 44.134 / 60 },
|
||||
} as const;
|
||||
@@ -0,0 +1,5 @@
|
||||
export const COMPASS = {
|
||||
tickDegrees: 5,
|
||||
visibleDegrees: 150,
|
||||
labels: ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'],
|
||||
} as const;
|
||||
@@ -0,0 +1,15 @@
|
||||
export const GISAMUN = {
|
||||
latitude: 38.00555,
|
||||
longitude: 128.73195,
|
||||
// OSM coastline nodes spanning the beach south of Gisamun harbour.
|
||||
// Sand extent is an illustrative 35m inland strip, not surveyed geometry.
|
||||
sandLatitudeMin: 38.0043299,
|
||||
sandLatitudeMax: 38.0064958,
|
||||
sandWidthMeters: 35,
|
||||
harbour: { latitude: 38.0085, longitude: 128.7328 },
|
||||
// Local metres relative to the unchanged terrain-data origin. Provisional
|
||||
// north breakwater entrance, not a surveyed visitor/camera location.
|
||||
viewpoint: { x: -30, z: -350 },
|
||||
// Centre of the mapped offshore island's bounding box (Jodo).
|
||||
jodo: { x: 970.095, z: -171.101 },
|
||||
} as const;
|
||||
@@ -0,0 +1,78 @@
|
||||
// Footprint follows OSM way/583161999 in the published Gisamun local coordinates.
|
||||
// Inland closure, top elevation, wall height and shelter strength are illustrative.
|
||||
export const GISAMUN_HARBOUR = {
|
||||
topElevation: 3,
|
||||
bottomElevation: -2,
|
||||
shelterWaveScale: .25,
|
||||
entranceBlendMeters: 18,
|
||||
parapetHeight: .7,
|
||||
parapetWidth: .65,
|
||||
topColor: '#a2a198',
|
||||
wallColor: '#737a78',
|
||||
land: [
|
||||
[-28.051, -155.739],
|
||||
[-4.057, -150.511],
|
||||
[13.586, -144.984],
|
||||
[25.908, -151.71],
|
||||
[47.118, -140.822],
|
||||
[58.307, -147.348],
|
||||
[36.956, -163.498],
|
||||
[25.943, -167.849],
|
||||
[-12.129, -159.935],
|
||||
[-31.678, -173.088],
|
||||
[-37.272, -178.882],
|
||||
[-114.628, -175.93],
|
||||
[-129.038, -274.496],
|
||||
[-122.205, -279.746],
|
||||
[-121.933, -316.042],
|
||||
[-115.995, -349.851],
|
||||
[-100.196, -362.937],
|
||||
[-42.848, -363.359],
|
||||
[-35.024, -332.835],
|
||||
[-22.272, -302.31],
|
||||
[-15.94, -303.764],
|
||||
[-3.047, -271.731],
|
||||
[16.019, -247.7],
|
||||
[95.386, -163.543],
|
||||
[90.485, -155.029],
|
||||
[98.916, -150.723],
|
||||
[111.818, -152.21],
|
||||
[118.158, -165.841],
|
||||
[56.804, -238.465],
|
||||
[21.244, -279.578],
|
||||
[-4.857, -330.848],
|
||||
[-17.424, -401.508],
|
||||
[-24.81, -423.552],
|
||||
[-180, -423.552],
|
||||
[-180, -155.739],
|
||||
],
|
||||
basin: [
|
||||
[58.307, -147.348],
|
||||
[36.956, -163.498],
|
||||
[25.943, -167.849],
|
||||
[-12.129, -159.935],
|
||||
[-31.678, -173.088],
|
||||
[-37.272, -178.882],
|
||||
[-114.628, -175.93],
|
||||
[-129.038, -274.496],
|
||||
[-122.205, -279.746],
|
||||
[-121.933, -316.042],
|
||||
[-115.995, -349.851],
|
||||
[-100.196, -362.937],
|
||||
[-42.848, -363.359],
|
||||
[-35.024, -332.835],
|
||||
[-22.272, -302.31],
|
||||
[-15.94, -303.764],
|
||||
[-3.047, -271.731],
|
||||
[16.019, -247.7],
|
||||
[95.386, -163.543],
|
||||
],
|
||||
parapet: [
|
||||
[118.158, -165.841],
|
||||
[56.804, -238.465],
|
||||
[21.244, -279.578],
|
||||
[-4.857, -330.848],
|
||||
[-17.424, -401.508],
|
||||
[-24.81, -423.552],
|
||||
],
|
||||
} as const;
|
||||
@@ -0,0 +1,6 @@
|
||||
export const IMPOSTOR_EXPERIMENT = {
|
||||
width: 1280, height: 720, textureScale: 2, sideOffset: 300,
|
||||
minLongitude: 126.99, maxLongitude: 127.00,
|
||||
minLatitude: 37.425, maxLatitude: 37.435,
|
||||
warmupFrames: 30, sampleFrames: 90, rounds: 3,
|
||||
} as const;
|
||||
@@ -0,0 +1,35 @@
|
||||
import { LOCATION_ENABLED } from './locations.ts';
|
||||
|
||||
export const APP_NAME = '해보러가기';
|
||||
export const LOBBY_CHARACTER = {
|
||||
maxSize: 360,
|
||||
widthFraction: 0.65,
|
||||
heightFraction: 0.55,
|
||||
marginFraction: 0,
|
||||
heading: 160,
|
||||
frameBottom: 0.75,
|
||||
frameTop: 1.5,
|
||||
minimumLightingAltitude: -3,
|
||||
} as const;
|
||||
export const LOBBY_SUNRISE = {
|
||||
durationMs: 4500,
|
||||
nightHoldMs: 300,
|
||||
from: Date.parse('2026-11-06T05:40:00+09:00'),
|
||||
to: Date.parse('2026-11-06T07:45:00+09:00'),
|
||||
heading: 110,
|
||||
pitch: 12,
|
||||
fieldOfView: 40,
|
||||
maxPixelRatio: 1.5,
|
||||
maxExposure: 0.32,
|
||||
} as const;
|
||||
export const LOBBY_SERVERS = [
|
||||
{ id: 'gwanaksan', name: '관악산 가기', description: '능선 위에서 함께 맞이하는 아침', enabled: LOCATION_ENABLED.gwanaksan },
|
||||
{ id: 'hajodae', name: '하조대 가기', description: '바다와 소나무 사이로 떠오르는 해', enabled: LOCATION_ENABLED.hajodae },
|
||||
{ id: 'gisamun', name: '기사문 해변 가기', description: '잔잔한 해변에서 기다리는 첫 햇살', enabled: LOCATION_ENABLED.gisamun },
|
||||
] as const;
|
||||
export const LOBBY = { endpoint: '/api/lobby', timeoutMs: 10000, channelName: '채널 1' } as const;
|
||||
|
||||
export interface LobbyData {
|
||||
servers: typeof LOBBY_SERVERS;
|
||||
channel: { id: string; name: string; capacity: number; players: number; available: boolean };
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { observer, observerName } from '../config/observer.ts';
|
||||
import { COAST } from './coast.ts';
|
||||
import { TERRAIN } from './terrain.ts';
|
||||
import { GISAMUN } from './gisamun.ts';
|
||||
|
||||
export const LOCATIONS = {
|
||||
gwanaksan: {
|
||||
name: observerName, label: 'GWANAKSAN', observer,
|
||||
terrain: { metadataUrl: TERRAIN.metadataUrl, heightsUrl: TERRAIN.heightsUrl },
|
||||
coast: null,
|
||||
},
|
||||
hajodae: {
|
||||
name: '하조대 정자', label: 'HAJODAE',
|
||||
observer: { latitude: COAST.latitude, longitude: COAST.longitude, elevation: 0, eyeHeight: 1.7 },
|
||||
terrain: { metadataUrl: '/terrain/hajodae/metadata.json', heightsUrl: '/terrain/hajodae/heights.f32' },
|
||||
coast: { directory: '/terrain/hajodae', lookTarget: COAST.pine, lookLabel: '소나무 방향' },
|
||||
},
|
||||
gisamun: {
|
||||
name: '기사문 해변', label: 'GISAMUN',
|
||||
observer: { latitude: GISAMUN.latitude, longitude: GISAMUN.longitude, elevation: 0, eyeHeight: 1.7 },
|
||||
terrain: { metadataUrl: '/terrain/gisamun/metadata.json', heightsUrl: '/terrain/gisamun/heights.f32' },
|
||||
coast: { directory: '/terrain/gisamun', lookTarget: GISAMUN.harbour, lookLabel: '기사문항 방향' },
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const DEFAULT_LOCATION: keyof typeof LOCATIONS = 'gwanaksan';
|
||||
export const LOCATION_ENABLED: Record<keyof typeof LOCATIONS, boolean> = {
|
||||
gwanaksan: true,
|
||||
hajodae: false,
|
||||
gisamun: false,
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export const MINIMAP = {
|
||||
size: 256,
|
||||
padding: 12,
|
||||
contourInterval: 50,
|
||||
majorInterval: 100,
|
||||
minZoom: 1,
|
||||
maxZoom: 16,
|
||||
zoomStep: 2,
|
||||
background: '#17272b',
|
||||
contourColor: '#80998b',
|
||||
majorColor: '#bed0ad',
|
||||
markerColor: '#ffd29a',
|
||||
} as const;
|
||||
@@ -0,0 +1 @@
|
||||
export const MOVEMENT = { speed: 4, maxDelta: 0.05, dragSensitivity: 0.003, dragThreshold: 6, arrivalDistance: 0.01 } as const;
|
||||
@@ -0,0 +1,15 @@
|
||||
export const MULTIPLAYER = {
|
||||
locationId: 'gwanaksan',
|
||||
roomId: 'gwanaksan-001',
|
||||
capacity: 100,
|
||||
tickMs: 100,
|
||||
snapshotMs: 5000,
|
||||
clockSyncMs: 30000,
|
||||
visitHeartbeatMs: 60000,
|
||||
interpolationMs: 150,
|
||||
playerHeartbeatMs: 1000,
|
||||
staleMovementMs: 1500,
|
||||
maxPacketBytes: 4096,
|
||||
ackTimeoutMs: 10000,
|
||||
maxNicknameLength: 20,
|
||||
} as const;
|
||||
@@ -0,0 +1,13 @@
|
||||
export const NIGHT_SKY = {
|
||||
starCount: 1800,
|
||||
seed: 73021,
|
||||
distance: 60000,
|
||||
moonRadiusKm: 1737.4,
|
||||
fadeStartAltitude: -12,
|
||||
fadeEndAltitude: -4,
|
||||
backgroundRadiance: [0.08, 0.13, 0.22],
|
||||
starRadiance: 8,
|
||||
moonRadiance: 7,
|
||||
moonFadeStartAltitude: -4,
|
||||
moonFadeEndAltitude: 5,
|
||||
} as const;
|
||||
@@ -0,0 +1,5 @@
|
||||
export const EYE_HEIGHT = {
|
||||
minCentimeters: 160,
|
||||
maxCentimeters: 195,
|
||||
stepCentimeters: 1,
|
||||
} as const;
|
||||
@@ -0,0 +1,9 @@
|
||||
/** Visual density limits, not meteorological severity thresholds. */
|
||||
export const PRECIPITATION = {
|
||||
radius: 22,
|
||||
height: 30,
|
||||
belowCamera: 10,
|
||||
maxDelta: 0.05,
|
||||
rain: { maxParticles: 5000, fullRate: 30, speed: 14, streak: 0.65, opacity: 0.28 },
|
||||
snow: { maxParticles: 2200, fullRate: 4, speed: 1.2, size: 0.09, opacity: 0.85, drift: 0.35 },
|
||||
} as const;
|
||||
@@ -0,0 +1,4 @@
|
||||
export const RAIN_GEAR = {
|
||||
umbrellaUrl: '/characters/umbrella.glb?v=1',
|
||||
raincoatUrl: '/characters/raincoat.glb?v=5',
|
||||
} as const;
|
||||
@@ -0,0 +1,12 @@
|
||||
export const RENDER_QUALITY = {
|
||||
mobileCap: 1.5,
|
||||
mobilePixelBudget: 1_500_000,
|
||||
levels: [0.75, 1, 1.25, 1.5, 1.75, 2] as readonly number[],
|
||||
settleMs: 10_000,
|
||||
windowMs: 5_000,
|
||||
minimumSamples: 30,
|
||||
lowerP95Ms: 34,
|
||||
raiseP95Ms: 22,
|
||||
raiseMeanMs: 19,
|
||||
healthyWindows: 4,
|
||||
} as const;
|
||||
@@ -0,0 +1,20 @@
|
||||
export const SCENE = {
|
||||
fieldOfView: 65,
|
||||
near: 0.1,
|
||||
far: 100000,
|
||||
skyRadius: 45000,
|
||||
sunDistance: 60000,
|
||||
sunDiameterDegrees: 0.53,
|
||||
haloDiameterDegrees: 7,
|
||||
haloOpacity: 0.32,
|
||||
sunRadianceAtHorizon: 6,
|
||||
sunRadianceAtDay: 40,
|
||||
sunRadianceDayAltitude: 15,
|
||||
mieCoefficient: 0.005,
|
||||
mieDirectionalG: 0.8,
|
||||
horizonRadius: 40000,
|
||||
horizonBlendDegrees: 2,
|
||||
markerRadius: 3000,
|
||||
pitchLimitDegrees: 85,
|
||||
maxPixelRatio: 2,
|
||||
} as const;
|
||||
@@ -0,0 +1,24 @@
|
||||
export const STRUCTURE_ASSETS = {
|
||||
baseUrl: '/models/summit',
|
||||
foundationColor: '#bbb9ac',
|
||||
supportColor: '#454b42',
|
||||
access: { deckIds: ['north-deck'] as readonly string[], treadDepth: .3, maxRiser: .18, maxSteps: 32, landingLength: .6, groundOverlap: .1 },
|
||||
} as const;
|
||||
|
||||
/** Preliminary dimensions in meters; NOT surveyed heights. Sources: data/references/summit. */
|
||||
export const STRUCTURES = {
|
||||
towers: [
|
||||
{ id: 'summit-mast', latitude: 37.4450675, longitude: 126.9638043, height: 24, width: 2.4, source: 'OSM node/3445797250', estimatedPosition: false },
|
||||
// OSM transmitter points identify facilities, not the centers of individual towers.
|
||||
{ id: 'south-tower-1', latitude: 37.4401643, longitude: 126.9642555, height: 48, width: 5, source: 'OSM node/4262612712 + recent-02.jpg', estimatedPosition: true },
|
||||
{ id: 'south-tower-2', latitude: 37.4400359, longitude: 126.9640016, height: 36, width: 3.2, source: 'OSM node/4736107159 + recent-02.jpg', estimatedPosition: true },
|
||||
{ id: 'south-tower-3', latitude: 37.44012, longitude: 126.96448, height: 40, width: 3, source: 'recent-02.jpg; approximate cluster offset', estimatedPosition: true },
|
||||
{ id: 'south-tower-4', latitude: 37.44003, longitude: 126.96472, height: 34, width: 2.4, source: 'recent-02.jpg; approximate cluster offset', estimatedPosition: true },
|
||||
],
|
||||
radar: { latitude: 37.444028, longitude: 126.963808, radius: 4, buildingHeight: 7, source: 'OSM way/337498781 (identity inferred), photo-01/09/10' },
|
||||
decks: [
|
||||
{ id: 'north-deck', enabled: false, latitude: 37.44516, longitude: 126.96405, width: 3, length: 7, heading: -20, stairLength: 7, stairDrop: 3, source: 'deck-19/20/22; position and dimensions estimated' },
|
||||
].filter(deck => deck.enabled),
|
||||
railing: { height: 1.15, postWidth: 0.1, maxSpan: 1.5 },
|
||||
deck: { thickness: 0.18, clearance: 0.25, plankWidth: 0.18 },
|
||||
} as const;
|
||||
@@ -0,0 +1,9 @@
|
||||
export const SUMMIT_ASSETS = {
|
||||
manifestUrl: '/terrain/summit-mesh.json',
|
||||
bufferUrl: '/terrain/summit-mesh.bin',
|
||||
version: 1,
|
||||
magic: 0x53554d54,
|
||||
interiorMaxEdge: 5.6,
|
||||
detailedStartRadius: 20,
|
||||
attributes: [['position',3],['normal',3],['uv',2],['color',3],['trailDistance',1],['rockDistance',1]] as const,
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/** Illustrative CC0 surface scans; not photographs or measured materials of this site. */
|
||||
export const SUMMIT_MATERIALS = {
|
||||
baseUrl: '/terrain/materials',
|
||||
anisotropy: 8,
|
||||
edgeBlend: { innerMeters: -0.5, outerMeters: 0.4, irregularityMeters: 0.16 },
|
||||
rockBlend: { innerMeters: -0.7, outerMeters: 0.5, irregularityMeters: 0.25 },
|
||||
path: { tileMeters: 2, normalStrength: 0.65, tint: '#ffffff' },
|
||||
rock: { tileMeters: 1.8, normalStrength: 0.55, tint: '#ffffff', secondaryScale: 1.37, secondaryOffset: [0.31, 0.73], secondaryBlend: 0.5, secondaryVariation: 0.3 },
|
||||
forest: { tileMeters: 2, normalStrength: 0.75, tint: '#b8c6a3', farColor: '#697052', fadeNear: 15, fadeFar: 65 },
|
||||
} as const;
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
|
||||
/** User reference photos, 2026-10-30. Visual estimates, not surveyed rock geometry.
|
||||
* Offsets in metres east/south of the radar; tops relative to its terrain contact.
|
||||
* The adjacent mast in the first photo is not identified with the mapped north mast.
|
||||
*/
|
||||
export const SUMMIT_RELIEF = {
|
||||
rockTint: '#ffffff',
|
||||
assetId: 'radar-rocks',
|
||||
access: { bottom: [-10, -28], top: [-8, -4], landingEnd: [-3.5, -4], width: 1.25, treadDepth: .28, railHeight: 1.05, railRadius: .035, postEvery: 5, color: '#85999c' },
|
||||
} as const;
|
||||
@@ -0,0 +1,33 @@
|
||||
/** Photo/contour interpretation, NOT surveyed GPS or elevations. See /terrain/summit-reconstruction.html. */
|
||||
export const SUMMIT_TERRAIN = {
|
||||
start: { latitude: 37.44472, longitude: 126.96422 },
|
||||
coreRadius: 100,
|
||||
outerRadius: 200,
|
||||
// Looking south leaves the radar to the right, the eastern valley to the left.
|
||||
heading: 190,
|
||||
pitch: -3,
|
||||
controls: [
|
||||
{ label: '시작 위치 암반', latitude: 37.44472, longitude: 126.96422, elevation: 620 },
|
||||
{ label: '북쪽 정상 암반', latitude: 37.44503, longitude: 126.96394, elevation: 629 },
|
||||
{ label: '정상 표지석 일대 암반', latitude: 37.4451398, longitude: 126.9642379, elevation: 629 },
|
||||
{ label: '정상에서 내려오는 넓은 석판', latitude: 37.44494, longitude: 126.96420, elevation: 626 },
|
||||
{ label: '중간 안부', latitude: 37.44440, longitude: 126.96402, elevation: 606 },
|
||||
{ label: '레이돔 암봉', latitude: 37.444028, longitude: 126.963808, elevation: 628 },
|
||||
// User photos: narrow radar crown, steep exposed faces, separate western rock fin.
|
||||
{ label: '레이돔 북쪽 받침', latitude: 37.444080, longitude: 126.963808, elevation: 628 },
|
||||
{ label: '레이돔 남쪽 받침', latitude: 37.443975, longitude: 126.963808, elevation: 627 },
|
||||
{ label: '레이돔 동쪽 받침', latitude: 37.444028, longitude: 126.963875, elevation: 627 },
|
||||
{ label: '레이돔 서쪽 받침', latitude: 37.444028, longitude: 126.963740, elevation: 627 },
|
||||
{ label: '북동 절벽 하단', latitude: 37.444145, longitude: 126.963945, elevation: 603 },
|
||||
{ label: '북쪽 절벽 하단', latitude: 37.444185, longitude: 126.963805, elevation: 608 },
|
||||
{ label: '서쪽 첨봉 받침', latitude: 37.444105, longitude: 126.963580, elevation: 617 },
|
||||
{ label: '첨봉 북쪽 암릉', latitude: 37.444240, longitude: 126.963570, elevation: 608 },
|
||||
{ label: '첨봉 아래 안부', latitude: 37.444380, longitude: 126.963680, elevation: 603 },
|
||||
{ label: '암봉 북사면', latitude: 37.44425, longitude: 126.96390, elevation: 610 },
|
||||
{ label: '암봉 동사면', latitude: 37.44403, longitude: 126.96408, elevation: 605 },
|
||||
{ label: '암봉 서사면', latitude: 37.44403, longitude: 126.96353, elevation: 604 },
|
||||
{ label: '암봉 남사면', latitude: 37.44382, longitude: 126.96382, elevation: 610 },
|
||||
{ label: '동쪽 골짜기', latitude: 37.44435, longitude: 126.96465, elevation: 582 },
|
||||
{ label: '서쪽 사면', latitude: 37.44435, longitude: 126.96335, elevation: 582 },
|
||||
],
|
||||
} as const;
|
||||
@@ -0,0 +1,343 @@
|
||||
/** OSM centerlines; widths and surface boundaries estimated from Naver Oct 2013 panoramas.
|
||||
* No public access inferred for the radar facility spur (way/337498785).
|
||||
*/
|
||||
import { SUMMIT_PLATEAU } from './summitPlateau.ts';
|
||||
export const SUMMIT_TRAILS = {
|
||||
radius: 200, surfaceStep: 0.7, surfaceLift: 0.06, sweepStep: 0.2,
|
||||
mapZoom: 64, mapMaxZoom: 128,
|
||||
colors: { path: '#b5a080', rock: '#a7a397' },
|
||||
// Photo-estimated slab from the lower forecourt to the OSM summit point ~47m north.
|
||||
// Shared by walking, rock material and minimap; excludes the western mast and eastern drop.
|
||||
rockPolygon: SUMMIT_PLATEAU.boundary,
|
||||
rockOutcrops: [
|
||||
{ latitude: 37.444028, longitude: 126.963808, radius: 14 },
|
||||
{ latitude: 37.444105, longitude: 126.963580, radius: 11 },
|
||||
{ latitude: 37.444240, longitude: 126.963570, radius: 9 },
|
||||
],
|
||||
routes: [
|
||||
{
|
||||
"id": "way/337498789",
|
||||
"label": "정상 암반길",
|
||||
"width": 3.2,
|
||||
"points": [
|
||||
[
|
||||
126.9642427,
|
||||
37.4452121
|
||||
],
|
||||
[
|
||||
126.9642346,
|
||||
37.4450861
|
||||
],
|
||||
[
|
||||
126.9641628,
|
||||
37.4449609
|
||||
],
|
||||
[
|
||||
126.9641194,
|
||||
37.4449084
|
||||
],
|
||||
[
|
||||
126.9641086,
|
||||
37.4448542
|
||||
],
|
||||
[
|
||||
126.9641235,
|
||||
37.4447614
|
||||
],
|
||||
[
|
||||
126.9641299,
|
||||
37.4446834
|
||||
],
|
||||
[
|
||||
126.9641627,
|
||||
37.4446443
|
||||
],
|
||||
[
|
||||
126.9641937,
|
||||
37.4446176
|
||||
],
|
||||
[
|
||||
126.9641853,
|
||||
37.4445946
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "way/37751526",
|
||||
"label": "남쪽 하산 계단길",
|
||||
"width": 2.4,
|
||||
"points": [
|
||||
[
|
||||
126.9652191,
|
||||
37.4426477
|
||||
],
|
||||
[
|
||||
126.965157,
|
||||
37.4427111
|
||||
],
|
||||
[
|
||||
126.9650832,
|
||||
37.4428437
|
||||
],
|
||||
[
|
||||
126.9649758,
|
||||
37.4428823
|
||||
],
|
||||
[
|
||||
126.9646903,
|
||||
37.4431718
|
||||
],
|
||||
[
|
||||
126.9644942,
|
||||
37.4433977
|
||||
],
|
||||
[
|
||||
126.9645363,
|
||||
37.4435795
|
||||
],
|
||||
[
|
||||
126.9644974,
|
||||
37.4437541
|
||||
],
|
||||
[
|
||||
126.9645055,
|
||||
37.4438755
|
||||
],
|
||||
[
|
||||
126.9644849,
|
||||
37.4439916
|
||||
],
|
||||
[
|
||||
126.9644634,
|
||||
37.4441563
|
||||
],
|
||||
[
|
||||
126.9644231,
|
||||
37.4442014
|
||||
],
|
||||
[
|
||||
126.9643909,
|
||||
37.4441957
|
||||
],
|
||||
[
|
||||
126.9643509,
|
||||
37.4442247
|
||||
],
|
||||
[
|
||||
126.9642731,
|
||||
37.4442455
|
||||
],
|
||||
[
|
||||
126.9642271,
|
||||
37.4442888
|
||||
],
|
||||
[
|
||||
126.9641796,
|
||||
37.4443334
|
||||
],
|
||||
[
|
||||
126.9641677,
|
||||
37.4443904
|
||||
],
|
||||
[
|
||||
126.9641998,
|
||||
37.4444216
|
||||
],
|
||||
[
|
||||
126.9642101,
|
||||
37.444477
|
||||
],
|
||||
[
|
||||
126.9641853,
|
||||
37.4445946
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "way/337498787",
|
||||
"label": "동쪽 계단길",
|
||||
"width": 2.2,
|
||||
"points": [
|
||||
[
|
||||
126.9646956,
|
||||
37.4448264
|
||||
],
|
||||
[
|
||||
126.9644011,
|
||||
37.4449652
|
||||
],
|
||||
[
|
||||
126.9641628,
|
||||
37.4449609
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "way/337498788",
|
||||
"label": "북쪽 능선길",
|
||||
"width": 2.4,
|
||||
"points": [
|
||||
[
|
||||
126.9652188,
|
||||
37.445905
|
||||
],
|
||||
[
|
||||
126.9651599,
|
||||
37.4458421
|
||||
],
|
||||
[
|
||||
126.9651204,
|
||||
37.445817
|
||||
],
|
||||
[
|
||||
126.9650739,
|
||||
37.4458262
|
||||
],
|
||||
[
|
||||
126.965047,
|
||||
37.4458008
|
||||
],
|
||||
[
|
||||
126.9650012,
|
||||
37.4458049
|
||||
],
|
||||
[
|
||||
126.9649836,
|
||||
37.4457585
|
||||
],
|
||||
[
|
||||
126.9649235,
|
||||
37.4457452
|
||||
],
|
||||
[
|
||||
126.9649129,
|
||||
37.4458003
|
||||
],
|
||||
[
|
||||
126.9648793,
|
||||
37.445814
|
||||
],
|
||||
[
|
||||
126.9648108,
|
||||
37.4457987
|
||||
],
|
||||
[
|
||||
126.9648084,
|
||||
37.4457327
|
||||
],
|
||||
[
|
||||
126.9647692,
|
||||
37.4457201
|
||||
],
|
||||
[
|
||||
126.9647305,
|
||||
37.4457475
|
||||
],
|
||||
[
|
||||
126.9646677,
|
||||
37.4457742
|
||||
],
|
||||
[
|
||||
126.9646443,
|
||||
37.4457812
|
||||
],
|
||||
[
|
||||
126.9646393,
|
||||
37.4457277
|
||||
],
|
||||
[
|
||||
126.9646373,
|
||||
37.4456519
|
||||
],
|
||||
[
|
||||
126.9646231,
|
||||
37.4456153
|
||||
],
|
||||
[
|
||||
126.9645478,
|
||||
37.4456006
|
||||
],
|
||||
[
|
||||
126.9645194,
|
||||
37.4455309
|
||||
],
|
||||
[
|
||||
126.9645211,
|
||||
37.4455051
|
||||
],
|
||||
[
|
||||
126.9644963,
|
||||
37.4454888
|
||||
],
|
||||
[
|
||||
126.9645078,
|
||||
37.4454665
|
||||
],
|
||||
[
|
||||
126.9644384,
|
||||
37.4454786
|
||||
],
|
||||
[
|
||||
126.9644443,
|
||||
37.4454544
|
||||
],
|
||||
[
|
||||
126.9644447,
|
||||
37.4454142
|
||||
],
|
||||
[
|
||||
126.9644298,
|
||||
37.4453984
|
||||
],
|
||||
[
|
||||
126.9644073,
|
||||
37.4454045
|
||||
],
|
||||
[
|
||||
126.9644102,
|
||||
37.4454574
|
||||
],
|
||||
[
|
||||
126.9643506,
|
||||
37.445427
|
||||
],
|
||||
[
|
||||
126.9642934,
|
||||
37.4454174
|
||||
],
|
||||
[
|
||||
126.9642857,
|
||||
37.4454008
|
||||
],
|
||||
[
|
||||
126.9643346,
|
||||
37.4453985
|
||||
],
|
||||
[
|
||||
126.9643315,
|
||||
37.4453643
|
||||
],
|
||||
[
|
||||
126.9642929,
|
||||
37.4453472
|
||||
],
|
||||
[
|
||||
126.9642727,
|
||||
37.4453499
|
||||
],
|
||||
[
|
||||
126.9642484,
|
||||
37.4453197
|
||||
],
|
||||
[
|
||||
126.9642584,
|
||||
37.4452722
|
||||
],
|
||||
[
|
||||
126.9642427,
|
||||
37.4452121
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
} as const;
|
||||
@@ -0,0 +1,9 @@
|
||||
export const TERRAIN = {
|
||||
metadataUrl: '/terrain/gwanaksan.json',
|
||||
heightsUrl: '/terrain/gwanaksan.f32',
|
||||
earthRadiusMeters: 6371008.8,
|
||||
fogNear: 4000,
|
||||
fogFar: 16500,
|
||||
refinementRadiusMeters: 180,
|
||||
refinementSegments: 6,
|
||||
} as const;
|
||||
@@ -0,0 +1,5 @@
|
||||
export const TIME_ZONE = 'Asia/Seoul';
|
||||
export const KST_OFFSET_MS = 9 * 60 * 60 * 1000;
|
||||
export const LIVE_INTERVAL_MS = 1000;
|
||||
export const TIME_STEP_SECONDS = 10;
|
||||
export const LAST_SELECTABLE_SECOND = 86400 - TIME_STEP_SECONDS;
|
||||
@@ -0,0 +1,15 @@
|
||||
export const DIALOG_TITLES = {
|
||||
menu: '메뉴', location: '장소', time: '날짜·시간', information: '관측 정보',
|
||||
view: '지도·시점', session: '닉네임·접속 상태',
|
||||
settings: '설정·조작 방법', sources: '출처·오픈소스',
|
||||
} as const;
|
||||
|
||||
export const EQUIPMENT_NOTICE = {
|
||||
weather: '기상악화시 사용할 수 있습니다',
|
||||
raincoat: '우비를 먼저 착용해 주세요',
|
||||
durationMs: 2400,
|
||||
margin: 12,
|
||||
pointerOffset: 16,
|
||||
} as const;
|
||||
|
||||
export const PRAYER_NOTICE = '일출 전후 5분에 사용할 수 있습니다';
|
||||
@@ -0,0 +1,22 @@
|
||||
export const WEATHER = {
|
||||
forecastUrl: 'https://api.open-meteo.com/v1/forecast',
|
||||
historyUrl: 'https://historical-forecast-api.open-meteo.com/v1/forecast',
|
||||
archiveUrl: 'https://archive-api.open-meteo.com/v1/archive',
|
||||
archiveStart: '1940-01-01',
|
||||
historyStart: '2022-01-01',
|
||||
recentDays: 5,
|
||||
forecastDays: 16,
|
||||
hourMs: 3600000,
|
||||
dayMs: 86400000,
|
||||
refreshMs: 30 * 60 * 1000,
|
||||
retryMs: 2 * 60 * 1000,
|
||||
timeoutMs: 15000,
|
||||
cacheDays: 8,
|
||||
transitionSeconds: 0.7,
|
||||
cloudOpticalDepth: 3.5,
|
||||
hazePathMeters: 2000,
|
||||
cloudScale: 3.8,
|
||||
overcastStart: 0.7,
|
||||
cloudOpacity: 0.98,
|
||||
overcastAmbient: 0.65,
|
||||
} as const;
|
||||
Reference in New Issue
Block a user