Html5로 만든 도형을 카카오 api 지도위에 올릴 방법이 있을가요?

https://developer.mozilla.org/ko/docs/Web/HTML/Canvas/Tutorial/Drawing_shapes

링크에 나와있는 사각형 그리기 입니다.

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    ctx.fillRect(25, 25, 100, 100);
    ctx.clearRect(45, 45, 60, 60);
    ctx.strokeRect(50, 50, 50, 50);
  }
}

Javascript 를 이용해서 그린 도형을 지도위에 삽입하거나 맵핑할수 있는 방법이 있을까요?

https://apis.map.kakao.com/web/documentation/#AbstractOverlay_Methods
이런식으로 도형같은 것도 할 수 있나요?

관 같은 걸 지도위에 그리려고 하는데 그냥 사각형 방법으로는 어려울거 같아서 방법을 찾는 중입니다.

특정 좌표에 표시하려면
CustomOverlay를 사용해서 지도 위에 올려주세요.

var canvas = document.createElement('canvas');    
var ctx = canvas.getContext('2d');
ctx.fillRect(25, 25, 100, 100);
ctx.clearRect(45, 45, 60, 60);
ctx.strokeRect(50, 50, 50, 50);

// 커스텀 오버레이를 생성합니다
var customOverlay = new kakao.maps.CustomOverlay({
    position: position,
    content: canvas   
});

또는, 특정 좌표 위치가 아닌 지도 위에 고정으로 표시할 경우
Canvas Element의 position 스타일 속성을 absolute로 적용해서 위치를 고정시켜주세요.

그려서 커스텀 오버레이로 출력 되는 것은 확인 했습니다.
https://apis.map.kakao.com/web/sample/drawShape/
이 예제처럼 그렸을때 맵에 고정되게 할수는 없나요?
맵위에 그려진 것 처럼요.

줌을 하거나 그럴때 지도에 고정 시키고 싶습니다.

GroundOverlay로 지도에 canvas를 올려주세요.
아래 예제 코드 참고해주세요.

답변 감사합니다.
GroundOverlay를 사용해서 Canvas를 Bound에 표현하는 것은 성공했습니다.
근데 canvas에서 rotate를 사용하니까 잘리는 것처럼 직사각형이 표현되더라고요.
똑바로 나올 방법은 없을까요? 확인 부탁 드립니다.

이게 그리고 싶은 것으로 직사각형이 똑바로 회전한 결과입니다.
https://jsfiddle.net/JaeseoLee/zdpcn0yj/1/
이건 제가 작성한 코드 입니다.

  // 오버레이로 올릴 이미지의 bounds를 받아 AbstractOverlay를 생성합니다.
  function GroundOverlay(bounds) {
    this.bounds = bounds;
    this.node = document.createElement("canvas");
    this.node.style.backgroundColor = "yellow";
    this.node.style.opacity = "0.5";
    this.node.style.position = "absolute";
    this.ctx = this.node.getContext("2d");
    this.width = 175;
    this.height = 65;
    this.startX = 65;
    this.startY = 65;

    this.ctx.beginPath();
    this.ctx.translate(
      this.startX + this.width / 2,
      this.startY + this.height / 2
    );
    this.ctx.rotate((30 * Math.PI) / -180);
    this.ctx.fillRect(-175 / 25, -20 / 2, 175, 20);
    this.ctx.fillStyle = "black";
  }

  GroundOverlay.prototype = new kakao.maps.AbstractOverlay();

  GroundOverlay.prototype.onAdd = function() {
    var panel = this.getPanels().overlayLayer;
    panel.appendChild(this.node);
  };

  // 줌인 아웃 시 이미지를 원하는 bounds값에 맞게 표출하기 위해 img style을 정의 및 선언합니다.
  GroundOverlay.prototype.draw = function() {
    var projection = this.getProjection();
    var ne = projection.pointFromCoords(this.bounds.getNorthEast());
    var sw = projection.pointFromCoords(this.bounds.getSouthWest());

    var width = ne.x - sw.x;
    var height = sw.y - ne.y;

    this.node.style.top = ne.y + "px";
    this.node.style.left = sw.x + "px";
    this.node.style.width = width + "px";
    this.node.style.height = height + "px";
  };

  GroundOverlay.prototype.onRemove = function() {
    this.node.parentNode.removeChild(this.node);
  };

  var sw = new kakao.maps.LatLng(37.54989262685873, 127.04985765049643),
    ne = new kakao.maps.LatLng(37.55036983933805, 127.05060203264918);

  var bounds = new kakao.maps.LatLngBounds(sw, ne);

  var overlay = new GroundOverlay(bounds);
  overlay.setMap(map);

이건 결과 사진 입니다. 뭔가 잘린듯히 회전을 했습니다.
rect
post image

jsfiddle 예제에서 컨버스의 크기는 w: 300, h: 200으로 적용되어 있습니다.
로직에 canvas 크기를 적용해주시고, 직사각형의 시작점을 조정해주세요.

svg로도 groundoverlay를 적용해보려고 하는데요.
svg에서는 적용이 잘 안되는 것 같습니다.
지도에 고정시킬 방법이 있을까요?

