OpenLayers 3
지도 표출 예제
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OpenLayers 예제</title>
<link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.5.0/css/ol.css">
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.5.0/build/ol.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<script>
// 기본 지도 설정
const map = new ol.Map({
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([126.82861822721662, 37.20462651463613]),
zoom: 14
})
});
// 배경색 설정
document.getElementById('map').style.backgroundColor = 'hsl(0, 0%, 10%)';
// 줌 레벨에 따른 선 너비 계산 함수
function getLineWidth(stops, zoom) {
for (let i = 0; i < stops.length - 1; i++) {
if (zoom >= stops[i][0] && zoom < stops[i + 1][0]) {
const z1 = stops[i][0], w1 = stops[i][1];
const z2 = stops[i + 1][0], w2 = stops[i + 1][1];
const ratio = (zoom - z1) / (z2 - z1);
return w1 + (w2 - w1) * ratio;
}
}
if (zoom >= stops[stops.length - 1][0]) {
return stops[stops.length - 1][1];
}
return stops[0][1];
}
// HD Map 소스
const hdmapSource = new ol.source.VectorTile({
format: new ol.format.MVT(),
url: 'https://dashboard.mqnicrnd5.com/tiles/data/hdmap/{z}/{x}/{y}.pbf'
});
// HD Map 레이어 - Mapbox 스타일 순서대로 구현
const hdmapLayer = new ol.layer.VectorTile({
source: hdmapSource,
renderMode: 'vector',
style: function (feature, resolution) {
const layer = feature.get('layer');
const zoom = map.getView().getZoom();
const styles = [];
// 1. road_belt_element_link (roadbeltelementlink)
if (layer === 'roadbeltelementlink' && zoom >= 14) {
const stops = [[14, 5], [15, 10], [16, 15], [17, 20], [18, 40], [19, 70], [20, 140], [21, 360], [22, 620]];
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#283042',
width: getLineWidth(stops, zoom),
lineCap: 'round'
}),
zIndex: 1
}));
}
// 2. lanebeltelementlink_base (베이스)
if (layer === 'lanebeltelementlink' && zoom >= 14) {
const stops = [[14, 3], [15, 6], [16, 10], [17, 14], [18, 28], [19, 50], [20, 100], [21, 250], [22, 430]];
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#283042',
width: getLineWidth(stops, zoom),
lineCap: 'round'
}),
zIndex: 2
}));
}
// 3. lanebeltsideline_base
if (layer === 'lanebeltsideline' && zoom >= 14) {
const stops = [[14, 3], [15, 6], [16, 10], [17, 14], [18, 28], [19, 50], [20, 100], [21, 250], [22, 430]];
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#283042',
width: getLineWidth(stops, zoom),
lineCap: 'round'
}),
zIndex: 3
}));
}
// 4. roadcentremarking_base
if (layer === 'roadcentremarking' && zoom >= 14) {
const stops = [[14, 3], [15, 6], [16, 10], [17, 14], [18, 28], [19, 50], [20, 100], [21, 250], [22, 430]];
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#283042',
width: getLineWidth(stops, zoom),
lineCap: 'round'
}),
zIndex: 4
}));
}
// 5. lane_belt_element_link (상위 레이어)
if (layer === 'lanebeltelementlink') {
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#4863a3',
width: 1.5
}),
zIndex: 5
}));
}
// 6. road_belt_terminal_line
if (layer === 'roadbeltterminalline' && zoom >= 16) {
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#777',
width: 1.5
}),
zIndex: 6
}));
}
// 7. lane_belt_terminal_line
if (layer === 'lanebeltterminalline' && zoom >= 16) {
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(106, 141, 193, 0.7)',
width: 0.5
}),
zIndex: 7
}));
}
// 8. bridge
if (layer === 'bridge' && zoom >= 15) {
styles.push(new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(155, 131, 101, 0.35)'
}),
zIndex: 8
}));
}
// 9. tunnel
if (layer === 'tunnel' && zoom >= 15) {
styles.push(new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(69, 69, 85, 0.4)'
}),
zIndex: 9
}));
}
// 10. wall
if (layer === 'wall' && zoom >= 16) {
const stops = [[16, 1.5], [18, 2], [20, 3]];
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#5a6a7f',
width: getLineWidth(stops, zoom)
}),
zIndex: 10
}));
}
// 11. fence
if (layer === 'fence' && zoom >= 17) {
const stops = [[17, 0.8], [18, 1], [20, 1.5]];
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#9b9b9b',
width: getLineWidth(stops, zoom)
}),
zIndex: 11
}));
}
// 12. traffic_island_marking
if (layer === 'trafficislandmarking' && zoom >= 16) {
const stops = [[16, 1.5], [18, 2], [20, 3]];
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#ffd54f',
width: getLineWidth(stops, zoom)
}),
zIndex: 12
}));
}
// 13. kerb
if (layer === 'kerb' && zoom >= 17) {
const stops = [[17, 1.2], [18, 1.8], [20, 2.5]];
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#6a7a8f',
width: getLineWidth(stops, zoom)
}),
zIndex: 13
}));
}
// 14. guardrail
if (layer === 'guardrail' && zoom >= 16) {
const stops = [[16, 1.5], [18, 2], [20, 2.5]];
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#8b9baf',
width: getLineWidth(stops, zoom)
}),
zIndex: 14
}));
}
// 15. road_centre_marking (상위 레이어)
if (layer === 'roadcentremarking') {
const linecolour = feature.get('linecolour');
const colorMap = {
2: '#444e68',
3: '#3b39a8',
4: '#216317',
5: '#5a5444',
6: '#631a10',
7: '#000000'
};
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: colorMap[linecolour] || '#444e68',
width: 2
}),
zIndex: 15
}));
}
// 16. lane_edge_marking_dot (점선)
if (layer === 'laneedgemarking') {
const linestyle = feature.get('linestyle');
const linecolour = feature.get('linecolour');
const colorMap = {
2: '#444e68',
3: '#4863a3',
4: '#216317',
5: '#5a5444',
6: '#631a10',
7: '#000000'
};
if (linestyle === 'brokenLine') {
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: colorMap[linecolour] || '#444e68',
width: 2,
lineDash: [6, 5]
}),
zIndex: 16
}));
}
// 17. lane_edge_marking_solid (실선)
else if (linestyle === 1) {
styles.push(new ol.style.Style({
stroke: new ol.style.Stroke({
color: colorMap[linecolour] || '#444e68',
width: 2
}),
zIndex: 17
}));
}
}
return styles.length > 0 ? styles : null;
}
});
// 레이어 추가
map.addLayer(hdmapLayer);
</script>
</body>
</html>Last updated