[네이버 지도] 행정구역 표시(shp -> geojson)
기타2021. 1. 7. 11:01
준비물: 시도 shp, 시군구 shp, 읍면동 shp
프로그램: mapshaper, QGIS, python 3.9.1
국내 행정구역 shp 파일은 용량도 크고 너무 세밀하게 표현된 부분이 많아서
웹에 단순한 행정구역을 표시할 때 용량과 속도 등에서 제약사항이 발생한다.
국내 행정구역 shp 파일에서 사용된 좌표계는 GRS80 (EPSG: 5179) 이므로
네이버 지도에서 사용하는 위도와 경도 좌표계 WGS84 (EPSG: 4326)로 변환해야 한다.
변환 과정 요약
1. mapshaper 등의 프로그램으로 simplify 과정을 거쳐 단순화(shp ▶ shp)
2. QGIS 등의 프로그램을 이용하여 WGS 84 좌표로 변환(shp ▶ json(geojson))
3. python 등을 이용해 전체 geojson 파일에서 필요한 행정구역 파일로 분할 저장(json ▶ json(geojson))
[시군구 geojson 분할 저장] python 3.9.1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - / / 시군구 geojson 분할 저장 / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #python 3.9.1 import json #json 파일 읽기 with open ( 'd:\\sig_202005_wgs84.geojson' , 'r' , encoding = 'UTF8' ) as rf: geojson = json.load(rf) #시군구 반복 for item in geojson[ 'features' ]: code = item[ 'properties' ][ 'SIG_CD' ] #행정구역코드 name = item[ 'properties' ][ 'SIG_KOR_NM' ] #행정구역명 item[ 'id' ] = code; #네이버 지도용 id 설정 #json 파일 저장 경로 path = 'd:\\sig\\'+ code +' .json' print (path + ' ' + name) #json 객체 생성 geo = dict () geo[ 'type' ] = 'FeatureCollection' geo[ 'features' ] = [] #features는 배열 geo[ 'features' ].append(item) #json 파일 저장 with open (path, 'w' , encoding = 'UTF8' ) as wf: json.dump(geo, wf, ensure_ascii = False ) #한글 유니코드 저장 방지 |
[행정구역 json 파일 로드]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | //-------------------------------------- // 행정구역 json 파일 로드 //-------------------------------------- var HOME_PATH = window.HOME_PATH || '.' , urlPrefix = HOME_PATH + '/data/region' , urlSuffix = '.json' , regionGeoJson = [], loadCount = 0; // 행정구역 json 파일 로드 naver.maps.Event.once(map, 'init_stylemap' , function () { for ( var i = 1; i < 18; i++) { var keyword = i + '' ; if (keyword.length === 1) { keyword = '0' + keyword; } $.ajax({ url: urlPrefix + keyword + urlSuffix, success: function (idx) { return function (geojson) { regionGeoJson[idx] = geojson; loadCount++; if (loadCount === 17) { startDataLayer(); } } }(i - 1) }); } }); |
[Geojson 파일 형태]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | //-------------------------------------- // Geojson 파일 형태 //-------------------------------------- // 툴팁 설정 var tooltip = $( '<div style="position: absolute; z-index: 1000; padding: 5px 10px; background-color: #fff; border: solid 2px #000; font-size: 14px; pointer-events: none; display: none;"> </div>' ); tooltip.appendTo(map.getPanes().floatPane); // 로드된 행정구역은 아래와 같은 형태 regionGeoJson.push({ "type" : "FeatureCollection" , "features" : [{ "id" : "11140" , "type" : "Feature" , "properties" : { "SIG_CD" : "11140" , "SIG_ENG_NM" : "Jung-gu" , "SIG_KOR_NM" : "중구" }, "geometry" : { "type" : "MultiPolygon" , "coordinates" : [[[ [127.0233653, 37.5719143], [127.0233917, 37.5719073], [127.0235305, 37.5671585], [127.0235359, 37.5669135], [127.0235319, 37.5668462], [127.0235326, 37.5668336], [127.0217938, 37.5575103], [127.0217328, 37.5575278], [127.0195773, 37.5574955], [127.0196807, 37.5572629], [127.0180939, 37.5568746], [127.0178901, 37.5567028], [127.0162301, 37.5528015], [127.0159829, 37.552589], [127.015938, 37.5525498], [127.015858, 37.552471], [127.0089881, 37.5441349], [127.0050173, 37.5461716], [127.0061278, 37.5481932], [127.0046885, 37.5486851], [127.0045604, 37.5498499], [127.0043733, 37.5501537], [127.0043557, 37.5501974], [127.0043362, 37.5502112], [127.0042094, 37.5501507], [127.0034213, 37.5500195], [127.0028642, 37.5496416], [127.0016841, 37.5500597], [126.9983251, 37.5496954], [126.9944593, 37.547488], [126.9787954, 37.5540872], [126.9724082, 37.5548773], [126.96571, 37.5541518], [126.963376, 37.552259], [126.962778, 37.551848], [126.9626113, 37.5517331], [126.9623428, 37.5515489], [126.9623691, 37.5516032], [126.962376, 37.5516286], [126.9624048, 37.5516477], [126.9623107, 37.55277], [126.9620066, 37.5540349], [126.9619314, 37.554448], [126.9617737, 37.5547951], [126.9617773, 37.554982], [126.9619781, 37.5551268], [126.9621418, 37.5555309], [126.9624769, 37.5559106], [126.9627196, 37.5559726], [126.9631727, 37.5565488], [126.9633575, 37.5566854], [126.9634369, 37.5568535], [126.9634273, 37.5569479], [126.9634093, 37.5569943], [126.963052, 37.5574148], [126.9630411, 37.5580298], [126.9620761, 37.5584566], [126.9615951, 37.5584184], [126.9617358, 37.5588129], [126.961711, 37.5589526], [126.9616892, 37.5589824], [126.9616726, 37.5590258], [126.962956, 37.5591763], [126.9632096, 37.5591958], [126.9633065, 37.5592155], [126.9668376, 37.561274], [126.9674439, 37.5615089], [126.9681526, 37.5616215], [126.969265, 37.5619273], [126.9694319, 37.5619679], [126.9694641, 37.5619758], [126.9693301, 37.5622305], [126.9689586, 37.5629149], [126.967562, 37.5648787], [126.9666982, 37.56582], [126.9668651, 37.5659861], [126.9668874, 37.5660078], [126.9966167, 37.5686865], [126.9968368, 37.5687099], [126.997025, 37.5687315], [127.0007881, 37.5693806], [127.0013078, 37.5694769], [127.014613, 37.5697183], [127.0147018, 37.5697206], [127.0176066, 37.5702101], [127.0177723, 37.5702912], [127.0233653, 37.5719143] ]]] } }] }); |
[행정구역 표시]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | //-------------------------------------- // 행정구역 표시 //-------------------------------------- function startDataLayer() { map.data.setStyle( function (feature) { var styleOptions = { fillColor: '#ff0000' , fillOpacity: 0.0001, strokeColor: '#ff0000' , strokeWeight: 4, strokeOpacity: 0.4 }; if (feature.getProperty( 'focus' )) { styleOptions.fillOpacity = 0.6; styleOptions.fillColor = '#0f0' ; styleOptions.strokeColor = '#0f0' ; styleOptions.strokeWeight = 4; styleOptions.strokeOpacity = 1; } return styleOptions; }); regionGeoJson.forEach( function (geojson) { map.data.addGeoJson(geojson); }); map.data.addListener( 'click' , function (e) { var feature = e.feature; if (feature.getProperty( 'focus' ) !== true ) { feature.setProperty( 'focus' , true ); } else { feature.setProperty( 'focus' , false ); } }); map.data.addListener( 'mouseover' , function (e) { var feature = e.feature; var regionName = feature.getProperty( 'SIG_KOR_NM' ); tooltip.css({ display: '' , left: e.offset.x, top: e.offset.y }).text(regionName); map.data.overrideStyle(feature, { fillOpacity: 0.6, strokeWeight: 4, strokeOpacity: 1 }); }); map.data.addListener( 'mouseout' , function (e) { tooltip.hide().empty(); map.data.revertStyle(); }); } startDataLayer(); |
참고
'기타' 카테고리의 다른 글
[네이버 지도] 마커 클러스터링 (0) | 2021.01.14 |
---|---|
[네이버 지도] 사용자 정의 오버레이 (0) | 2021.01.13 |
티스토리 SyntaxHighlighter 3.0.8.3 사용법 (0) | 2018.10.25 |
택배 조회 URL (0) | 2018.09.18 |
CSS 이미지 위에 텍스트 표시 (0) | 2018.08.20 |