Skip to content

Instantly share code, notes, and snippets.

@ayaysir
Created October 15, 2018 09:15
Show Gist options
  • Save ayaysir/f22f0f703d1566875b5dbdc3b581e510 to your computer and use it in GitHub Desktop.
Save ayaysir/f22f0f703d1566875b5dbdc3b581e510 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Map 2</title>
<link rel="stylesheet" href="https://openlayers.org/en/v3.19.1/css/ol.css" type="text/css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://openlayers.org/en/v3.19.1/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4-src.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<style>
*{
font-size: 8px
}
body{
margin-top: 10px;
}
.container {
width: 1900px;
max-width: none !important;
}
#map {
width: 100%;
height: 1080px;
}
#mouse-position {
font-size: 8px;
}
#textbox_url {
position: absolute;
top: 0;
left: 0;
width: 1px;
height: 1px;
margin: 0;
padding: 0;
border: 0;
}
</style>
</head>
<body>
<div class=container>
<form>
<div class=row>
<div class=col-5>
<div class=row>
<div class=col-12>
<div class="form-group">
<label>Projection</label>
<select class=form-control id="projection">
<!-- projection: 투영 도법 -->
<option value="EPSG:4326">EPSG:4326</option> <!-- 일반적인 위경도 -->
<option value="EPSG:3857">EPSG:3857</option>
<option value="EPSG:2098">EPSG:2098</option>
<option value="EPSG:5178">EPSG:5178</option>
<option value="EPSG:5185">EPSG:5185</option>
<option value="EPSG:5186" selected>EPSG:5186</option>
<option value="EPSG:5187">EPSG:5187</option>
<option value="EPSG:5188">EPSG:5188</option>
</select>
</div>
</div>
</div>
<div class=row>
<div class="col-12 mb-3">
<label>Precision</label>
<input id="precision" class=form-control type="number" min="0" max="12" value="4" />
</div>
</div>
<div class=row>
<div class="col-12 mb-3">
<button type=button id=drawBtn class="btn btn-primary">Draw</button>
<button type=button id=resetBtn class="btn btn-warning">Reset</button>
<button type=button id=helpBtn class="btn btn-secondary">Help</button>
<button type=button id=exportBtn class="btn btn-primary">Save to PNG...</button>
</div>
</div>
</div>
<div class=col-7>
<label>Coordinates</label>
<div class=form-group>
<textarea id=coorArea class="form-control" rows=6></textarea>
</div>
</div>
</div>
<div id="map" class="map"></div>
<div id="mouse-position" class="text-muted"></div>
</form>
</div>
<input id="textbox_url" value="">
<!--modal-->
<div class="modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Save changes</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script>
proj4.defs('EPSG:21781',
'+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 ' +
'+x_0=600000 +y_0=200000 +ellps=bessel ' +
'+towgs84=660.077,13.551,369.344,2.484,1.783,2.939,5.66 +units=m +no_defs');
proj4.defs('EPSG:5187',
"+proj=tmerc +lat_0=38 +lon_0=129 +k=1 +x_0=200000 +y_0=600000 +ellps=GRS80 +units=m +no_defs")
proj4.defs('EPSG:5178',
"+proj=tmerc +lat_0=38 +lon_0=127.5 +k=0.9996 +x_0=1000000 +y_0=2000000 +ellps=bessel +units=m +no_defs")
proj4.defs('EPSG:5185',
"+proj=tmerc +lat_0=38 +lon_0=125 +k=1 +x_0=200000 +y_0=600000 +ellps=GRS80 +units=m +no_defs")
proj4.defs('EPSG:5186',
"+proj=tmerc +lat_0=38 +lon_0=127 +k=1 +x_0=200000 +y_0=600000 +ellps=GRS80 +units=m +no_defs")
proj4.defs('EPSG:5188',
"+proj=tmerc +lat_0=38 +lon_0=131 +k=1 +x_0=200000 +y_0=600000 +ellps=GRS80 +units=m +no_defs")
proj4.defs('EPSG:2098',
"+proj=tmerc +lat_0=38 +lon_0=125 +k=1 +x_0=200000 +y_0=500000 +ellps=bessel +units=m +no_defs")
ol.proj.setProj4(proj4);
//var 5187Projection = ol.proj.get('EPSG:5187');
console.log(ol.proj.fromLonLat([-0.12755, 51.507222]));
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: ol.coordinate.createStringXY(4),
projection: $("#projection option:selected").val(),
// comment the following two lines to have the mouse position
// be placed within the map.
className: 'custom-mouse-position',
target: document.getElementById('mouse-position'),
undefinedHTML: '&nbsp;'
});
var vectorSource = new ol.source.Vector();
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
var viewer = new ol.View({
center: [14130209, 4516756],
zoom: 6
});
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
//url: 'http://api.vworld.kr/req/wmts/1.0.0/721F7DEE-B8BA-3791-9432-99113FDF13F8/Base/{z}/{y}/{x}.png',
url: 'http://xdworld.vworld.kr:8080/2d/Base/service/{z}/{x}/{y}.png', // 오픈베타 주소
attributions: ['<a href="http://www.vworld.kr/po_main.do" target="_blank">공간정보 오픈플랫폼</a>',
'<a href="https://www.molit.go.kr/" target="_blank">국토교통부</a>'
],
crossOrigin: "anonymous" // CORS 해결 위한 속성
})
// source: new ol.source.OSM()
}),
vectorLayer
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: ({
collapsible: false
})
}).extend([mousePositionControl]),
view: viewer
});
function addPolygon( /* ol.source.Vector */ src, polygonCoorArr) {
var feature = new ol.Feature({
geometry: new ol.geom.Polygon(
[
[
//[13768449, 4871327],
//[14556056, 5287144],
//[14445986, 4166883],
//[13995925, 3861135],
// 좌표 2개 가지고 4각형 그리기
// [14101095, 4520889], // 좌표 1
// [14101095, 4166883],
// [14445986, 4166883], // 좌표 2
// [14445986, 4520889],
// 그리는 순서 ↓ → ↑
[polygonCoorArr[0][0], polygonCoorArr[0][1]], // 좌표 1
[polygonCoorArr[0][0], polygonCoorArr[1][1]],
[polygonCoorArr[1][0], polygonCoorArr[1][1]], // 좌표 2
[polygonCoorArr[1][0], polygonCoorArr[0][1]],
/*
좌표 1: [1x, 1y] (왼쪽 위 모서리)
좌표 2: [2x, 2y] (오른쪽 아래 모서리)
라면
[1x, 1y] [1x, 2y]
[2x, 1y] [2x, 2y]
*/
]
]
)
});
var style = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(0,0,205,0.1)'
})
});
feature.setStyle(style);
feature.set('name', 'CurrentPolygon');
src.addFeature(feature);
}
var globalIsThisCoordOne = true
map.on('click', function(evt) {
var coor_xy = $('#mouse-position').text().split(', ')
var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
return feature;
});
if (feature) {
alert(feature.get('name') + " " + feature.getGeometry().getCoordinates());
} else {
// alert('피처 밖 영역' + " " + $('#mouse-position').text())
$('#textbox_url').val($('#mouse-position').text())
var urlbox = document.getElementById('textbox_url');
urlbox.select();
document.execCommand('Copy');
alert('좌표가 복사되었습니다.');
}
});
var projectionSelect = document.getElementById('projection');
projectionSelect.addEventListener('change', function(event) {
mousePositionControl.setProjection(ol.proj.get(event.target.value));
// 투영 방법 (projection) 변경
});
var precisionInput = document.getElementById('precision');
precisionInput.addEventListener('change', function(event) {
// alert(event.target.valueAsNumber); 1, 2, 3, 4...
var format = ol.coordinate.createStringXY(event.target.valueAsNumber);
mousePositionControl.setCoordinateFormat(format);
// 정확도를 해당 숫자로 변경
});
/*var polygonCoorArr1 = [
[14101095, 4520889],
[14445986, 4166883]
]
addPolygon(vectorSource, polygonCoorArr1);*/
function panToX(extent, duration) {
var pan = ol.animation.pan({
duration: duration,
source: /** @type {ol.Coordinate} */ (viewer.getCenter())
});
map.beforeRender(pan);
// extent: An array of numbers representing an extent: [minx, miny, maxx, maxy].
viewer.fit(extent, map.getSize())
// 센터 자동으로 잡아준다
// 위치 상관없이 min은 작은 값, max는 큰 값임
console.log("mapExtent: " + extent)
}
$('#drawBtn').click(function() {
var coors = $('#coorArea').val()
var coorsArr = coors.split("\n");
console.log(coorsArr)
var minX = Number.POSITIVE_INFINITY;
var minY = Number.POSITIVE_INFINITY;
var maxX = Number.NEGATIVE_INFINITY;
var maxY = Number.NEGATIVE_INFINITY;
if (coors == '') {
alert('빈칸을 입력해주세요.')
return false;
}
function minMax(num, xy) {
if (xy == 'x') {
if (num < minX) minX = num;
else if (num > maxX) maxX = num;
} else if (xy == 'y') {
if (num < minY) minY = num;
else if (num > maxY) maxY = num;
}
}
for (i = 0; i < coorsArr.length; i++) {
if (coorsArr[i] == '') break;
var oneLine = coorsArr[i].split(",")
var coor1x = parseFloat(oneLine[0]);
var coor1y = parseFloat(oneLine[1]);
var coor2x = parseFloat(oneLine[2]);
var coor2y = parseFloat(oneLine[3]);
var polygonCoorArrToUpdate = [
[coor1x, coor1y],
[coor2x, coor2y]
]
if ($('#projection').val() != 'EPSG:3857') {
var destProj = proj4("EPSG:3857");
var sourceProj = proj4($('#projection').val())
// 단일 배열 좌표만 가능
var transformation1 = proj4(sourceProj, destProj, [coor1x, coor1y])
var transformation2 = proj4(sourceProj, destProj, [coor2x, coor2y])
console.log(transformation1)
console.log(transformation2)
var polygonCoorArrToUpdate = [transformation1, transformation2]
}
// x1가 최소(대)값이라면
minMax(polygonCoorArrToUpdate[0][0], 'x')
minMax(polygonCoorArrToUpdate[0][1], 'y')
minMax(polygonCoorArrToUpdate[1][0], 'x')
minMax(polygonCoorArrToUpdate[1][1], 'y')
addPolygon(vectorSource, polygonCoorArrToUpdate);
}
// vectorSource.clear();
// proj4를 사용하려면 반드시 float 등의 숫자로 바꿔줘야한다.
panToX([minX, minY, maxX, maxY], 500)
})
$('#resetBtn').click(function() {
$('#coorArea').val("");
vectorSource.clear()
viewer.setZoom(6);
viewer.setCenter([14130209, 4516756]);
globalIsThisCoordOne = true;
});
$('#projection').change(function() {
/*$('#coor1-x').val('');
$('#coor1-y').val('');
$('#coor2-x').val('');
$('#coor2-y').val('');*/
globalIsThisCoordOne = true;
})
$('#helpBtn').click(function() {
$('.modal-title').text('Instruction');
$('.modal-body').html("[좌표1의 x],[좌표1의 y],[좌표2의 x], [좌표2의 y]<br>라인 1줄에 사각형 1개입니다.")
$('.modal').modal();
})
$('#exportBtn').click(function() {
map.once('postcompose', function(event) {
var canvas = event.context.canvas;
canvas.toBlob(function(blob) {
saveAs(blob, 'map.png');
});
});
map.renderSync();
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment