Script / CSS

G1sUtil.js

G1sBlogger.js

G1sNavigationList.js

G1sCode

G1sTagList

Posts List

2012년 3월 12일 월요일

[Blogspot] 구글 지도를 이용한 블로그 지도 만들기

이전 포스트에 Google Map API를 다뤄 본 것에 이어서, 구글맵과 블로거의 feed를 이용해 제 블로그 상단 페이지에서 있는 Blog Map를 만들어 봤습니다.

Blog Map에 들어가시면 아래와 같이 구글 지도가 보이실 텐데요.



기본 위치는 서울. 그리고 지도 위에는 블로그 post에 설정한 위치가 마커에 표시되구요.
마커를 선택하면 해당 포스트 제목과 Thumbnail, 그리고 약간의 포스트 내용이 써진 정보창이 보이실 것입니다.
역시나 정보창의 제목을 클릭하면 해당 포스트로 이동이 가능하구요.
그외의 우측에는 검색창과 포스트가 표시되구요.

검색을 하면, 해당 포스트 제목이과 포스트의 주소, 그리고 Google GeoAPI를 이용한 주소 검색 결과가 나오고, 해당 포스트 또는 주소를 클릭하면 지도가 해당 위치를 중심으로 이동을 하게 됩니다.

설명은 이만 마치고... 블로그에 이를 추가하시기 위해서는 간단한 설정이 필요한데요.

우선 이 방식은 블로그에서 위치를 지정한 포스트들만 특정 label를 붙여서 이를 이용하는 방식이라 블로그의 posting를 할때부터 몇가지 설정을 해 줘야 합니다.
물론 이미 작성한 포스트에 대해서는 수정을 통해 이 설정을 해주시면 되구요.



위에 스크린샷을 보시면... 구글 블로그에 글을 작성하실때 우측에 보이시는 설정 창입니다.
저 중에 위치를 지도에 노출 시키고 싶으신 포스팅에 특정 태그와 위치 설정을 해 주셔야 합니다.

위에를 보시면 저는 maprss 라는 특정 태그를 지정한 것이 보이구요.
위치는 제주도 한라산으로 설정 된 것이 보이실 겁니다.

