이 글은 Calvin Allen의 게스트 게시물입니다. Calvin은 오하이오주 콜럼버스에서 비즈니스 문제를 해결할 뿐만 아니라 예산과 시간에 맞춰 사용하기 쉬운 소프트웨어를 설계하는 것을 즐기는 .NET 개발자입니다. 그는 소프트웨어를 설계하지 않을 때는 더 나은 소프트웨어 개발자가 되는 방법을 배우고 있습니다. 이것은 그에게 단순한 직업이 아니라 라이프스타일이기도 합니다.
캘빈의 게시물을 팔로우하여 소스 코드와 GitHub를 확인합니다. 그리고 최신 개발자 프리뷰 릴리스 다운로드하기.
GeoJSON이란 무엇인가요? GeoJSON.org 로 정의합니다:
"지리적 데이터 구조를 다양하게 인코딩하기 위한 형식입니다."
그렇다면 이것이 실제로 무엇을 의미할까요? 기본적으로 지리적 객체를 정의하기 위해 JSON 구조를 사용하는 표준 형식입니다. 이러한 '지리적 개체'는 단순한 '점'에서부터 '다각형'과 같은 복잡한 개체까지 다양한 항목이 될 수 있습니다.
다음은 '디나갓 제도'에 대한 '지도상의 지점'의 간단한 예입니다:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "type": "FeatureCollection", "기능": [ { "type": "기능", "지오메트리": { "type": "포인트", "좌표": [ 125.6, 10.1 ] }, "속성": { } } ] } |
이제 배경 이야기를 다 들었으니 "왜 GeoJSON이 필요한가요?"라고 질문하실 수도 있습니다. 간단한 대답은 현재 Google 지도와 같은 다양한 매핑 기술에서 지원되는 표준이기 때문입니다. 데이터가 이미 GeoJSON 형식으로 되어 있으면 다음과 같은 데이터를 제공할 수 있습니다. 직접 를 Google 지도에 추가하고 설명된 대로 개체를 렌더링하면 됩니다. 이렇게 하면 '직접' 형식을 만들 필요가 없을 뿐만 아니라 다른 제공업체에서도 이미 이를 지원하고 있으므로 원하는 대로 활용할 수 있습니다.
코드를 살펴봅시다!
이 글에서는 .NET MVC 애플리케이션, Couchbase(커뮤니티) 서버(및 .NET SDK), Google 지도를 사용하여 GeoJSON 형식을 시연할 예정이므로 이 모든 유틸리티에 대한 실무 지식이 있다고 가정해야 합니다.
이러한 항목을 수행하는 방법을 설명하는 다른 튜토리얼/글이 많이 있으므로 MVC 프로젝트를 만드는 방법이나 Couchbase 설치/구성 방법에 대해서는 자세히 설명하지 않겠습니다. 매튜 그로브스 카우치베이스 블로그.
지금 언급할 한 가지는 제가 Couchbase 버킷을 "기능"이라고 부르고, 로마 주변의 다각형에 대한 문서와 디나갓 제도에 대한 점(위와 같이)이 있는 문서 두 개를 미리 로드해 놓았다는 것입니다. 이 두 json 파일은 이 글의 뒷부분에서 링크할 github 리포지토리에서 찾을 수 있습니다.
Visual Studio에서 새 MVC 웹사이트가 로드된 상태에서 NuGet 패키지 관리자 콘솔을 열고 다음 명령을 입력하여 Couchbase .NET SDK를 로드합니다:
1 |
설치-패키지 카우치베이스넷클라이언트 |
Couchbase .NET SDK 설치가 완료되면 다음 명령을 실행하여 geojson 라이브러리를 설치합니다:
1 |
설치-패키지 geojson.net |
첫 번째 패키지인 "couchbasenetclient"는 GeoJSON 문서를 관리하기 위해 로컬 Couchbase 서버와 통신하는 데 사용됩니다. 이것은 Couchbase 팀에서 생성/지원하는 라이브러리입니다. 다음으로 "geojson.net"은 GeoJSON 문서를 생성/읽기 위한 도우미 라이브러리입니다. 내부적으로, geojson.net 라이브러리는 라이브러리가 제공하는 .NET 유형의 json 직렬화/역직렬화를 위해 JSON.Net을 활용합니다. 이 패키지/라이브러리를 사용하지 않고 직접 유형을 관리할 수도 있지만, 간단하게 유지하기 위해 저는 이 라이브러리를 활용하기로 했습니다.
가장 먼저 해야 할 일은 컨트롤러를 연결하는 것입니다. 프로젝트에 이미 존재하는 "HomeController"를 재사용하겠습니다.
먼저 버킷을 저장하는 데 사용할 생성자를 추가하겠습니다:
1 2 3 4 5 6 7 8 9 |
public 클래스 홈컨트롤러 : 컨트롤러 { 비공개 읽기 전용 IBucket _버킷; public 홈컨트롤러() { _버킷 = 클러스터 도우미.GetBucket("기능"); } } |
이제 세 개의 엔드포인트가 필요합니다.
- 모든 기능 목록 보기
- 지도 페이지에 대한 간단한 라우팅 역할을 할 것입니다(무슨 말인지 알 수 있을 것입니다).
- 마지막으로 Google 지도 API가 직접 호출하여 기능에 대한 JSON을 가져오는 것입니다.
세 가지 모두 여기에 있습니다:
첫 번째는 내 Couchbase 버킷에 있는 전체 기능 목록을 반환하는 작업입니다. 이것은 기능 ID를 문자열 목록으로 가져오는 간단한 N1QL 쿼리일 뿐입니다. (저는 목록 페이지에 있는 기능의 ID에만 관심이 있습니다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public 액션 결과 특징() { var 요청 = 쿼리 요청.만들기("SELECT META().id as `id` FROM `features` as f"); 요청.스캔 일관성(스캔 일관성.요청 플러스); var featureIds = _버킷 .쿼리<동적>(요청) .행 .선택(x => x.id.ToString()) .ToList(); 반환 보기(featureIds); } |
목록 페이지에서 탐색하는 동안 사용자가 클릭한 요청된 기능의 ID를 보유하기 위해 사용하는 간단한 라우팅 방법입니다.
1 2 3 4 |
public 액션 결과 지도 기능(문자열 id) { ViewBag.FeatureId = id; 반환 보기(); } |
마지막으로, 이 메서드는 MapFeature 페이지의 Google Maps API를 통해 호출되어 사용자가 매핑하려는 기능의 JSON을 가져옵니다(다시, geojson.net 라이브러리의 FeatureCollection 객체를 사용하며, 라이브러리에 자체 직렬화기가 함께 제공되는 Json.Net을 사용하여 해당 객체를 직렬화합니다).
1 2 3 4 5 6 |
public ContentResult GetFeatureJson(문자열 id) { var 기능 = _버킷.Get<기능 컬렉션>(id).가치; var json = JsonConvert.SerializeObject(기능); 반환 콘텐츠(json, "application/json"); } |
이제 보기 페이지 자체로 이동합니다(두 개만 있습니다).
'기능' 페이지에서는 Couchbase 버킷에 있는 기능의 목록일 뿐이며, 각 기능 ID를 순서 없이 나열된 목록 안에 있는 작업 링크로 출력합니다:
1 2 3 4 5 6 7 8 9 |
@모델 목록<문자열> <h2>특징</h2> <ul> @foreach (var 기능 in 모델) { <li>@Html.액션링크(기능, "MapFeature", "홈", new { id = 기능 }, null)</li> } </ul> |
마지막 페이지인 맵기능은 '무거운 작업'을 하는 페이지입니다:
1 2 3 4 5 6 |
<h2>지도 기능</h2> @{ var id = ViewBag.FeatureId; } |
$(function () {
var map = new google.maps.Map(document.getElementById('map'), {
줌: 6
});
map.data.loadGeoJson('/Home/GetFeatureJson/@id');
//루프의 각 기능에 대한 콜백 - 마지막 기능이 승리합니다.
함수 forEachGeometry(feature) {
feature.getGeometry().forEachLatLng(resetCenter);
};
//각 지오메트리에서 위도와 경도를 가져와 맵의 중심점을 재설정합니다 - 마지막 지오메트리가 승리 - 완전히 비효율적입니다.
함수 resetCenter(latLng) {
map.setCenter(latLng);
};
//지도에 기능이 추가될 때마다 컬렉션을 반복 - 완전히 비효율적이지만 아이디어를 제공해야 합니다.
map.data.addListener('addfeature', function (e) {
map.data.forEach(forEachGeometry);
});
});