function GroundOverlay(bounds) {
          this.bounds = bounds;
          this.node = document.createElement("div");
          this.node.style.position = "absolute";
          this.svg1 = document.createElementNS("http://www.w3.org/2000/svg", "svg");
          this.svg1.setAttribute("position", "absolute");
          this.svg1.style.position = "absolute";

          // create a circle
          this.cir1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
          this.cir1.style.position = "absolute";
          this.cir1.setAttribute("cx", "80");
          this.cir1.setAttribute("cy", "80");
          this.cir1.setAttribute("r", "30");
          this.cir1.setAttribute("fill", "red");
          this.cir1.setAttribute("position", "absolute");


          // attach it to the container
          this.svg1.appendChild(this.cir1);

          // attach container to document
          this.node.appendChild(this.svg1);
        }

        //프로토타입 체인을 연결한다
        GroundOverlay.prototype = new kakao.maps.AbstractOverlay();

        // AbstractOverlay의 getPanels() 메소드로 MapPanel 객체를 가져오고
        // 거기에서 오버레이 레이어를 얻어 생성자에서 만든 엘리먼트를 자식 노드로 넣어준다.
        GroundOverlay.prototype.onAdd = function() {
          var panel = this.getPanels().overlayLayer;
          panel.appendChild(this.node);
        };

        // 지도의 속성 값들이 변화할 때마다 호출된다. (zoom, center, mapType)
        // 엘리먼트의 위치를 재조정 해 주어야 한다.
        GroundOverlay.prototype.draw = function() {
          var projection = this.getProjection();
          var ne = projection.pointFromCoords(this.bounds.getNorthEast());
          var sw = projection.pointFromCoords(this.bounds.getSouthWest());

          var width = ne.x - sw.x;
          var height = sw.y - ne.y;

          this.node.style.top = ne.y + "px";
          this.node.style.left = sw.x + "px";
          this.node.style.width = width + "px";
          this.node.style.height = height + "px";
        };

        GroundOverlay.prototype.onRemove = function() {
          this.node.parentNode.removeChild(this.node);
        };

        var sw = new kakao.maps.LatLng(37.549845375759396, 127.04973596677972),
          ne = new kakao.maps.LatLng(37.55043738386111, 127.05067280692033);

        var bounds = new kakao.maps.LatLngBounds(sw, ne);

        var overlay = new GroundOverlay(bounds);
        overlay.setMap(map);

draw 함수에서 circle의 cx, cy 값을 재조정해주어야 합니다.
아래 코드는 예시로 참고해주세요.

function GroundOverlay(bounds) {
    this.bounds = bounds;
    this.svg1 = document.createElementNS("http://www.w3.org/2000/svg", "svg");
    this.svg1.style.position = "absolute";

    // create a circle
    this.cir1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    this.cir1.setAttribute("r", "10");

    // attach it to the container
    this.svg1.appendChild(this.cir1);
}

//프로토타입 체인을 연결한다
/* ... */

// 엘리먼트의 위치를 재조정 해 주어야 한다.
GroundOverlay.prototype.draw = function() {
    var projection = this.getProjection();
    var ne = projection.pointFromCoords(this.bounds.getNorthEast());
    var sw = projection.pointFromCoords(this.bounds.getSouthWest());
    var width = ne.x - sw.x;
    var height = sw.y - ne.y;

    this.svg1.style.top = ne.y+'px';
    this.svg1.style.left = sw.x+'px';
    this.svg1.style.width = width+'px';
    this.svg1.style.height = height+'px';

    this.cir1.setAttribute("cx", width/2);
    this.cir1.setAttribute("cy", height/2);
};

var sw = new kakao.maps.LatLng(37.549845375759396, 127.04973596677972),
    ne = new kakao.maps.LatLng(37.55043738386111, 127.05067280692033);
var bounds = new kakao.maps.LatLngBounds(sw, ne)

var overlay = new GroundOverlay(bounds);
overlay.setMap(map);

// bounds 확인을 위해 rectangle을 지도에 표시합니다.
var rectangle = new kakao.maps.Rectangle({
    map: map,
    bounds : bounds,
    strokeWeight: 4,
    strokeColor: '#FF00FF',
    strokeOpacity: 0.8,
    strokeStyle: 'dashed',
    fillColor: '#00EEEE',
    fillOpacity: 0.5
});

답변 항상 감사합니다.
아래와 같이 좌표 변경하는 게 그려질때
사용자가 Zoom out/in을 하는지 알수 있는 방법 이 있을가요?

GroundOverlay.prototype.draw = function() {
           //줌인일때
           if(zoomBehavior==zoomout) {
                   // Do scale up
           } else {
                 // Do scale down
           }
};

GroundOverlay에서 this.zoom = map.getLevel(); 선언하고
draw 함수에서 console.log(this.zoom, map.getLevel()); 을 출력해보면
지도 생성 시 설정한 지도 레벨, 현재 지도의 레벨을 확인할 수 있습니다.
이를 활용해서 구현해주세요.

답변 감사합니다.

groundOverlay에 이벤트를 추가하고 싶은데

var overlay = new GroundOverlay(bounds);

      kakao.maps.event.addListener(overlay, "mouseover", function() {
          // 마커에 마우스오버 이벤트가 발생하면 인포윈도우를 마커위에 표시합니다
          infowindow.open(map, marker);
        });

이런식으로 하면 되나요?

아니면 따로 자바스크립트로 구현 해줘야 하나요?

생성한 HTMLElement에 직접 이벤트를 걸어주세요.