이제 코드를 보시면....
<script src="http://maps.google.com/maps/api/js?sensor=true&key=YOUR_API_KEY" type="text/javascript">
</script>
<script type="text/javascript">
        BloggerLocation = function(title,adress,ua,va,link,thumbnail,summary,published){
            this.title = title;
            this.address = adress;
            this.ua = ua;
            this.va = va;
            this.link = link
            this.thumbnail = thumbnail;
            this.summary = summary;
        }
        BloggerLocations = function(feeds){
            this.total = feeds.feed.openSearch$totalResults.$t
            this.posts = new Array();
            for(var i=0; i<this.total; i++){
                var post = feeds.feed.entry[i];
                var location = feeds.feed.entry[i].georss$point.$t.split(' ');
                var link = "";
                for(var j=0; j<post.link.length; j++)
                    if(post.link[j].rel == "alternate"){
                        link = post.link[j].href;
                        break;
                    }
                this.posts[i] = new BloggerLocation(post.title.$t,post.georss$featurename.$t, parseFloat(location[0]),parseFloat(location[1]),link,post.media$thumbnail.url, post.summary.$t,post.published.$t);
            }
        }
        BloggerMap = {
            //초기화.
            initialize : function(feeds) {
                this.blog = new BloggerLocations(feeds);
                this.input = document.getElementById("BloggerMap_input");
                this.address = document.getElementById("BloggerMap_addr");
                this.geocoder = new google.maps.Geocoder();
                
                //지도 생성.
                var latlng = new google.maps.LatLng(37.566419230900905,126.97787415510291);
                var myOptions = {
                    zoom: 6,
                    center: latlng,
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                };
                this.map = new google.maps.Map(document.getElementById("BloggerMap_map"),myOptions);
                
                //마커 생성.
                this.marker = new google.maps.Marker({
                    map : this.map,
                    animation: google.maps.Animation.DROP
                });
                this.markBlog();
                this.setAddressList(this.blog.posts, null);
            },
            markBlog : function(){
                var infowindow = new Array();
                for(var i=0; i<this.blog.total; i++){
                    var marker = new google.maps.Marker({
                        map : this.map,
                        position : new google.maps.LatLng(this.blog.posts[i].ua,this.blog.posts[i].va),
                        title : this.blog.posts[i].title
                    });
                    var contentstr = '<h4><a href="' + this.blog.posts[i].link + '">' +this.blog.posts[i].title + '</a></h4>'+'<div style="height:100px; width:250px;overflow-x:hidden;color:black;"><div style="float:left;"><img src="'+ this.blog.posts[i].thumbnail + '"/></div>'+ '<div style="font-size:small;">' + this.blog.posts[i].summary + '</div></div>';
                    infowindow[i] = new google.maps.InfoWindow({
                        content : contentstr
                    });
                    BloggerMap.clickMarker(marker, infowindow, i);  
                }
            },
            clickMarker : function(marker, infowindow, n){
                google.maps.event.addListener(marker, 'click', function(){
                    for(var i=0; i<infowindow.length; i++)
                        infowindow[i].close();
                    infowindow[n].open(this.map, marker);
                    this.map.setCenter(marker.getPosition());
                });
            },
            searchPost : function (search) {
                var posts = new Array();
                for(var i=0; i<this.blog.total; i++){
                    var title = this.blog.posts[i].title.indexOf(search);
                    var address = this.blog.posts[i].address.indexOf(search);
                    var summary = this.blog.posts[i].summary.indexOf(search);
                    if(title != -1 || address != -1|| summary != -1)
                        posts[posts.length] = this.blog.posts[i];
                }
                return posts;
            },
            //주소 검색.(지오코딩)
            codeAddress : function() {
                var search = this.input.value;
                this.geocoder.geocode( { 'address': search}, function(results, status) {
                    if (status == google.maps.GeocoderStatus.OK) 
                        //검색 된 주소 목록.
                        BloggerMap.setAddressList(BloggerMap.searchPost(search),results);
                    else
                        BloggerMap.setAddressList(BloggerMap.searchPost(search),null);
                });
            },
            setAddressList : function(posts, address){
                BloggerMap.address.innerHTML = "";
                if(posts.length > 0){
                    var blogh = document.createElement('b');
                    var blogul = document.createElement('ul');
                    
                    blogh.innerHTML = 'Blog Posts';
                    blogul.appendChild(blogh);
                    
                    for(var i=0; i<posts.length; i++)
                        blogul.appendChild(this.addAddress(posts[i].title,new google.maps.LatLng(posts[i].ua,posts[i].va)));
                
                    this.address.appendChild(blogul);
                }
                if(address != null){
                    var addressh = document.createElement('b');
                    var addressul = document.createElement('ul');
                    
                    addressh.innerHTML = 'Address';
                    addressul.appendChild(addressh);

                    for(var i=0; i<address.length; i++)
                        addressul.appendChild(this.addAddress(address[i].formatted_address,address[i].geometry.location));
                    
                    this.address.appendChild(addressul);
                }
            },
            addAddress : function(address, location){
                var li = document.createElement('li');
                var a = document.createElement('a');
                
                a.href = "#";
                a.innerHTML = address;
                this.clickAddress(a, location);
                
                li.appendChild(a);
                return li;
            },               
            //주소 클릭 이벤트.
            clickAddress : function(a, addr){
                a.onmousedown = function(){
                    //지도 이동.
                    BloggerMap.map.setCenter(addr);
                }
            }
        }
        function BloggerMapinit(feeds){
            BloggerMap.initialize(feeds);
        }
    
</script>
    
<br />
<div>
<div id="BloggerMap_map" style="float: left; height: 400px; width: 400px;">
</div>
<div>
<div>
<input id="BloggerMap_input" onkeydown="javascript:if(event.keyCode == 13) BloggerMap.codeAddress();" type="textbox" value="" />
                <input onclick="javascript:BloggerMap.codeAddress()" type="button" value="Enter" />
                <input onclick="javascript:BloggerMap.setAddressList(BloggerMap.blog.posts,null)" type="button" value="Post List" />
            </div>
<div id="BloggerMap_addr" style="height : 350px; padding-left: 1px;overflow-x:hidden; overflow-y: auto;">
</div>
</div>
<script src="http://creatorhong.blogspot.com/feeds/posts/summary/-/maprss?max-results=300&amp;alt=json-in-script&amp;callback=BloggerMapinit">
</script>
</div>
html, javascript를 모르시는 분들은 복잡하다고 생각하실수도 있지만....
그런 분들도 가장 아래쪽에

<script src="http://creatorhong.blogspot.com/feeds/posts/summary/-/maprss?max-results=300&amp;alt=json-in-script&amp;callback=BloggerMapinit">
</script>

부분만 봐주시면 됩니다.
색이 다른 3부분이 보이시나요? 각각 아래와 같습니다.

블로그 주소 : creatorhong.blogspot.com
지도에 표시할 포스트 Label : maprss
지도에 표시할 최대 마커 수 : 300

블로그 주소를 개인 블로그 주소로 바꿔 주시고, Label은 위에 설명드린데로 특정 라벨을 설정해 주시구요. 최대 마커수는 최근 포스트부터 원하시는 만큼 표시가 됩니다.

