9 files changed
+6540
-6243
No files matched your search
@@ -0,0 +1,15 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
export const gradeColors = {
|
||||||
|
grade_flat: '#fff',
|
||||||
|
grade_0: '#f4f7cd',
|
||||||
|
grade_1: '#f8ff99',
|
||||||
|
grade_2: '#edfc1b',
|
||||||
|
grade_3: '#fcb520',
|
||||||
|
grade_4: '#f07837',
|
||||||
|
grade_5: '#e66441',
|
||||||
|
grade_6: '#ce3f57',
|
||||||
|
grade_7: '#c33577',
|
||||||
|
grade_8: '#a3008d',
|
||||||
|
grade_9: '#690097',
|
||||||
|
}
|
||||||
+59
-40
@@ -18,10 +18,10 @@
|
|||||||
<div id="mapNavigator">
|
<div id="mapNavigator">
|
||||||
<svg id="map" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 10000 10000">
|
<svg id="map" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 10000 10000">
|
||||||
<style>
|
<style>
|
||||||
.sign{
|
.fixedScale{
|
||||||
transform: scale(var(--signScale));
|
transform: scale(var(--markerScale));
|
||||||
}
|
}
|
||||||
.sign, .rail, .signText{
|
.sign, .rail, .signText, .poi{
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
.signText{
|
.signText{
|
||||||
@@ -105,84 +105,103 @@
|
|||||||
.gradeSign.grade_9{
|
.gradeSign.grade_9{
|
||||||
fill: var(--grade_9);
|
fill: var(--grade_9);
|
||||||
}
|
}
|
||||||
.cullThreshold_0{
|
|
||||||
display: var(--cullThreshold_state_0);
|
|
||||||
}
|
|
||||||
.cullThreshold_1{
|
|
||||||
display: var(--cullThreshold_state_1);
|
|
||||||
}
|
|
||||||
.cullThreshold_2{
|
|
||||||
display: var(--cullThreshold_state_2);
|
|
||||||
}
|
|
||||||
.cullThreshold_3{
|
|
||||||
display: var(--cullThreshold_state_3);
|
|
||||||
}
|
|
||||||
.cullThreshold_4{
|
|
||||||
display: var(--cullThreshold_state_4);
|
|
||||||
}
|
|
||||||
.cullThreshold_5{
|
|
||||||
display: var(--cullThreshold_state_5);
|
|
||||||
}
|
|
||||||
.cullThreshold_6{
|
|
||||||
display: var(--cullThreshold_state_6);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
<style id="zoomStyle"></style>
|
<style id="zoomStyle"></style>
|
||||||
<defs>
|
<defs>
|
||||||
<g id="gradeArrow" transform="scale(10)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="gradeArrow" transform="scale(30)" viewBox="0 0 10 10" >
|
||||||
<path d="M 0 -7 L 3.8 4 L -3.8 4 z" fill="black"/>
|
<path d="M 0 -7 L 3.8 4 L -3.8 4 z" fill="black"/>
|
||||||
<path d="M 0 -5 L 3 4 L 0 5 L -3 4 z"/>
|
<path d="M 0 -5 L 3 4 L 0 5 L -3 4 z"/>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign" transform="scale(15)" viewBox="0 0 10 10" refX="5" refY="5" style="fill:#fff; stroke:#e73819">
|
<g id="speedSign" transform="scale(15)" viewBox="0 0 10 10" style="fill:#fff; stroke:#e73819">
|
||||||
<circle cx="0" cy="0" r="3"/>
|
<circle cx="0" cy="0" r="3"/>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSignWarning" transform="scale(15)" viewBox="0 0 10 10" refX="5" refY="5" style="fill:#702012; stroke:#e73819">
|
<g id="speedSignWarning" transform="scale(15)" viewBox="0 0 10 10" style="fill:#702012; stroke:#e73819">
|
||||||
<circle cx="0" cy="0" r="3"/>
|
<circle cx="0" cy="0" r="3"/>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_1" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_1" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSignWarning"></use>
|
<use href="#speedSignWarning"></use>
|
||||||
<text class="signText" style="fill:#fff;transform:translate(-15px, 20px)">1</text>
|
<text class="signText" style="fill:#fff;transform:translate(-15px, 20px)">1</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_2" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_2" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSignWarning"></use>
|
<use href="#speedSignWarning"></use>
|
||||||
<text class="signText" style="fill:#fff;transform:translate(-15px, 20px)">2</text>
|
<text class="signText" style="fill:#fff;transform:translate(-15px, 20px)">2</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_3" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_3" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSignWarning"></use>
|
<use href="#speedSignWarning"></use>
|
||||||
<text class="signText" style="fill:#fff;transform:translate(-15px, 20px)">3</text>
|
<text class="signText" style="fill:#fff;transform:translate(-15px, 20px)">3</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_4" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_4" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSign"></use>
|
<use href="#speedSign"></use>
|
||||||
<text class="signText" style="transform:translate(-15px, 20px)">4</text>
|
<text class="signText" style="transform:translate(-15px, 20px)">4</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_5" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_5" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSign"></use>
|
<use href="#speedSign"></use>
|
||||||
<text class="signText" style="transform:translate(-16px, 20px)">5</text>
|
<text class="signText" style="transform:translate(-16px, 20px)">5</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_6" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_6" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSign"></use>
|
<use href="#speedSign"></use>
|
||||||
<text class="signText" style="transform:translate(-15px, 20px)">6</text>
|
<text class="signText" style="transform:translate(-15px, 20px)">6</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_7" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_7" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSign"></use>
|
<use href="#speedSign"></use>
|
||||||
<text class="signText" style="transform:translate(-15px, 20px)">7</text>
|
<text class="signText" style="transform:translate(-15px, 20px)">7</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_8" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_8" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSign"></use>
|
<use href="#speedSign"></use>
|
||||||
<text class="signText" style="transform:translate(-16px, 20px)">8</text>
|
<text class="signText" style="transform:translate(-16px, 20px)">8</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_9" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_9" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSign"></use>
|
<use href="#speedSign"></use>
|
||||||
<text class="signText" style="transform:translate(-15px, 20px)">9</text>
|
<text class="signText" style="transform:translate(-15px, 20px)">9</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_10" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_10" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSign"></use>
|
<use href="#speedSign"></use>
|
||||||
<text class="signText" style="transform:translate(-35px, 20px)">10</text>
|
<text class="signText" style="transform:translate(-35px, 20px)">10</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="speedSign_12" transform="scale(1)" viewBox="0 0 10 10" refX="5" refY="5">
|
<g id="speedSign_12" transform="scale(3)" viewBox="0 0 10 10">
|
||||||
<use href="#speedSign"></use>
|
<use href="#speedSign"></use>
|
||||||
<text class="signText" style="transform:translate(-35px, 20px)">12</text>
|
<text class="signText" style="transform:translate(-35px, 20px)">12</text>
|
||||||
</g>
|
</g>
|
||||||
|
<g id="mrk_office" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="M10 3.8l5.56 6.03h-1.66v5.2h-2.51v-3.93h-2.78v3.93h-2.51v-5.2h-1.66z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
|
<g id="mrk_water" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="M10 2c-1.02 2.01-7.08 14.38 0 14.38 7.08 0 1.02-12.46 0-14.38z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
|
<g id="mrk_coal" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="M10.75 2.98 7.85 4.02 5.64 7.39 5.74 7.54 7.08 7.06 10.14 9.03 10.47 8.6 13.67 7.4 14.65 8.03 14.94 7.21 13.65 4.97ZM7.07 7.6 4.18 8.64 1.96 12.01 3.49 15.33h6.78l.99-3.5-1.3-2.25zm6.61.47-2.9 1.04-.27.4.17.13 1.22 2.21-.91 3.48h5.88l.99-3.02-1.3-2.25z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
|
<g id="mrk_landmark" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="m11.39 1.43c-.2-.09-.42 0-.51.2L4.22 16.88c-.09.2 0 .42.2.5.2.09.42 0 .51-.2L11.59 1.93c.09-.2 0-.42-.2-.51zm.53.93-2.39 5.48c.21 0 .42 0 .62.01.2.01.41.02.61.03.2.01.4.03.6.05.2.02.39.04.59.06.19.02.39.05.58.08.19.03.38.06.57.1.09.02.18.04.28.05l2.12-2.56c-.01-.01-.02-.03-.04-.05C15.31 5.46 15.18 5.3 15.05 5.14 14.91 4.99 14.78 4.83 14.64 4.68 14.5 4.53 14.36 4.39 14.22 4.24 14.08 4.1 13.93 3.96 13.79 3.82 13.64 3.68 13.49 3.55 13.34 3.42 13.27 3.35 13.19 3.29 13.12 3.23 13.04 3.16 12.96 3.1 12.88 3.04 12.81 2.98 12.73 2.92 12.65 2.86 12.57 2.8 12.49 2.74 12.41 2.69 12.33 2.63 12.25 2.57 12.16 2.52 12.08 2.47 12 2.41 11.92 2.36Zm3.37 4.06-2.12 2.56c.1.02.19.04.29.06.19.04.37.08.55.13.18.04.37.09.55.14.18.05.36.1.54.15.18.05.36.1.53.16.18.05.35.11.53.17.18.06.35.12.53.17.17.06.35.12.52.18.35.12.69.25 1.04.37C18 10.15 17.76 9.79 17.51 9.44 17.27 9.09 17.02 8.74 16.78 8.39 16.65 8.22 16.53 8.05 16.4 7.88 16.28 7.7 16.15 7.53 16.02 7.36 15.9 7.2 15.77 7.03 15.64 6.86 15.53 6.71 15.41 6.57 15.29 6.42Z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
|
<g id="mrk_shop" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="M9.25 17.9V16.35C8.29 16.26 7.75 15.91 7.12 15.31 6.49 14.71 6.14 13.86 6.06 12.75l2.2-.49c.03.65.21 1.14.54 1.49.33.35.75.52 1.24.52.47 0 .81-.13 1.03-.4.23-.27.34-.55.34-.85 0-.39-.11-.71-.34-.94-.23-.24-.52-.46-.88-.65L8.66 10.62C7.91 10.23 7.33 9.75 6.9 9.2 6.48 8.65 6.27 7.92 6.27 7.02 6.27 6.37 6.41 5.8 6.68 5.31 6.97 4.8 7.35 4.4 7.83 4.1 8.32 3.8 8.63 3.61 9.25 3.54V2.1h1.65v1.48c.91.12 1.41.49 1.94 1.1.53.6.82 1.39.88 2.36L11.65 7.47C11.62 6.87 11.45 6.41 11.15 6.08 10.86 5.75 10.5 5.58 10.07 5.58 9.66 5.58 9.33 5.7 9.08 5.94 8.84 6.17 8.72 6.48 8.72 6.88c0 .36.11.65.32.86.21.21.51.42.88.63l1.63.86c.83.45 1.43.95 1.82 1.51.39.55.58 1.23.58 2.02 0 .6-.13 1.16-.4 1.67-.25.51-.63.95-1.12 1.3-.48.33-.84.54-1.53.63v1.4z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
|
<g id="mrk_garage" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="M10 2.88 2.98 6.42 2.98 15.1 5.53 15.1 5.53 8.91 14.47 8.91 14.47 15.1 17.02 15.1 17.02 6.42 10 2.88z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
|
<g id="mrk_service" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="m8.92 1.99q3.29 0 4.68 1.13 1.39 1.1 1.39 2.74 0 2.06-1.78 3.36-.67.5-1.63.91l-.38.17q-.17.07-.34 1.01-.14.91-.14 1.32-.12.12-.7.29-.55.14-.94.14-.36 0-.55-.05-.26-.43-.26-1.87 0-1.44.12-1.85 3.79-.91 3.79-3.07 0-1.87-3.46-1.87-1.22 0-1.78.24-.14-.24-.14-1.01 0-.77.22-1.3.65-.29 1.9-.29zm-.7 15.5q-.46-.48-.46-1.15 0-.67.46-1.13.48-.48 1.15-.48.67 0 1.13.48.48.46.48 1.13 0 .67-.48 1.15-.46.46-1.13.46-.67 0-1.15-.46z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
|
<g id="mrk_service_repair" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="m12.88 2.82c-.1.01-.2.05-.28.13l-2.19 2.19c-.15.16-.17.39-.03.53l1.12 1.12c.29-.29.37.07.57.58l-1.61 1.6 1.77 1.72 1.7-1.7c.44.03.82-.06.99.11.22.22.19.59-.06.85l-.02.02c1.48 1.26 3.85-1.11 2.59-2.59l-.02.02c-.25.25-.63.28-.85.06-.3-.3.23-1.31-.61-2.15l-.1-.1c-.73-.74-2.07-.7-1.6-1.18l-1.12-1.12c-.06-.06-.16-.09-.25-.09zM5.63 3.68c-.28 0-.55.05-.83.14l2.02 2.02-1.85 1.86-2.02-2.02c-.72 2.23 1.45 4.34 3.67 3.55l7.27 7.27c.46.47 1.22.47 1.71-.02.49-.49.5-1.25.03-1.72L8.36 7.49c.69-1.94-.84-3.84-2.73-3.81zm2.41 7.72-3.36 3.35c-.47.47-.47 1.23.02 1.72.49.49 1.25.49 1.72.02l3.38-3.38z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
|
<g id="mrk_service_diesel" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="m12.67 2.93c-.5-.01-1 .09-1.46.31L9.86 3.88 9.76 3.66 7.64 4.67 7.18 4.02C7.09 3.89 6.92 3.86 6.79 3.95L5.55 4.8C5.43 4.89 5.4 5.07 5.48 5.2L5.87 5.75 5.51 6.22 2.7 10.29c-.2.3-.18.7.06.97-.4.74-.49 1.54-.3 2.26.22.86.77 1.6 1.5 2.16 1.46 1.12 3.68 1.56 5.63.5 1.07-.59 2.19-.79 2.99-.64.8.14 1.26.52 1.39 1.32.05.33.36.55.69.5.33-.05.55-.36.5-.69-.2-1.27-1.2-2.1-2.36-2.31-1.16-.21-2.51.08-3.78.77C7.53 15.95 5.8 15.6 4.69 14.74 4.14 14.32 3.76 13.77 3.62 13.23 3.52 12.83 3.53 12.42 3.73 11.99l1.39.96c.81.56 1.93.36 2.49-.46L10.41 8.46 9.88 5.6 10.53 5.29 10.42 5.05 11.76 4.42C12.2 4.21 12.7 4.17 13.17 4.32L16.71 5.44 17.1 4.2 13.56 3.08C13.27 2.99 12.97 2.94 12.67 2.93Zm4.24 3.31c-.39.63-2.7 4.48 0 4.48 2.7 0 .39-3.88 0-4.48zM6.91 7.47 8.22 7.92 7.2 8.58c-.04.03-.08.06-.11.11l-1.55 2.46c-.1.16-.05.38.11.48.16.1.38.05.48-.11L7.64 9.12 8.94 8.29c.24.29.25.71.02 1.03L7.44 11.52C6.92 12.27 5.93 12.48 5.22 11.99L4.36 11.4Z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
|
<g id="mrk_service_charger" transform="scale(20)" viewBox="0 0 20 20">
|
||||||
|
<circle r="10"></circle>
|
||||||
|
<path transform="translate(-10 -10)" d="m7.96 2.6h4.56l-1.97 5.8h3.02L8.61 18.36 9.6 10.25H7.26Z" fill="#fff"></path>
|
||||||
|
</g>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
<svg id="mapMarkers" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 10000 10000">
|
<svg id="mapMarkers" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 10000 10000">
|
||||||
@@ -196,13 +215,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="legend" style="display: flex;">
|
<div id="legend" style="display: flex;">
|
||||||
<div style="display:flex; flex-direction:column; width: 400px;">
|
<div id="legendContents" style="display:flex; flex-direction:column; width: 400px;">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
Welcome to the WIP community map of <a href="https://www.derailvalley.com/" style="white-space:nowrap;">Derail Valley</a>, a resource for documenting and displaying all tracks and points of interest.
|
Welcome to the WIP community map of <a href="https://www.derailvalley.com/" style="white-space:nowrap;">Derail Valley</a>, a resource for documenting and displaying all tracks and points of interest.
|
||||||
<hr>
|
<hr>
|
||||||
Hover over tracks and objects for detailed information.
|
Hover over tracks and objects for detailed information.
|
||||||
</div>
|
</div>
|
||||||
<div class="panel">
|
<div class="panel" style="width:330px">
|
||||||
<h3>Key</h3>
|
<h3>Key</h3>
|
||||||
<hr>
|
<hr>
|
||||||
<div id="legendKey"></div>
|
<div id="legendKey"></div>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import * as Vector from './js/vectorlib.js';
|
import * as Vector from './js/vectorlib.js';
|
||||||
import * as Bezier from './js/bezierlib.js';
|
import * as Bezier from './js/bezierlib.js';
|
||||||
import * as Utils from './js/utillib.js';
|
import * as Utils from './js/utillib.js';
|
||||||
|
import * as Config from './config.js';
|
||||||
|
|
||||||
// CONFIG
|
// CONFIG
|
||||||
const bezierGradeResolution = 80;
|
const bezierGradeResolution = 80;
|
||||||
@@ -57,6 +58,14 @@ map.appendChild(map_rails);
|
|||||||
//map_markers.setAttribute('id', 'map_markers');
|
//map_markers.setAttribute('id', 'map_markers');
|
||||||
//map.appendChild(map_markers);
|
//map.appendChild(map_markers);
|
||||||
const map_markers = document.getElementById('mapMarkers');
|
const map_markers = document.getElementById('mapMarkers');
|
||||||
|
const poiLayers = {
|
||||||
|
container: document.createElementNS(svgns, 'g'),
|
||||||
|
|
||||||
|
stations: document.createElementNS(svgns, 'g'),
|
||||||
|
service: document.createElementNS(svgns, 'g'),
|
||||||
|
features: document.createElementNS(svgns, 'g'),
|
||||||
|
landmarks: document.createElementNS(svgns, 'g')
|
||||||
|
};
|
||||||
|
|
||||||
let mapData = [];
|
let mapData = [];
|
||||||
let trackNameCounting = {};
|
let trackNameCounting = {};
|
||||||
@@ -67,8 +76,17 @@ let markers = [];
|
|||||||
let currentMapNav = {};
|
let currentMapNav = {};
|
||||||
let previousMapScale = -1;
|
let previousMapScale = -1;
|
||||||
|
|
||||||
|
let MapMatrix = {};
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
let dynamicStyles = [];
|
||||||
|
for(let i=0; i<scaleCullThresholds.length; i++){
|
||||||
|
dynamicStyles.push(`.maxZoomCull_${i}{display:var(--maxZoomCull_state_${i});}`);
|
||||||
|
dynamicStyles.push(`.minZoomCull_${i}{display:var(--minZoomCull_state_${i});}`);
|
||||||
|
}
|
||||||
|
document.getElementById('zoomStyle').innerHTML = dynamicStyles.join('\n');
|
||||||
await loadTrackData('trackdata_dv.json');
|
await loadTrackData('trackdata_dv.json');
|
||||||
|
await loadPoiData('poi_dv.json');
|
||||||
mapScrollSetup();
|
mapScrollSetup();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -78,6 +96,21 @@ async function loadTrackData(file){
|
|||||||
fillSvg();
|
fillSvg();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadPoiData(file){
|
||||||
|
poiData = await (await fetch(new Request(file))).json();
|
||||||
|
|
||||||
|
for(let layerIdx in poiLayers){
|
||||||
|
poiLayers[layerIdx].setAttribute('id', 'poi_'+layerIdx);
|
||||||
|
if(layerIdx == 'container') continue;
|
||||||
|
poiLayers.container.appendChild(poiLayers[layerIdx]);
|
||||||
|
}
|
||||||
|
map_markers.appendChild(poiLayers.container);
|
||||||
|
|
||||||
|
for(let poi of poiData){
|
||||||
|
addPoi(poi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Handling for the map scrolling and zooming */
|
/** Handling for the map scrolling and zooming */
|
||||||
function mapScrollSetup(){
|
function mapScrollSetup(){
|
||||||
let mapNav = {x:currentMapNav.x, y:currentMapNav.y, scale:currentMapNav.scale};
|
let mapNav = {x:currentMapNav.x, y:currentMapNav.y, scale:currentMapNav.scale};
|
||||||
@@ -149,10 +182,11 @@ function updateMapview(navData = {x:0, y:0, scale:1}){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
map_rails.setAttribute('stroke-width', Utils.clamp(trackWidth.base/navData.scale, trackWidth.min, trackWidth.max));
|
map_rails.setAttribute('stroke-width', Utils.clamp(trackWidth.base/navData.scale, trackWidth.min, trackWidth.max));
|
||||||
styleRoot.style.setProperty('--signScale', Utils.clamp(signSize.base/navData.scale, signSize.min, signSize.max));
|
styleRoot.style.setProperty('--markerScale', 1/navData.scale);
|
||||||
if(dirtyScale){
|
if(dirtyScale){
|
||||||
for(let i=0; i<scaleCullThresholds.length; i++){
|
for(let i=0; i<scaleCullThresholds.length; i++){
|
||||||
styleRoot.style.setProperty(`--cullThreshold_state_${i}`, navData.scale >= scaleCullThresholds[i].scale ? 'initial' : 'none')
|
styleRoot.style.setProperty(`--minZoomCull_state_${i}`, navData.scale >= scaleCullThresholds[i].scale ? 'initial' : 'none');
|
||||||
|
styleRoot.style.setProperty(`--maxZoomCull_state_${i}`, navData.scale <= scaleCullThresholds[i].scale ? 'initial' : 'none');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
previousMapScale = navData.scale;
|
previousMapScale = navData.scale;
|
||||||
@@ -171,16 +205,27 @@ function establishDimensions(){
|
|||||||
let maxAlt = -Infinity;
|
let maxAlt = -Infinity;
|
||||||
for(const obj of mapData){
|
for(const obj of mapData){
|
||||||
for(const point of obj.points){
|
for(const point of obj.points){
|
||||||
minX = Math.min(minX, point[0].x, point[1].x, point[2].x);
|
minX = Math.min(minX, point.position.x, point.h1.x, point.h2.x);
|
||||||
minY = Math.min(minY, point[0].z, point[1].z, point[2].z);
|
minY = Math.min(minY, point.position.z, point.h1.z, point.h2.z);
|
||||||
minAlt = Math.min(minAlt, point[0].y, point[1].y, point[2].y);
|
minAlt = Math.min(minAlt, point.position.y, point.h1.y, point.h2.y);
|
||||||
maxX = Math.max(maxX, point[0].x, point[1].x, point[2].x);
|
maxX = Math.max(maxX, point.position.x, point.h1.x, point.h2.x);
|
||||||
maxY = Math.max(maxY, point[0].z, point[1].z, point[2].z);
|
maxY = Math.max(maxY, point.position.z, point.h1.z, point.h2.z);
|
||||||
maxAlt = Math.max(maxAlt, point[0].y, point[1].y, point[2].y);
|
maxAlt = Math.max(maxAlt, point.position.y, point.h1.y, point.h2.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let width = maxX-minX;
|
let width = maxX-minX;
|
||||||
let height = maxY-minY;
|
let height = maxY-minY;
|
||||||
|
MapMatrix = {
|
||||||
|
x1: minX,
|
||||||
|
x2: maxX,
|
||||||
|
y1: minY,
|
||||||
|
y2: maxY,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
fixY: yIn => {
|
||||||
|
return minY+maxY-yIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
map.setAttribute('viewBox', `${minX-padding} ${minY-padding} ${width+2*padding} ${height+2*padding}`);
|
map.setAttribute('viewBox', `${minX-padding} ${minY-padding} ${width+2*padding} ${height+2*padding}`);
|
||||||
map_markers.setAttribute('viewBox', map.getAttribute('viewBox'));
|
map_markers.setAttribute('viewBox', map.getAttribute('viewBox'));
|
||||||
updateMapview({
|
updateMapview({
|
||||||
@@ -193,9 +238,9 @@ function establishDimensions(){
|
|||||||
// Flip the z coordinate so the map doesn't display upside-down
|
// Flip the z coordinate so the map doesn't display upside-down
|
||||||
for(const obj of mapData){
|
for(const obj of mapData){
|
||||||
for(const point of obj.points){
|
for(const point of obj.points){
|
||||||
point[0].z = minY+maxY-point[0].z;
|
point.position.z = minY+maxY-point.position.z;
|
||||||
point[1].z = minY+maxY-point[1].z;
|
point.h1.z = minY+maxY-point.h1.z;
|
||||||
point[2].z = minY+maxY-point[2].z;
|
point.h2.z = minY+maxY-point.h2.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,6 +255,7 @@ function fillSvg(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sortTracks();
|
sortTracks();
|
||||||
|
setTrackColorMode('Grade');
|
||||||
drawMarkers();
|
drawMarkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,12 +267,29 @@ function drawTracks(bezierData){
|
|||||||
}else{
|
}else{
|
||||||
trackNameCounting[bezierData.name]++;
|
trackNameCounting[bezierData.name]++;
|
||||||
}
|
}
|
||||||
|
let yardData = /\[(#)\]|\[(Y)\]_\[(.*?)\]_\[((.*?)-(.*?)-(.*?))\]/.exec(bezierData.name);
|
||||||
|
if(yardData){
|
||||||
|
if(yardData[1]){ // track is [#], thus in yard limits, but not a specific designated yard.
|
||||||
|
bezierData.isYard = true;
|
||||||
|
}else if(yardData[2]){ // track is [Y], and is a specific yard.
|
||||||
|
bezierData.isYard = true;
|
||||||
|
bezierData.yardStation = yardData[3]; // Which station the track belongs to
|
||||||
|
bezierData.yardDesignation = yardData[4]; // Full yard designation, used on signs
|
||||||
|
bezierData.yardName = yardData[5]; // A yard, B yard, C yard, etc.
|
||||||
|
bezierData.yardSidingNumber = yardData[6]; // Which siding within the yard
|
||||||
|
bezierData.yardUsage = yardData[7]; // Outbound? Parking? Inbound? Loading? That's this.
|
||||||
|
}
|
||||||
|
}else if(/Turntable Track/.test(bezierData.name)){
|
||||||
|
bezierData.isTurntable = true;
|
||||||
|
}else if(/\[track (diverging|through)\]/.test(bezierData.name)){
|
||||||
|
bezierData.isPoint = true;
|
||||||
|
}
|
||||||
for(let i=0; i+1<bezierData.points.length; i++){
|
for(let i=0; i+1<bezierData.points.length; i++){
|
||||||
const bezStart = bezierData.points[i][0];
|
const bezStart = bezierData.points[i].position;
|
||||||
const bezHandle1 = bezierData.points[i][2];
|
const bezHandle1 = bezierData.points[i].h2;
|
||||||
const bezHandle2 = bezierData.points[i+1][1];
|
const bezHandle2 = bezierData.points[i+1].h1;
|
||||||
const bezEnd = bezierData.points[i+1][0];
|
const bezEnd = bezierData.points[i+1].position;
|
||||||
let newBezier = document.createElementNS(svgns, 'path');
|
bezierData.points[i].element = document.createElementNS(svgns, 'path');
|
||||||
let genPath = 'M ';
|
let genPath = 'M ';
|
||||||
genPath += `${bezStart.x} ${bezStart.z} `;
|
genPath += `${bezStart.x} ${bezStart.z} `;
|
||||||
genPath += `C ${bezHandle1.x} ${bezHandle1.z} ${bezHandle2.x} ${bezHandle2.z} ${bezEnd.x} ${bezEnd.z} `;
|
genPath += `C ${bezHandle1.x} ${bezHandle1.z} ${bezHandle2.x} ${bezHandle2.z} ${bezEnd.x} ${bezEnd.z} `;
|
||||||
@@ -235,18 +298,20 @@ function drawTracks(bezierData){
|
|||||||
bezierData.points[i].bezLength = Bezier.estimateLength(bezStart, bezHandle1, bezHandle2, bezEnd, bezierLengthResolution);
|
bezierData.points[i].bezLength = Bezier.estimateLength(bezStart, bezHandle1, bezHandle2, bezEnd, bezierLengthResolution);
|
||||||
bezierData.points[i].curvature = Bezier.estimateCurvature(bezStart, bezHandle1, bezHandle2, bezEnd, bezierCurvatureResolution);
|
bezierData.points[i].curvature = Bezier.estimateCurvature(bezStart, bezHandle1, bezHandle2, bezEnd, bezierCurvatureResolution);
|
||||||
bezierData.points[i].postedSpeed = Utils.radiusToSpeed(1/bezierData.points[i].curvature);
|
bezierData.points[i].postedSpeed = Utils.radiusToSpeed(1/bezierData.points[i].curvature);
|
||||||
newBezier.setAttribute('d', genPath);
|
if(bezierData.isYard || bezierData.isTurntable) bezierData.points[i].postedSpeed = Math.min(bezierData.points[i].postedSpeed, 50);
|
||||||
|
bezierData.points[i].element.setAttribute('d', genPath);
|
||||||
|
|
||||||
newBezier.classList.add('rail');
|
bezierData.points[i].element.classList.add('rail');
|
||||||
newBezier.classList.add(bezierData.points[i].gradeClass != null ? 'grade_'+bezierData.points[i].gradeClass : 'grade_flat');
|
//bezierData.points[i].element.setAttribute('stroke', Config.gradeColors[bezierData.points[i].gradeClass ? 'grade_'+bezierData.points[i].gradeClass : 'grade_flat']);
|
||||||
|
//bezierData.points[i].element.classList.add(bezierData.points[i].gradeClass != null ? 'grade_'+bezierData.points[i].gradeClass : 'grade_flat');
|
||||||
|
|
||||||
//newBezier.setAttribute('stroke', Utils.rgba2hex(bezierData.points[i].grade*50*0,(bezStart.y-113)/(252-113),bezierData.points[i].bezLength*0.01*0,1.0));
|
//bezierData.points[i].element.setAttribute('stroke', Utils.rgba2hex(bezierData.points[i].grade*50*0,(bezStart.y-113)/(252-113),bezierData.points[i].bezLength*0.01*0,1.0));
|
||||||
//newBezier.setAttribute('stroke', Utils.rgba2hex((1/bezierData.points[i].curvature) * 100,0,0,1.0));
|
//bezierData.points[i].element.setAttribute('stroke', Utils.rgba2hex((1/bezierData.points[i].curvature) * 100,0,0,1.0));
|
||||||
//newBezier.setAttribute('stroke', trackCol);
|
//bezierData.points[i].element.setAttribute('stroke', trackCol);
|
||||||
//newBezier.setAttribute('data-grade', bezierData.points[i].grade);
|
//bezierData.points[i].element.setAttribute('data-grade', bezierData.points[i].grade);
|
||||||
//newBezier.setAttribute('data-length', bezierData.points[i].bezLength);
|
//bezierData.points[i].element.setAttribute('data-length', bezierData.points[i].bezLength);
|
||||||
//newBezier.setAttribute('data-maxradius', 1/bezierData.points[i].curvature);
|
//bezierData.points[i].element.setAttribute('data-maxradius', 1/bezierData.points[i].curvature);
|
||||||
tracks.push([(bezStart.y+bezEnd.y)*0.5, newBezier]);
|
tracks.push([(bezStart.y+bezEnd.y)*0.5, bezierData.points[i].element]);
|
||||||
|
|
||||||
// Curve tooltip
|
// Curve tooltip
|
||||||
let title = document.createElementNS(svgns, 'title');
|
let title = document.createElementNS(svgns, 'title');
|
||||||
@@ -258,7 +323,7 @@ function drawTracks(bezierData){
|
|||||||
`Length: ${Math.round(bezierData.points[i].bezLength*10)/10} meters`,
|
`Length: ${Math.round(bezierData.points[i].bezLength*10)/10} meters`,
|
||||||
`Altitude: ${Math.round((bezStart.y+bezEnd.y)*0.5)} meters`,
|
`Altitude: ${Math.round((bezStart.y+bezEnd.y)*0.5)} meters`,
|
||||||
].join('\n');
|
].join('\n');
|
||||||
newBezier.appendChild(title);
|
bezierData.points[i].element.appendChild(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Signage
|
// Add Signage
|
||||||
@@ -283,17 +348,17 @@ function drawTracks(bezierData){
|
|||||||
}else{
|
}else{
|
||||||
//Grade Signs
|
//Grade Signs
|
||||||
if(trackZoneData.gradeClass != bezierData.points[i].gradeClass || trackZoneData.gradeDirection != Math.sign(bezierData.points[i].grade) || trackZoneData.gradeSectionLength > maxSectionLength || zI > 0){
|
if(trackZoneData.gradeClass != bezierData.points[i].gradeClass || trackZoneData.gradeDirection != Math.sign(bezierData.points[i].grade) || trackZoneData.gradeSectionLength > maxSectionLength || zI > 0){
|
||||||
if(trackZoneData.gradeClass != null){
|
if(trackZoneData.gradeClass != 'flat'){
|
||||||
let offset = Math.floor((trackZoneData.gradeCount+1)/2)+1;
|
let offset = Math.floor((trackZoneData.gradeCount+1)/2)+1;
|
||||||
let center = trackZoneData.gradeCount % 2 ? 1 : 0.5;
|
let center = trackZoneData.gradeCount % 2 ? 1 : 0.5;
|
||||||
let b1 = bezierData.points[(i+zI)-offset][0];
|
let b1 = bezierData.points[(i+zI)-offset].position;
|
||||||
let b2 = bezierData.points[(i+zI)-offset][2];
|
let b2 = bezierData.points[(i+zI)-offset].h2;
|
||||||
let b3 = bezierData.points[(i+zI)+1-offset][1];
|
let b3 = bezierData.points[(i+zI)+1-offset].h1;
|
||||||
let b4 = bezierData.points[(i+zI)+1-offset][0];
|
let b4 = bezierData.points[(i+zI)+1-offset].position;
|
||||||
markers.push({
|
markers.push({
|
||||||
type: 'grade',
|
type: 'grade',
|
||||||
value: bezierData.points[(i+zI)-offset].grade,
|
value: bezierData.points[(i+zI)-offset].grade,
|
||||||
class: 'grade_'+trackZoneData.gradeClass,
|
gradeClass: trackZoneData.gradeClass,
|
||||||
position: Bezier.evaluatePoint(b1, b2, b3, b4, center),
|
position: Bezier.evaluatePoint(b1, b2, b3, b4, center),
|
||||||
sectionLength: trackZoneData.gradeSectionLength,
|
sectionLength: trackZoneData.gradeSectionLength,
|
||||||
cullLevel: Math.round(scaleCullThresholds.length-1-trackZoneData.gradeSectionLength/scaleCullBaseSectionLength),
|
cullLevel: Math.round(scaleCullThresholds.length-1-trackZoneData.gradeSectionLength/scaleCullBaseSectionLength),
|
||||||
@@ -311,10 +376,10 @@ function drawTracks(bezierData){
|
|||||||
if(trackZoneData.speed != bezierData.points[i].postedSpeed || trackZoneData.speedSectionLength > maxSectionLength || zI > 0){
|
if(trackZoneData.speed != bezierData.points[i].postedSpeed || trackZoneData.speedSectionLength > maxSectionLength || zI > 0){
|
||||||
let offset = Math.floor((trackZoneData.speedCount+1)/2)+1;
|
let offset = Math.floor((trackZoneData.speedCount+1)/2)+1;
|
||||||
let center = trackZoneData.speedCount % 2 ? 0.75 : 0.25;
|
let center = trackZoneData.speedCount % 2 ? 0.75 : 0.25;
|
||||||
let b1 = bezierData.points[(i+zI)-offset][0];
|
let b1 = bezierData.points[(i+zI)-offset].position;
|
||||||
let b2 = bezierData.points[(i+zI)-offset][2];
|
let b2 = bezierData.points[(i+zI)-offset].h2;
|
||||||
let b3 = bezierData.points[(i+zI)+1-offset][1];
|
let b3 = bezierData.points[(i+zI)+1-offset].h1;
|
||||||
let b4 = bezierData.points[(i+zI)+1-offset][0];
|
let b4 = bezierData.points[(i+zI)+1-offset].position;
|
||||||
let cullLevel = Math.round(scaleCullThresholds.length-1-trackZoneData.gradeSectionLength/scaleCullBaseSectionLengthSpeedboard);
|
let cullLevel = Math.round(scaleCullThresholds.length-1-trackZoneData.gradeSectionLength/scaleCullBaseSectionLengthSpeedboard);
|
||||||
let speedDelta = Math.max(0,
|
let speedDelta = Math.max(0,
|
||||||
(bezierData.points[i].postedSpeed != null && bezierData.points[i].postedSpeed < 100) ? bezierData.points[i].postedSpeed-trackZoneData.speed : 0,
|
(bezierData.points[i].postedSpeed != null && bezierData.points[i].postedSpeed < 100) ? bezierData.points[i].postedSpeed-trackZoneData.speed : 0,
|
||||||
@@ -330,7 +395,7 @@ function drawTracks(bezierData){
|
|||||||
value: trackZoneData.speed,
|
value: trackZoneData.speed,
|
||||||
position: Bezier.evaluatePoint(b1, b2, b3, b4, center),
|
position: Bezier.evaluatePoint(b1, b2, b3, b4, center),
|
||||||
sectionLength: trackZoneData.speedSectionLength,
|
sectionLength: trackZoneData.speedSectionLength,
|
||||||
cullLevel: cullLevel,
|
cullLevel: cullLevel == 1 ? 2 : cullLevel,
|
||||||
tangent: Bezier.evaluateVelocity(b1, b2, b3, b4, center)
|
tangent: Bezier.evaluateVelocity(b1, b2, b3, b4, center)
|
||||||
});
|
});
|
||||||
resetTzdSpeed();
|
resetTzdSpeed();
|
||||||
@@ -353,45 +418,194 @@ function sortTracks(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create the signage */
|
function setTrackColorMode(mode){
|
||||||
function drawMarkers(){
|
let modeFunction = null;
|
||||||
const gradeSigns = document.createElementNS(svgns, 'g');
|
switch(mode){
|
||||||
gradeSigns.setAttribute('id', 'grade_signs');
|
case 'Track Type':
|
||||||
map_markers.appendChild(gradeSigns);
|
modeFunction = (section, curve) => {
|
||||||
const speedSigns = document.createElementNS(svgns, 'g');
|
let finalColor = '#aaa';
|
||||||
speedSigns.setAttribute('id', 'speed_signs');
|
if(curve.isYard && curve.yardDesignation) finalColor = '#4bf';
|
||||||
map_markers.appendChild(speedSigns);
|
else if(curve.isYard) finalColor = '#4fb';
|
||||||
for(const markerData of markers){
|
else if(curve.isPoint) finalColor = '#fb4';
|
||||||
//if(markerData.skip) continue;
|
else if(curve.isTurntable) finalColor = '#b4f';
|
||||||
let marker = document.createElementNS(svgns, 'g');
|
|
||||||
let markerImg = document.createElementNS(svgns, 'use');
|
|
||||||
let title = document.createElementNS(svgns, 'title');
|
|
||||||
marker.appendChild(markerImg);
|
|
||||||
marker.appendChild(title);
|
|
||||||
marker.setAttribute('transform', `translate(${markerData.position.x} ${markerData.position.z})`);
|
|
||||||
// Grade signs
|
|
||||||
if(markerData.type == 'grade'){
|
|
||||||
markerImg.setAttribute('href', '#gradeArrow');
|
|
||||||
markerImg.classList.add('sign', 'gradeSign');
|
|
||||||
if(markerData.class) markerImg.classList.add(markerData.class);
|
|
||||||
const tanLen = Math.sqrt(markerData.tangent.x*markerData.tangent.x + markerData.tangent.z*markerData.tangent.z) * Math.sign(markerData.tangent.y);
|
|
||||||
const rot = Math.atan2(markerData.tangent.x/tanLen, -markerData.tangent.z/tanLen) * (180/Math.PI);
|
|
||||||
marker.setAttribute('transform', `translate(${markerData.position.x} ${markerData.position.z}) rotate(${rot})`);
|
|
||||||
title.innerHTML = `${Math.round(markerData.value*1000)/10}% Grade\nSection Length: ${markerData.sectionLength.toFixed(1)} meters`;
|
|
||||||
gradeSigns.appendChild(marker);
|
|
||||||
// Speed Signs
|
|
||||||
}else if(markerData.type == 'speed'){
|
|
||||||
markerImg.setAttribute('href', `#speedSign_${Math.round(markerData.value/10)}`);
|
|
||||||
markerImg.classList.add('sign', 'speedSign');
|
|
||||||
title.innerHTML = `${Math.round(markerData.value)} km/h\nSection Length: ${markerData.sectionLength.toFixed(1)} meters`;
|
|
||||||
/*let offset = Vector.normalize({x:markerData.tangent.z, y:0, z:-markerData.tangent.x});
|
|
||||||
marker.setAttribute('transform', `translate(${markerData.position.x + offset.x*100} ${markerData.position.z + offset.z*50})`);*/
|
|
||||||
marker.setAttribute('transform', `translate(${markerData.position.x} ${markerData.position.z})`);
|
|
||||||
speedSigns.appendChild(marker);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
section.element.setAttribute('stroke', finalColor);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'Grade':
|
||||||
|
modeFunction = section => {
|
||||||
|
section.element.setAttribute('stroke', Config.gradeColors['grade_'+section.gradeClass]);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
modeFunction = section => {
|
||||||
|
section.element.setAttribute('stroke', '#fff');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(modeFunction !== null){
|
||||||
|
for(let curve of mapData){
|
||||||
|
for(let section of curve.points){
|
||||||
|
if(!section.element) continue;
|
||||||
|
modeFunction(section, curve);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create the signage */
|
||||||
|
function drawMarkers(){
|
||||||
|
const signage_container = document.createElementNS(svgns, 'g');
|
||||||
|
const gradeSigns = document.createElementNS(svgns, 'g');
|
||||||
|
const speedSigns = document.createElementNS(svgns, 'g');
|
||||||
|
|
||||||
|
signage_container.setAttribute('id', 'signage_container');
|
||||||
|
gradeSigns.setAttribute('id', 'signage_grade');
|
||||||
|
speedSigns.setAttribute('id', 'signage_speed');
|
||||||
|
|
||||||
|
map_markers.appendChild(signage_container);
|
||||||
|
signage_container.appendChild(gradeSigns);
|
||||||
|
signage_container.appendChild(speedSigns);
|
||||||
|
|
||||||
|
for(const markerData of markers){
|
||||||
|
//if(markerData.skip) continue;
|
||||||
|
let markerElement = document.createElementNS(svgns, 'g');
|
||||||
|
let markerImg = document.createElementNS(svgns, 'use');
|
||||||
|
let markerTooltip = document.createElementNS(svgns, 'title');
|
||||||
|
markerElement.appendChild(markerImg);
|
||||||
|
markerElement.appendChild(markerTooltip);
|
||||||
|
markerElement.setAttribute('transform', `translate(${markerData.position.x} ${markerData.position.z})`);
|
||||||
|
markerImg.classList.add('fixedScale');
|
||||||
|
// Grade signs
|
||||||
|
if(markerData.type == 'grade'){
|
||||||
|
markerImg.setAttribute('href', '#gradeArrow');
|
||||||
|
markerImg.setAttribute('fill', Config.gradeColors['grade_'+markerData.gradeClass]);
|
||||||
|
const tanLen = Math.sqrt(markerData.tangent.x*markerData.tangent.x + markerData.tangent.z*markerData.tangent.z) * Math.sign(markerData.tangent.y);
|
||||||
|
const rot = Math.atan2(markerData.tangent.x/tanLen, -markerData.tangent.z/tanLen) * (180/Math.PI);
|
||||||
|
markerElement.setAttribute('transform', `translate(${markerData.position.x} ${markerData.position.z}) rotate(${rot})`);
|
||||||
|
markerTooltip.innerHTML = `${Math.round(markerData.value*1000)/10}% Grade\nSection Length: ${markerData.sectionLength.toFixed(1)} meters`;
|
||||||
|
gradeSigns.appendChild(markerElement);
|
||||||
|
// Speed Signs
|
||||||
|
}else if(markerData.type == 'speed'){
|
||||||
|
markerImg.setAttribute('href', `#speedSign_${Math.round(markerData.value/10)}`);
|
||||||
|
markerTooltip.innerHTML = `${Math.round(markerData.value)} km/h\nSection Length: ${markerData.sectionLength.toFixed(1)} meters`;
|
||||||
|
markerElement.setAttribute('transform', `translate(${markerData.position.x} ${markerData.position.z})`);
|
||||||
|
speedSigns.appendChild(markerElement);
|
||||||
|
}
|
||||||
|
|
||||||
if(markerData.cullLevel){
|
if(markerData.cullLevel){
|
||||||
marker.classList.add(`cullThreshold_${Math.min(scaleCullThresholds.length-1, markerData.cullLevel)}`);
|
markerElement.classList.add(`minZoomCull_${Math.min(scaleCullThresholds.length-1, markerData.cullLevel)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addPoi(poi, level = 0){
|
||||||
|
let poiElement = document.createElementNS(svgns, 'g');
|
||||||
|
let poiDisplay = document.createElementNS(svgns, 'g');
|
||||||
|
let poiIcon = document.createElementNS(svgns, poi.type == 'station' ? 'text' : 'use');
|
||||||
|
let poiTooltip = document.createElementNS(svgns, 'title');
|
||||||
|
poiElement.appendChild(poiDisplay);
|
||||||
|
poiDisplay.appendChild(poiIcon);
|
||||||
|
poiElement.appendChild(poiTooltip);
|
||||||
|
poiElement.setAttribute('transform', `translate(${poi.position.x} ${MapMatrix.fixY(poi.position.z)})`);
|
||||||
|
poiElement.classList.add('poi');
|
||||||
|
poiDisplay.classList.add('fixedScale');
|
||||||
|
if(level > 0) poiElement.classList.add('minZoomCull_2');
|
||||||
|
switch(poi.type){
|
||||||
|
case 'station':
|
||||||
|
poiDisplay.classList.remove('fixedScale');
|
||||||
|
poiElement.setAttribute('fill', poi.color ?? '#fff');
|
||||||
|
poiTooltip.innerHTML = poi.name;
|
||||||
|
poiIcon.innerHTML = poi.shorthand;
|
||||||
|
poiIcon.setAttribute('style', `font-size:400px; stroke:${poi.stroke ?? '#000'}; stroke-width:40px; paint-order:stroke; text-anchor:middle;`);
|
||||||
|
poiLayers.stations.prepend(poiElement);
|
||||||
|
break;
|
||||||
|
case 'office':
|
||||||
|
poiIcon.setAttribute('href', '#mrk_office');
|
||||||
|
if(poi.military){
|
||||||
|
poiDisplay.setAttribute('fill', '#978e47');
|
||||||
|
poiTooltip.innerHTML = 'Military Office';
|
||||||
|
}else if(poi.museum){
|
||||||
|
poiDisplay.setAttribute('fill', '#b44');
|
||||||
|
poiTooltip.innerHTML = 'Museum Office';
|
||||||
|
}else{
|
||||||
|
poiDisplay.setAttribute('fill', '#c4693e');
|
||||||
|
poiTooltip.innerHTML = 'Station Office';
|
||||||
|
}
|
||||||
|
poiLayers.service.prepend(poiElement);
|
||||||
|
break;
|
||||||
|
case 'coal':
|
||||||
|
poiIcon.setAttribute('href', '#mrk_coal');
|
||||||
|
poiDisplay.setAttribute('fill', '#202020');
|
||||||
|
poiTooltip.innerHTML = 'Coal Tower';
|
||||||
|
poiLayers.service.prepend(poiElement);
|
||||||
|
break;
|
||||||
|
case 'water':
|
||||||
|
poiIcon.setAttribute('href', '#mrk_water');
|
||||||
|
poiDisplay.setAttribute('fill', '#3fa5ff');
|
||||||
|
poiTooltip.innerHTML = 'Water Tower';
|
||||||
|
poiLayers.service.prepend(poiElement);
|
||||||
|
break;
|
||||||
|
case 'garage':
|
||||||
|
poiIcon.setAttribute('href', '#mrk_garage');
|
||||||
|
poiDisplay.setAttribute('fill', '#8b5dd7');
|
||||||
|
poiTooltip.innerHTML = poi.name ?? 'Unknown Garage';
|
||||||
|
poiLayers.service.prepend(poiElement);
|
||||||
|
poiElement.classList.add('minZoomCull_1');
|
||||||
|
break;
|
||||||
|
case 'landmark':
|
||||||
|
poiIcon.setAttribute('href', '#mrk_landmark');
|
||||||
|
poiDisplay.setAttribute('fill', '#af5757');
|
||||||
|
poiTooltip.innerHTML = poi.name ?? 'Unknown Landmark';
|
||||||
|
poiLayers.landmarks.prepend(poiElement);
|
||||||
|
poiElement.classList.add('minZoomCull_1');
|
||||||
|
break;
|
||||||
|
case 'shop':
|
||||||
|
poiIcon.setAttribute('href', '#mrk_shop');
|
||||||
|
poiDisplay.setAttribute('fill', '#4f54e9');
|
||||||
|
poiTooltip.innerHTML = 'Shop';
|
||||||
|
poiLayers.service.prepend(poiElement);
|
||||||
|
poiElement.classList.add('minZoomCull_1');
|
||||||
|
break;
|
||||||
|
case 'service':
|
||||||
|
let serviceTypes = [];
|
||||||
|
if(poi.repair) serviceTypes.push('Repair');
|
||||||
|
if(poi.diesel) serviceTypes.push('Diesel');
|
||||||
|
if(poi.charger) serviceTypes.push('Charger');
|
||||||
|
|
||||||
|
if(serviceTypes.length == 0){
|
||||||
|
poiIcon.setAttribute('href', '#mrk_service');
|
||||||
|
poiDisplay.setAttribute('fill', '#239a96');
|
||||||
|
poiTooltip.innerHTML = 'Unknown Service';
|
||||||
|
}else{
|
||||||
|
poiIcon.setAttribute('href', '#mrk_service_'+serviceTypes[0].toLowerCase());
|
||||||
|
poiDisplay.setAttribute('fill', '#239a96');
|
||||||
|
let bumpOffset = -200*(serviceTypes.length-1);
|
||||||
|
poiIcon.setAttribute('transform', `translate(${bumpOffset} 0)`);
|
||||||
|
poiTooltip.innerHTML = serviceTypes[0];
|
||||||
|
for(let i=1; i<serviceTypes.length; i++){
|
||||||
|
let subIcon = document.createElementNS(svgns, 'use');
|
||||||
|
subIcon.setAttribute('href', '#mrk_service_'+serviceTypes[i].toLowerCase());
|
||||||
|
subIcon.setAttribute('transform', `translate(${i*400+bumpOffset} 0)`);
|
||||||
|
poiDisplay.appendChild(subIcon);
|
||||||
|
poiTooltip.innerHTML += (i == serviceTypes.length-1 ? (serviceTypes.length == 2 ? ' & ' : ', & ') : ', ')+serviceTypes[i];
|
||||||
|
}
|
||||||
|
poiTooltip.innerHTML += ' Service';
|
||||||
|
|
||||||
|
if(serviceTypes.length > 1){
|
||||||
|
let bgrect = document.createElementNS(svgns, 'rect');
|
||||||
|
bgrect.setAttribute('width', 400*(serviceTypes.length-1));
|
||||||
|
bgrect.setAttribute('height', 400);
|
||||||
|
bgrect.setAttribute('transform', `translate(${-200*(serviceTypes.length-1)} -200)`);
|
||||||
|
poiDisplay.prepend(bgrect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
poiLayers.service.prepend(poiElement);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(poi.children){
|
||||||
|
for(let child of poi.children){
|
||||||
|
addPoi(child, level+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+13
-4
@@ -21,9 +21,12 @@ export function estimateGrade(p1, h1, h2, p2, iterationCount = 50){
|
|||||||
for(let i=0; i<=iterationCount; i++){
|
for(let i=0; i<=iterationCount; i++){
|
||||||
let tan = evaluateVelocity(p1, h1, h2, p2, i/iterationCount);
|
let tan = evaluateVelocity(p1, h1, h2, p2, i/iterationCount);
|
||||||
let newGrade = Math.abs(tan.y)/Math.sqrt(tan.x*tan.x + tan.z*tan.z);
|
let newGrade = Math.abs(tan.y)/Math.sqrt(tan.x*tan.x + tan.z*tan.z);
|
||||||
grade = Math.max(grade, newGrade);
|
if(!Number.isNaN(newGrade)){
|
||||||
totalGrade += newGrade;
|
grade = Math.max(grade, newGrade);
|
||||||
|
totalGrade += newGrade;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(!grade) return 0;
|
||||||
return grade;
|
return grade;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,14 +62,20 @@ export function estimateCurvature(p1, h1, h2, p2, iterationCount = 50){
|
|||||||
let curvature = 0;
|
let curvature = 0;
|
||||||
let t = 0;
|
let t = 0;
|
||||||
let vel = {};
|
let vel = {};
|
||||||
|
let totalCount = 0;
|
||||||
for(let i=0; i<iterationCount; i++){
|
for(let i=0; i<iterationCount; i++){
|
||||||
t = i/iterationCount;
|
t = i/iterationCount;
|
||||||
vel = evaluateVelocity(p1, h1, h2, p2, t);
|
vel = evaluateVelocity(p1, h1, h2, p2, t);
|
||||||
curvature +=
|
let newCurvature =
|
||||||
Vector.length(Vector.cross(vel, evaluateAcceleration(p1, h1, h2, p2, t)))
|
Vector.length(Vector.cross(vel, evaluateAcceleration(p1, h1, h2, p2, t)))
|
||||||
/Math.pow(Vector.length(vel),3);
|
/Math.pow(Vector.length(vel),3);
|
||||||
|
if(!Number.isNaN(newCurvature)){
|
||||||
|
curvature += newCurvature;
|
||||||
|
totalCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return curvature/iterationCount;
|
if(!curvature) return 0.00000001;
|
||||||
|
return curvature/totalCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Evaluate the bezier at `t`, getting position.
|
/** Evaluate the bezier at `t`, getting position.
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export function gradeToClass(grade){
|
|||||||
return gradeIncrements.length-(j+1);
|
return gradeIncrements.length-(j+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 'flat';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function radiusToSpeed(radius){
|
export function radiusToSpeed(radius){
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import * as Utils from './js/utillib.js';
|
import * as Utils from './js/utillib.js';
|
||||||
|
import * as Config from './config.js';
|
||||||
|
|
||||||
let settingEntries = [
|
let settingEntries = [
|
||||||
{
|
{
|
||||||
@@ -8,7 +9,7 @@ let settingEntries = [
|
|||||||
id: 'toggle_signage',
|
id: 'toggle_signage',
|
||||||
state: true,
|
state: true,
|
||||||
func: state =>{
|
func: state =>{
|
||||||
document.getElementById('mapMarkers').style.display = state ? 'unset' : 'none';
|
document.getElementById('signage_container').style.display = state ? 'unset' : 'none';
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@@ -16,7 +17,7 @@ let settingEntries = [
|
|||||||
id: 'toggle_speedSigns',
|
id: 'toggle_speedSigns',
|
||||||
state: true,
|
state: true,
|
||||||
func: state =>{
|
func: state =>{
|
||||||
document.getElementById('speed_signs').style.display = state ? 'unset' : 'none';
|
document.getElementById('signage_speed').style.display = state ? 'unset' : 'none';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -24,11 +25,37 @@ let settingEntries = [
|
|||||||
id: 'toggle_gradeSigns',
|
id: 'toggle_gradeSigns',
|
||||||
state: true,
|
state: true,
|
||||||
func: state =>{
|
func: state =>{
|
||||||
document.getElementById('grade_signs').style.display = state ? 'unset' : 'none';
|
document.getElementById('signage_grade').style.display = state ? 'unset' : 'none';
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Points of Interest',
|
||||||
|
id: 'toggle_poi',
|
||||||
|
state: true,
|
||||||
|
func: state => {
|
||||||
|
document.getElementById('poi_container').style.display = state ? 'unset' : 'none';
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: 'Services',
|
||||||
|
id: 'toggle_services',
|
||||||
|
state: true,
|
||||||
|
func: state =>{
|
||||||
|
document.getElementById('poi_service').style.display = state ? 'unset' : 'none';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Landmarks',
|
||||||
|
id: 'toggle_landmarks',
|
||||||
|
state: true,
|
||||||
|
func: state =>{
|
||||||
|
document.getElementById('poi_landmarks').style.display = state ? 'unset' : 'none';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'Track Color',
|
label: 'Track Color',
|
||||||
id: 'radio_trackColor',
|
id: 'radio_trackColor',
|
||||||
@@ -116,27 +143,34 @@ function populateKey(){
|
|||||||
}else if(i >= 0){
|
}else if(i >= 0){
|
||||||
gradeValue += ` - ${getGradeValue(i+1)}%`;
|
gradeValue += ` - ${getGradeValue(i+1)}%`;
|
||||||
}
|
}
|
||||||
let gradeIcon = document.createElement('svg');
|
addKeyEntry(`<use fill="${Config.gradeColors['grade_'+gradeIndex]}" href="#gradeArrow" transform="rotate(90)"/>`, ` ${gradeValue} Grade`);
|
||||||
gradeIcon.classList.add('inlineSvg');
|
|
||||||
gradeIcon.setAttribute('viewBox', '-50 -50 100 100');
|
|
||||||
gradeIcon.innerHTML = `<use class="gradeSign grade_${gradeIndex}" href="#gradeArrow" transform="rotate(90)"/>`;
|
|
||||||
addKeyEntry(gradeIcon, ` ${gradeValue} Grade`);
|
|
||||||
}
|
}
|
||||||
let speedSignIcon = document.createElement('svg');
|
addKeyEntry('<use href="#speedSign_5"/>', ' Speed Limit');
|
||||||
speedSignIcon.classList.add('inlineSvg');
|
addKeyEntry('<use href="#mrk_office" fill="#c4693e" transform="scale(0.75)"/>', ' Station Office');
|
||||||
speedSignIcon.setAttribute('viewBox', '-50 -50 100 100');
|
addKeyEntry('<use href="#mrk_shop" fill="#4f54e9" transform="scale(0.75)"/>', ' Shop');
|
||||||
speedSignIcon.innerHTML = `<use class="speedSign" href="#speedSign_5"/>`;
|
addKeyEntry('<use href="#mrk_coal" fill="#202020" transform="scale(0.75)"/>', ' Coal Tower');
|
||||||
addKeyEntry(speedSignIcon, ' Speed Limit');
|
addKeyEntry('<use href="#mrk_water" fill="#3fa5ff" transform="scale(0.75)"/>', ' Water Tower');
|
||||||
|
addKeyEntry('<use href="#mrk_landmark" fill="#af5757" transform="scale(0.75)"/>', ' Landmark');
|
||||||
|
addKeyEntry('<use href="#mrk_garage" fill="#8b5dd7" transform="scale(0.75)"/>', ' Garage');
|
||||||
|
addKeyEntry('<use href="#mrk_service_repair" fill="#239a96" transform="scale(0.75)"/>', ' Repair Service');
|
||||||
|
addKeyEntry('<use href="#mrk_service_diesel" fill="#239a96" transform="scale(0.75)"/>', ' Diesel Refuel');
|
||||||
|
addKeyEntry('<use href="#mrk_service_charger" fill="#239a96" transform="scale(0.75)"/>', ' Electric Charger');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an entry to the map key.
|
* Add an entry to the map key.
|
||||||
* @param {Element} keyImage
|
* @param {string} keyImageHTML
|
||||||
* @param {string} keyLabel
|
* @param {string} keyLabel
|
||||||
*/
|
*/
|
||||||
function addKeyEntry(keyImage, keyLabel){
|
function addKeyEntry(keyImageHTML, keyLabel){
|
||||||
let keyDiv = document.createElement('div');
|
let keyDiv = document.createElement('div');
|
||||||
if(keyImage) keyDiv.appendChild(keyImage);
|
if(keyImageHTML){
|
||||||
|
let keyImage = document.createElement('svg');
|
||||||
|
keyImage.innerHTML = keyImageHTML;
|
||||||
|
keyImage.classList.add('inlineSvg');
|
||||||
|
keyImage.setAttribute('viewBox', '-150 -150 300 300');
|
||||||
|
keyDiv.appendChild(keyImage);
|
||||||
|
}
|
||||||
keyDiv.innerHTML += keyLabel;
|
keyDiv.innerHTML += keyLabel;
|
||||||
legendKey.appendChild(keyDiv);
|
legendKey.appendChild(keyDiv);
|
||||||
}
|
}
|
||||||
+28
-20
@@ -4,7 +4,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"CME",
|
"shorthand":"CME",
|
||||||
"color":"#958177",
|
"color":"#958177",
|
||||||
"position":{"x":15622.98,"y":204.2502,"z":11220.5},
|
"position":{"x":15622.98,"y":204.2502,"z":10620.5},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"CMS",
|
"shorthand":"CMS",
|
||||||
"color":"#6f6a58",
|
"color":"#6f6a58",
|
||||||
"position":{"x":8531.313,"y":156.2595,"z":3448.419},
|
"position":{"x":9251.313,"y":156.2595,"z":3408.419},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"CP",
|
"shorthand":"CP",
|
||||||
"color":"#824e4a",
|
"color":"#824e4a",
|
||||||
"position":{"x":2064.521,"y":145.1,"z":9031.848},
|
"position":{"x":2064.521,"y":145.1,"z":8231.848},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"CS",
|
"shorthand":"CS",
|
||||||
"color":"#dfd7dc",
|
"color":"#dfd7dc",
|
||||||
"position":{"x":9985.819,"y":134.6823,"z":1388.548},
|
"position":{"x":9785.819,"y":134.6823,"z":1488.548},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -100,6 +100,10 @@
|
|||||||
"type":"water",
|
"type":"water",
|
||||||
"position":{"x":10249.08,"y":134.7365,"z":1468.002}
|
"position":{"x":10249.08,"y":134.7365,"z":1468.002}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type":"water",
|
||||||
|
"position":{"x":10050.59,"y":134.7859,"z":1370.713}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name":"Olaf's Garage",
|
"name":"Olaf's Garage",
|
||||||
"type":"garage",
|
"type":"garage",
|
||||||
@@ -112,7 +116,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"CW",
|
"shorthand":"CW",
|
||||||
"color":"#f1cdbb",
|
"color":"#f1cdbb",
|
||||||
"position": {"x":1956,"y":122,"z":5692},
|
"position": {"x":1456,"y":122,"z":5692},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -141,7 +145,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"FF",
|
"shorthand":"FF",
|
||||||
"color":"#b2d1ff",
|
"color":"#b2d1ff",
|
||||||
"position":{"x":9435.343,"y":119.1784,"z":13504.95},
|
"position":{"x":9035.343,"y":119.1784,"z":13504.95},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -169,7 +173,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"FM",
|
"shorthand":"FM",
|
||||||
"color":"#ffda62",
|
"color":"#ffda62",
|
||||||
"position":{"x":6027.609,"y":123.8593,"z":6704.711},
|
"position":{"x":6027.609,"y":123.8593,"z":7074.711},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -186,7 +190,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"FRC",
|
"shorthand":"FRC",
|
||||||
"color":"#d3e075",
|
"color":"#d3e075",
|
||||||
"position":{"x":5727.74,"y":144.9063,"z":8757.236},
|
"position":{"x":6427.74,"y":144.9063,"z":8757.236},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -203,7 +207,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"FRS",
|
"shorthand":"FRS",
|
||||||
"color":"#8db16c",
|
"color":"#8db16c",
|
||||||
"position":{"x":5340.794,"y":175.1235,"z":3787.574},
|
"position":{"x":5890.794,"y":175.1235,"z":3787.574},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -221,7 +225,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"GF",
|
"shorthand":"GF",
|
||||||
"color":"#ff9db9",
|
"color":"#ff9db9",
|
||||||
"position":{"x":13002.78,"y":140.2193,"z":10995.55},
|
"position":{"x":13202.78,"y":140.2193,"z":10495.55},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -254,7 +258,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"HB",
|
"shorthand":"HB",
|
||||||
"color":"#ff9db9",
|
"color":"#ff9db9",
|
||||||
"position":{"x":13066.07,"y":113.082,"z":3596.37},
|
"position":{"x":13066.07,"y":113.082,"z":3876.37},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -292,7 +296,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"IME",
|
"shorthand":"IME",
|
||||||
"color":"#ff836f",
|
"color":"#ff836f",
|
||||||
"position":{"x":15041.38,"y":248.062,"z":15341.35},
|
"position":{"x":15041.38,"y":248.062,"z":15741.35},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -319,7 +323,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"IMW",
|
"shorthand":"IMW",
|
||||||
"color":"#dc6f54",
|
"color":"#dc6f54",
|
||||||
"position":{"x":2103.091,"y":133.5531,"z":13359.38},
|
"position":{"x":2163.091,"y":133.5531,"z":13759.38},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -345,7 +349,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"MB",
|
"shorthand":"MB",
|
||||||
"color":"#d6ac71",
|
"color":"#d6ac71",
|
||||||
"position":{"x":12524,"y":215.3452,"z":14749.98},
|
"position":{"x":12524,"y":215.3452,"z":14349.98},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -364,7 +368,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"MF",
|
"shorthand":"MF",
|
||||||
"color":"#ffad6d",
|
"color":"#ffad6d",
|
||||||
"position":{"x":2348.254,"y":159.2693,"z":10823.74},
|
"position":{"x":2848.254,"y":159.2693,"z":10523.74},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -401,7 +405,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"OR",
|
"shorthand":"OR",
|
||||||
"color":"#cf6884",
|
"color":"#cf6884",
|
||||||
"position":{"x":6404.917,"y":143.8076,"z":11133.96},
|
"position":{"x":6934.917,"y":143.8076,"z":11133.96},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -423,7 +427,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"OWC",
|
"shorthand":"OWC",
|
||||||
"color":"#7b6f6e",
|
"color":"#7b6f6e",
|
||||||
"position":{"x":4866.821,"y":122.9323,"z":6291.179},
|
"position":{"x":4466.821,"y":122.9323,"z":6651.179},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -446,7 +450,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"OWN",
|
"shorthand":"OWN",
|
||||||
"color":"#8b715e",
|
"color":"#8b715e",
|
||||||
"position":{"x":11570.04,"y":122.3343,"z":11554.65},
|
"position":{"x":11570.04,"y":122.3343,"z":11954.65},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -465,7 +469,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"SM",
|
"shorthand":"SM",
|
||||||
"color":"#ac9da2",
|
"color":"#ac9da2",
|
||||||
"position": {"x":7821,"y":131,"z":7277},
|
"position": {"x":8321,"y":131,"z":6707},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
@@ -485,6 +489,10 @@
|
|||||||
{
|
{
|
||||||
"type":"water",
|
"type":"water",
|
||||||
"position":{"x":7981.461,"y":131.77,"z":7392.4}
|
"position":{"x":7981.461,"y":131.77,"z":7392.4}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type":"water",
|
||||||
|
"position":{"x":7998.145,"y":131.7769,"z":7477.136}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -493,7 +501,7 @@
|
|||||||
"type":"station",
|
"type":"station",
|
||||||
"shorthand":"SW",
|
"shorthand":"SW",
|
||||||
"color":"#ffce98",
|
"color":"#ffce98",
|
||||||
"position":{"x":1364.217,"y":147.2043,"z":2194.633},
|
"position":{"x":964.217,"y":147.2043,"z":1794.633},
|
||||||
"children":[
|
"children":[
|
||||||
{
|
{
|
||||||
"type":"office",
|
"type":"office",
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wdth,wght@0,62.5..100,100..900;1,62.5..100,100..900&family=Protest+Strike&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wdth,wght@0,62.5..100,100..900;1,62.5..100,100..900&family=Protest+Strike&display=swap');
|
||||||
|
|
||||||
:root{
|
:root{
|
||||||
--grade_flat: #ffff;
|
|
||||||
--grade_0: #f4f7cd;
|
|
||||||
--grade_1: #f8ff99;
|
|
||||||
--grade_2: #edfc1b;
|
|
||||||
--grade_3: #fcb520;
|
|
||||||
--grade_4: #f07837;
|
|
||||||
--grade_5: #e66441;
|
|
||||||
--grade_6: #ce3f57;
|
|
||||||
--grade_7: #c33577;
|
|
||||||
--grade_8: #a3008d;
|
|
||||||
--grade_9: #690097;
|
|
||||||
|
|
||||||
--signScale: 1;
|
--signScale: 1;
|
||||||
--cullThreshold_state_0: none;
|
--cullThreshold_state_0: none;
|
||||||
--cullThreshold_state_1: none;
|
--cullThreshold_state_1: none;
|
||||||
@@ -21,6 +9,8 @@
|
|||||||
--cullThreshold_state_4: none;
|
--cullThreshold_state_4: none;
|
||||||
--cullThreshold_state_5: none;
|
--cullThreshold_state_5: none;
|
||||||
--cullThreshold_state_6: none;
|
--cullThreshold_state_6: none;
|
||||||
|
|
||||||
|
--absScale: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body, #map, #mapContainer, h1, h2, h3, h4, h5{
|
html, body, #map, #mapContainer, h1, h2, h3, h4, h5{
|
||||||
@@ -89,6 +79,9 @@ a:visited{
|
|||||||
|
|
||||||
#legendKey{
|
#legendKey{
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column wrap;
|
||||||
|
max-height: 310px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#footer{
|
#footer{
|
||||||
@@ -128,3 +121,7 @@ a:visited{
|
|||||||
height: 1em;
|
height: 1em;
|
||||||
vertical-align: -0.1em;
|
vertical-align: -0.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.poi{
|
||||||
|
font-variation-settings: "wght" 700;
|
||||||
|
}
|
||||||
+6076
-6076
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user