Sebastiankay/eft_group_map_websocket
0
1<!DOCTYPE html>
2<html lang="de">
3 <head>
4 <meta charset="UTF-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 <title>Woods Karte</title>
7 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" crossorigin="" />
8 <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js" integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" crossorigin=""></script>
9 <style>
10 * {
11 margin: 0;
12 padding: 0;
13 }
14 #map {
15 width: 100%;
16 height: 100vh;
17 }
18 /*.label {
19 -webkit-text-stroke: 0.082rem #ccc;
20 text-stroke:: 0.082rem #ccc;
21 font-weight: bold;
22 display: inline-block;
23 }*/
24 </style>
25 <link rel="stylesheet" href="woods.css" />
26 </head>
27 <body>
28 <div id="map"></div>
29 <script>
30 const transform = [0.1855, 113.1, 0.1855, 167.8]
31 const svgBounds = [
32 [650, -945],
33 [-695, 470],
34 ]
35 const bounds = [
36 [650, -945],
37 [-762, 470],
38 ]
39 const coordinateRotation = 180 //180
40 const svgPath = "Woods.svg"
41 const minZoom = 1
42 const maxZoom = 6
43
44 function getCRS(transform) {
45 let scaleX = 1
46 let scaleY = 1
47 let marginX = 0
48 let marginY = 0
49 if (transform) {
50 scaleX = transform[0]
51 scaleY = transform[2] * -1
52 marginX = transform[1]
53 marginY = transform[3]
54 }
55 return L.extend({}, L.CRS.Simple, {
56 transformation: new L.Transformation(scaleX, marginX, scaleY, marginY),
57 projection: L.extend({}, L.Projection.LonLat, {
58 project: (latLng) => {
59 return L.Projection.LonLat.project(applyRotation(latLng, coordinateRotation))
60 },
61 unproject: (point) => {
62 return applyRotation(L.Projection.LonLat.unproject(point), coordinateRotation * -1)
63 },
64 }),
65 })
66 }
67
68 function applyRotation(latLng, rotation) {
69 if (!latLng.lng && !latLng.lat) {
70 return L.latLng(0, 0)
71 }
72 if (!rotation) {
73 return latLng
74 }
75
76 const angleInRadians = (rotation * Math.PI) / 180
77 const cosAngle = Math.cos(angleInRadians)
78 const sinAngle = Math.sin(angleInRadians)
79
80 const { lng: x, lat: y } = latLng
81 const rotatedX = x * cosAngle - y * sinAngle
82 const rotatedY = x * sinAngle + y * cosAngle
83 return L.latLng(rotatedY, rotatedX)
84 }
85
86 function pos(position) {
87 return [position.z, position.x]
88 }
89
90 function getScaledBounds(bounds, scaleFactor) {
91 // Calculate the center point of the bounds
92 const centerX = (bounds[0][0] + bounds[1][0]) / 2
93 const centerY = (bounds[0][1] + bounds[1][1]) / 2
94
95 // Calculate the new width and height
96 const width = bounds[1][0] - bounds[0][0]
97 const height = bounds[1][1] - bounds[0][1]
98 const newWidth = width * scaleFactor
99 const newHeight = height * scaleFactor
100
101 // Update the coordinates of the two points defining the bounds
102 const newBounds = [
103 [centerY - newHeight / 2, centerX - newWidth / 2],
104 [centerY + newHeight / 2, centerX + newWidth / 2],
105 ]
106
107 // console.log("Initial Rectangle:", bounds);
108 // console.log("Scaled Rectangle:", newBounds);
109 // console.log("Center:", L.bounds(bounds).getCenter(true));
110
111 return newBounds
112 }
113
114 // Erstelle die Karte
115 //const map = L.map('map').setView([0, 0], 2);
116
117 const map = L.map("map", {
118 maxBounds: getScaledBounds(svgBounds, 1.5),
119 //maxBounds: bounds,
120 center: [0, 0],
121 zoom: 2,
122 minZoom: 1,
123 maxZoom: 6,
124 zoomSnap: 0.1,
125 scrollWheelZoom: true,
126 wheelPxPerZoomLevel: 120,
127 crs: getCRS(transform),
128 attributionControl: false,
129 id: "wwoodsMap",
130 })
131
132 // Hinzufügen des Image-Overlays
133 const imageUrl = "Woods.svg"
134
135 const overlay = L.imageOverlay(imageUrl, getBounds(svgBounds))
136 overlay.addTo(map)
137
138 // Add labels
139
140 // Hinzufügen der Labels
141 const labels = [
142 { position: [10, -3], text: "Sawmill" },
143 { position: [-485, -390], text: "Scav Town" },
144 { position: [-517, -210], text: "Old Sawmill" },
145 { position: [-80, -680], text: "Cultist Village" },
146 { position: [290, -475], text: "USEC Camp" },
147 { position: [-188, 235], text: "Military Camp" },
148 { position: [-5, -515], text: "Ponds", size: 80 },
149 { position: [-252, -37], text: "Crash Site", size: 80 },
150 { position: [239, -65], text: "Checkpoint", size: 70 },
151 { position: [244, 125], text: "Shack", size: 70 },
152 { position: [-16, -122], text: "Lumber", size: 70 },
153 { position: [-3, -74], text: "Cabins", size: 70 },
154 { position: [-234, 357], text: "Bus Stop", size: 70 },
155 { position: [-327, 19], text: "Jaeger's Camp", size: 70 },
156 { position: [85, -147], text: "Sniper Rock", size: 70 },
157 { position: [200, -606], text: "Convoy", size: 70 },
158 ]
159
160 function getBounds(bounds) {
161 if (!bounds) {
162 return undefined
163 }
164 return L.latLngBounds([bounds[0][1], bounds[0][0]], [bounds[1][1], bounds[1][0]])
165 //return [[bounds[0][1], bounds[0][0]], [bounds[1][1], bounds[1][0]]];
166 }
167
168 const layerOptions = {
169 maxZoom: maxZoom,
170 maxNativeZoom: maxZoom,
171 extents: [
172 {
173 height: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],
174 bounds: [bounds],
175 },
176 ],
177 type: "map-layer",
178 }
179 let tileLayer = false
180 const baseLayers = []
181 const tileSize = 256
182 let svgLayer = false
183 if (svgPath) {
184 const svgBounds2 = svgBounds ? getBounds(svgBounds) : bounds
185 svgLayer = L.imageOverlay(svgPath, svgBounds2, layerOptions)
186 baseLayers.push(svgLayer)
187 }
188
189 if (labels?.length > 0) {
190 const labelsGroup = L.layerGroup()
191 const defaultHeight = (layerOptions.extents[0].height[1] - layerOptions.extents[0].height[0]) / 2 + layerOptions.extents[0].height[0]
192 for (const label of labels) {
193 const fontSize = label.size ? label.size : 100
194 const height = label.position.length < 3 ? defaultHeight : label.position[2]
195 const rotation = label.rotation ? label.rotation : 0
196 L.marker(pos({ x: label.position[0], z: label.position[1] }), {
197 icon: L.divIcon({
198 html: `<div class="label" style="font-size: ${fontSize}%; transform: translate3d(-50%, -50%, 0) rotate(${rotation}deg)">${label.text}</div>`,
199 className: "map-area-label",
200 layers: baseLayers,
201 }),
202 interactive: false,
203 zIndexOffset: -100000,
204 position: {
205 x: label.position[0],
206 y: height,
207 z: label.position[1],
208 },
209 top: typeof label.top !== "undefined" ? label.top : 1000,
210 bottom: typeof label.bottom !== "undefined" ? label.bottom : -1000,
211 }).addTo(labelsGroup)
212 }
213 //addLayer(labelsGroup, 'place-names', 'Landmarks');
214 labelsGroup.addTo(map)
215 }
216
217 /*
218 labels.forEach(label => {
219 const rotation = label.rotation ? label.rotation : 0;
220 const marker = L.marker([label.position[1], label.position[0]], {
221 icon: L.divIcon({
222 className: 'label',
223 html: `<span style="font-size: ${label.size || 20}px; transform: rotate(${rotation}deg)">${label.text}</span>`,
224 iconSize: [100, 20],
225 }),
226 });
227 marker.addTo(map);
228 });
229 */
230 </script>
231 <style>
232 .label {
233 text-align: center;
234 }
235 </style>
236 </body>
237</html>
238 