저는 전부 보여주기위해 아직 몇년을 가도 채우지 못할 것 같은 숫자인 300을 써 줬습니다.
blogspot이 rss를 최대 얼마나 보여주는지는 확인해 보지 않아 최대값이 얼마일지는 확인을 못했네요.

아.. 그리고, 검색을 할때도 이 최대 마커수 이내의 포스트들만 검색이 가능하니 이를 염두에 두시고 설정을 해 주시면 되겠습니다.

그럼. 위에 코드를 수정 하신 후,
저처럼 블로그에 페이지를 만드셔서 위에 코드를 추가하시면 완성입니다.

2017년 5월 16일

이전에는 구글맵을 쓰는데 API키를 발급 안받아도 썼던거 같은데 오늘 확인하니 API키가 없을 경우 에러가 나네요. (참고 : 구글맵 API 가이드)

구글콘솔에서 API키를 발급 받으신 후 위 소스 상단 구글맵 Javascript 라이브러리를 로드 하는 부분에 API키를 입력해 주시면 됩니다.

<script src="http://maps.google.com/maps/api/js?sensor=true&key=YOUR_API_KEY" type="text/javascript">

댓글 13개:

  1. zzzzzzzzzz=ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

    답글삭제
  2. G1님, 저는 처음 구글 블로그를 운영하는 학생입니다. 정말 잘하시네요.ㅠ
    과제때문에 다양한 코드들을 찾고 있는데 도움이 많이 되고있어요~!

    답글삭제
    답글
    1. 도움이 되셨다니 다행이네요.
      잘하다니요... 과찬의...
      저도 공부하기 시작한지 얼마 안되는데다 요즘은 또 손 놓고 있다시피 하네요. ㅎㅎ 금방 익히실 수 있으실거에요. 이 정도는 간단한 응용? 정도? 일 겁니다. ㅋ

      삭제
  3. 좋은글 잘 봤습니다. 구글 블로그는 처음 써보는데, 덧글을 삭제하면 그냥 사라지는게 아니라, 삭제했습니다. 라고 로그가 남는 시스템이군요. -_- ;;;

    질문 몇자 드릴려고 했는데, 해결을 봤기 때문에 지웠었습니다. 그렇다고 달았다 지웠다 먹고 튀는건(?) 예의가 아닌것 같아, 다시금 감사의 인사를 남기고자 합니다.

    소란을 피워서 죄송합니다. -_-;;

    즐거운 하루 되세요~

    답글삭제
    답글
    1. 아. 이렇게 댓글 남겨주셔서 감사합니다.
      아니었으면 혼자 궁금해 할뻔했네요.
      잘 해결 하셨다니 다행이네요. ^^

      삭제
    2. 위에 댓글은 완전히 삭제 하겠습니다.

      삭제
  4. 구글 지도를 블로그에 올리는 걸 공부하는 중인데 한가지 질문해도될까요?ㅠㅠ

    구글 지도가 ie에서 보이지 않는데 어떤 문제일까요 ㅠㅠ
    크롬에서는 보이긴 하는데 마커가 안보이구 ㅠㅠ 도움부탁드립니다.

    답글삭제
    답글
    1. 검색해보니 이런게 있네요.
      http://support.google.com/maps/bin/answer.py?hl=ko&answer=21849

      삭제
    2. 빠른 답변 너무 감사합니다. 우선 directx 설치하면서 여러방면으로 해결방법
      으로 대처하고 있어요~~
      제가 지금 데이터를 파싱해서 구글지도에 마커 뿌려주는 걸 구현하려고 해요~ㅎ
      구글 블로거에 지도를 커스텀 해서 올리고 나서 핸드폰으로 보니
      말풍선도 깨지고 마커도 찌그러지는 현상이 나타나네요 ㅠㅠ
      이 자료로 많은 도움 받고 있습니다 감사합니다~

      삭제
    3. 저도 배우면서 쓰는 거라 큰 도움은 못 드리겠지만 서로 배워가면서 하면 많은 도움이 될 것 같네요.
      도움이 되었다니 다행입니다. ㅋ

      삭제
  5. 좋은 지식 배워 갑니다..
    한가지 궁금한건 위와 똑 같은 형태인데 단지 마커가 디비에 저장된 주소목록을 가져오는 형태로 불러오는 방법이 어렵나요?? 시간되시면 체크좀 해 주시면 무지 고맙겠습니다...ㅡㅡ;

    답글삭제
    답글
    1. RSS와 DB 어디서 가져오냐의 차이일 뿐이겠죠.
      어느쪽이 더 익숙하냐에 따라...
      하지만 완전 오픈된 RSS와는 달리 DB에서 가져올려면...
      JSP,ASP,PHP 등을 통해야 할 겁니다.
      이렇게 블로그에 올리거나 하기는 힘들겠죠. ㅋ

      삭제