javascript - multiple - html google map popup




Google지도 V3에 번호가 매겨진지도 아이콘을 만들려면 어떻게해야합니까? (10)

이건 어때? (2015 년)

1) 맞춤 마커 이미지를 가져옵니다.

var imageObj = new Image();
    imageObj.src = "/markers/blank_pin.png"; 

2) RAM canvasRAM 이미지를 그 위에 그립니다.

imageObj.onload = function(){
    var canvas = document.createElement('canvas');
    var context = canvas.getContext("2d");
    context.drawImage(imageObj, 0, 0);
}

3) 위에 무엇이든 적어 라.

context.font = "40px Arial";
context.fillText("54", 17, 55);

4) 캔버스에서 원시 데이터를 가져 와서 URL 대신 Google API에 제공합니다.

var image = {
    url: canvas.toDataURL(),
 };
 new google.maps.Marker({
    position: position,
    map: map,
    icon: image
 });

전체 코드 :

function addComplexMarker(map, position, label, callback){
    var canvas = document.createElement('canvas');
    var context = canvas.getContext("2d");
    var imageObj = new Image();
    imageObj.src = "/markers/blank_pin.png";
    imageObj.onload = function(){
        context.drawImage(imageObj, 0, 0);

        //Adjustable parameters
        context.font = "40px Arial";
        context.fillText(label, 17, 55);
        //End

        var image = {
            url: canvas.toDataURL(),
            size: new google.maps.Size(80, 104),
            origin: new google.maps.Point(0,0),
            anchor: new google.maps.Point(40, 104)
        };
        // the clickable region of the icon.
        var shape = {
            coords: [1, 1, 1, 104, 80, 104, 80 , 1],
            type: 'poly'
        };
        var marker = new google.maps.Marker({
            position: position,
            map: map,
            labelAnchor: new google.maps.Point(3, 30),
            icon: image,
            shape: shape,
            zIndex: 9999
        });
        callback && callback(marker)
    };
});

나는 그것에 여러 마커가있는지도에서 일하고 있습니다.

이 마커는 맞춤 아이콘을 사용하지만 맨 위에 숫자를 추가하고 싶습니다. 이전 버전의 API를 사용하여 이것이 어떻게 이루어 졌는지 보았습니다. V3에서 어떻게 할 수 있습니까?

* 참고 - 'title'속성은 마커를 마우 스 오버 할 때 툴팁을 생성하지만 사용자가 위에 올려 놓지 않아도 맞춤 이미지 상단에 겹칠 항목을 원합니다.

마커 클래스에 대한 설명서는 다음과 같습니다. http://code.google.com/apis/maps/documentation/v3/reference.html#MarkerOptions


@ ZuzEL과 비슷한 솔루션을 사용하여이 작업을 수행했습니다.

기본 솔루션 ( http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=7|FF0000|000000 )을 사용하는 대신 서버 측 코드없이 JavaScript를 사용하여 원하는대로이 이미지를 만들 수 있습니다 .

Google google.maps.Marker는 icon 속성으로 Base64를 허용합니다. 이를 통해 SVG에서 유효한 Base64를 만들 수 있습니다.

이 Plunker에서이 이미지와 같은 코드를 생성하는 코드를 볼 수 있습니다 : http://plnkr.co/edit/jep5mVN3DsVRgtlz1GGQ?p=preview

var markers = [
  [1002, -14.2350040, -51.9252800],
  [2000, -34.028249, 151.157507],
  [123, 39.0119020, -98.4842460],
  [50, 48.8566140, 2.3522220],
  [22, 38.7755940, -9.1353670],
  [12, 12.0733335, 52.8234367],
];

function initializeMaps() {
  var myLatLng = {
    lat: -25.363,
    lng: 131.044
  };

  var map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 4,
    center: myLatLng
  });

  var bounds = new google.maps.LatLngBounds();

  markers.forEach(function(point) {
    generateIcon(point[0], function(src) {
      var pos = new google.maps.LatLng(point[1], point[2]);

      bounds.extend(pos);

      new google.maps.Marker({
        position: pos,
        map: map,
        icon: src
      });
    });
  });

  map.fitBounds(bounds);
}

var generateIconCache = {};

function generateIcon(number, callback) {
  if (generateIconCache[number] !== undefined) {
    callback(generateIconCache[number]);
  }

  var fontSize = 16,
    imageWidth = imageHeight = 35;

  if (number >= 1000) {
    fontSize = 10;
    imageWidth = imageHeight = 55;
  } else if (number < 1000 && number > 100) {
    fontSize = 14;
    imageWidth = imageHeight = 45;
  }

  var svg = d3.select(document.createElement('div')).append('svg')
    .attr('viewBox', '0 0 54.4 54.4')
    .append('g')

  var circles = svg.append('circle')
    .attr('cx', '27.2')
    .attr('cy', '27.2')
    .attr('r', '21.2')
    .style('fill', '#2063C6');

  var path = svg.append('path')
    .attr('d', 'M27.2,0C12.2,0,0,12.2,0,27.2s12.2,27.2,27.2,27.2s27.2-12.2,27.2-27.2S42.2,0,27.2,0z M6,27.2 C6,15.5,15.5,6,27.2,6s21.2,9.5,21.2,21.2c0,11.7-9.5,21.2-21.2,21.2S6,38.9,6,27.2z')
    .attr('fill', '#FFFFFF');

  var text = svg.append('text')
    .attr('dx', 27)
    .attr('dy', 32)
    .attr('text-anchor', 'middle')
    .attr('style', 'font-size:' + fontSize + 'px; fill: #FFFFFF; font-family: Arial, Verdana; font-weight: bold')
    .text(number);

  var svgNode = svg.node().parentNode.cloneNode(true),
    image = new Image();

  d3.select(svgNode).select('clippath').remove();

  var xmlSource = (new XMLSerializer()).serializeToString(svgNode);

  image.onload = (function(imageWidth, imageHeight) {
    var canvas = document.createElement('canvas'),
      context = canvas.getContext('2d'),
      dataURL;

    d3.select(canvas)
      .attr('width', imageWidth)
      .attr('height', imageHeight);

    context.drawImage(image, 0, 0, imageWidth, imageHeight);

    dataURL = canvas.toDataURL();
    generateIconCache[number] = dataURL;

    callback(dataURL);
  }).bind(this, imageWidth, imageHeight);

  image.src = 'data:image/svg+xml;base64,' + btoa(encodeURIComponent(xmlSource).replace(/%([0-9A-F]{2})/g, function(match, p1) {
    return String.fromCharCode('0x' + p1);
  }));
}

initializeMaps();
#map_canvas {
  width: 100%;
  height: 300px;
}
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    
  </head>

  <body>
    <div id="map_canvas"></div>
  </body>
  
  <script src="script.js"></script>

</html>

이 데모에서는 D3.js를 사용하여 SVG를 만든 다음 SVG를 Canvas로 변환하여 원하는대로 이미지의 크기를 조정할 수 있고 이후 Base64를 캔버스에서 'toDataURL 메서드'로 가져올 수 있습니다.

이 모든 데모는 동료 @ thiago-mata 코드를 기반으로합니다. 그를위한 명예.



나는 최선의 방법을 발견했다. Snap.svg 를 사용하여 svg를 만든 다음 아이콘으로 포함 할 그래픽 데이터를 만드는 toDataURL () 함수를 사용하십시오. SlidingMarker 클래스를 사용하여 마커의 멋진 움직임을 제공하는 마커에 주목하십시오. Snap.svg를 사용하면 모든 종류의 그래픽을 만들 수 있으며지도가 환상적으로 보입니다.

var s = Snap(100, 100);
s.text(50, 50, store.name);
// Use more graphics here.
var marker = new SlidingMarker({
  position: {lat: store.lat, lng: store.lng},
  map: $scope.map,
  label: store.name, // you do not need this
  title: store.name, // nor this
  duration: 2000,
  icon: s.toDataURL()
});

답변에 대한 평판은 충분하지 않지만 Google Chart API는 더 이상 사용되지 않습니다.

API 홈페이지에서

Google Chart Tools의 Infographics 부분은 2012 년 4 월 20 일부터 공식적으로 지원 중단 될 예정입니다.


불행히도 그렇게 쉬운 일은 아닙니다. OverlayView 클래스 ( )를 기반으로 사용자 정의 마커를 만들고 카운터를 포함하여 자신의 HTML을 넣을 수 있습니다. 이렇게하면 매우 기본적인 마커가 생기고 그림자를 쉽게 드래그하거나 그림자를 추가 할 수 없지만 매우 맞춤 설정할 수 있습니다.

또는 기본 표시 자에 레이블을 추가 할 수 있습니다 . 이것은 덜 사용자 정의 할 수 있지만 작동해야합니다. 그것은 또한 표준 마커가하는 모든 유용한 것들을 유지합니다.

오버레이에 대한 자세한 내용은 Google의 기사 MVC 객체와 재미를 참조하십시오.

편집 : 자바 스크립트 클래스를 만들고 싶지 않으면 Google의 Chart API를 사용할 수 있습니다. 예 :

번호가 매겨진 마커 :

http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=7|FF0000|000000

텍스트 마커 :

http://chart.apis.google.com/chart?chst=d_map_spin&chld=1|0|FF0000|12|_|foo

이것은 빠르고 쉬운 경로이지만 맞춤 설정이 쉽지 않으며 각 마커에 대해 클라이언트가 새 이미지를 다운로드해야합니다.


이것은 이제 매핑 문서에 추가되었으며 타사 코드가 필요하지 않습니다.

다음 두 샘플을 결합 할 수 있습니다.

https://developers.google.com/maps/documentation/javascript/examples/marker-labels

https://developers.google.com/maps/documentation/javascript/examples/icon-simple

이런 코드를 얻으려면 :

var labelIndex = 0;
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';

function initialize() {
  var bangalore = { lat: 12.97, lng: 77.59 };
  var map = new google.maps.Map(document.getElementById('map-canvas'), {
    zoom: 12,
    center: bangalore
  });

  // This event listener calls addMarker() when the map is clicked.
  google.maps.event.addListener(map, 'click', function(event) {
    addMarker(event.latLng, map);
  });

  // Add a marker at the center of the map.
  addMarker(bangalore, map);
}

// Adds a marker to the map.
function addMarker(location, map) {
  // Add the marker at the clicked location, and add the next-available label
  // from the array of alphabetical characters.
  var marker = new google.maps.Marker({
    position: location,
    label: labels[labelIndex],
    map: map,
    icon: 'image.png'
  });
}

google.maps.event.addDomListener(window, 'load', initialize);

마커가 35 개 이상인 경우 레이블에 첫 번째 문자 만 표시되므로이 방법은 작동하지 않습니다 (AZ를 사용하고 0-9가 35를 사용함). 이 Google지도 문제 에 투표하여이 제한 사항을 해제 해달라고 요청하십시오.


이것이 내가 V3에서하는 일 :

먼저 Google지도 API를로드하고 콜백 메소드 initialize() 내에서 MarkerWithLabel.js 를로드하여 시작 합니다.

function initialize() {

            $.getScript("/js/site/marker/MarkerWithLabel.js#{applicationBean.version}", function(){

            var mapOptions = {
                zoom: 8,
                center: new google.maps.LatLng(currentLat, currentLng),
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                streetViewControl: false,
                mapTypeControl: false
            };

            var map = new google.maps.Map(document.getElementById('mapholder'),
                    mapOptions);

            var bounds = new google.maps.LatLngBounds();

            for (var i = 0; i &lt; mapData.length; i++) {
                createMarker(i+1, map, mapData[i]); <!-- MARKERS! -->
                extendBounds(bounds, mapData[i]);
            }
            map.fitBounds(bounds);
            var maximumZoomLevel = 16;
            var minimumZoomLevel = 11;
            var ourZoom = defaultZoomLevel; // default zoom level

            var blistener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
                if (this.getZoom(map.getBounds) &gt; 16) {
                    this.setZoom(maximumZoomLevel);
                }
                google.maps.event.removeListener(blistener);
            });
            });
        }

        function loadScript() {
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&amp;libraries=places&amp;sensor=false&amp;callback=initialize";
            document.body.appendChild(script);
        }

        window.onload = loadScript;

    </script> 

그런 다음 createMarker() 마커를 만듭니다.

function createMarker(number, currentMap, currentMapData) {

   var marker = new MarkerWithLabel({
       position: new google.maps.LatLng(currentMapData[0], currentMapData[1]),
                 map: currentMap,
                 icon: '/img/sticker/empty.png',
                 shadow: '/img/sticker/bubble_shadow.png',
                 transparent: '/img/sticker/bubble_transparent.png',
                 draggable: false,
                 raiseOnDrag: false,
                 labelContent: ""+number,
                 labelAnchor: new google.maps.Point(3, 30),
                 labelClass: "mapIconLabel", // the CSS class for the label
                 labelInBackground: false
                });
            }

마커에 mapIconLabel 클래스를 추가 한 이후 CSS에 몇 가지 CSS 규칙을 추가 할 수 있습니다.

.mapIconLabel {
    font-size: 15px;
    font-weight: bold;
    color: #FFFFFF;
    font-family: 'DINNextRoundedLTProMediumRegular';
}

결과는 다음과 같습니다.


Google 차트 API 를 사용하여이 문제를 해결하는 방법을 보여주는 두 가지 센트입니다.


가장 쉬운 솔루션 - SVG 사용

작동 위치 : IE9 , IE10 , FF, Chrome, Safari

(다른 브라우저를 사용하는 경우 "코드 스 니펫 실행"을 클릭하고 의견을 말하십시오)

Google Maps API 외의 외부 종속성이 없습니다!

.svg 형식의 아이콘이 있으면 매우 쉽습니다. 이 경우 적절한 텍스트 요소를 추가 하고 콘텐츠를 JS의 필요에 맞게 변경하십시오.

.svg 코드에 다음과 같이 추가하십시오 (이 텍스트는 나중에 JS로 변경되는 "섹션"텍스트입니다).

<text id="1" fill="#20539F" font-family="NunitoSans-ExtraBold, Nunito Sans" font-size="18" font-weight="600" letter-spacing=".104" text-anchor="middle" x="50%" y="28">1</text>

예 : (부분적으로 @ EstevãoLucas에서 복사)

중요 : 올바른 <text> 태그 속성을 사용하십시오. 더 긴 숫자를 중심으로하는 text-anchor="middle" x="50%" y="28" (자세한 정보 : SVG 직사각형에 텍스트를 배치하고 가운데 정렬하는 방법 )

encodeURIComponent() 사용하십시오 encodeURIComponent() IE9 및 10과의 호환성 보장)

// Most important part (use output as Google Maps icon)
function getMarkerIcon(number) {
  // inline your SVG image with number variable
  var svg = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40" height="40" viewBox="0 0 40 40"> <defs> <rect id="path-1" width="40" height="40"/> <mask id="mask-2" width="40" height="40" x="0" y="0" fill="white"> <use xlink:href="#path-1"/> </mask> </defs> <g id="Page-1" fill="none" fill-rule="evenodd"> <g id="Phone-Portrait---320" transform="translate(-209 -51)"> <g id="Group" transform="translate(209 51)"> <use id="Rectangle" fill="#FFEB3B" stroke="#F44336" stroke-width="4" mask="url(#mask-2)" xlink:href="#path-1"/> <text id="1" fill="#20539F" font-family="NunitoSans-ExtraBold, Nunito Sans" font-size="18" font-weight="600" letter-spacing=".104" text-anchor="middle" x="50%" y="28">' + number + '</text> </g> </g> </g> </svg>';
  // use SVG without base64 see: https://css-tricks.com/probably-dont-base64-svg/
  return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
}

// Standard Maps API code
var markers = [
  [1, -14.2350040, -51.9252800],
  [2, -34.028249, 151.157507],
  [3, 39.0119020, -98.4842460],
  [5, 48.8566140, 2.3522220],
  [9, 38.7755940, -9.1353670],
  [12, 12.0733335, 52.8234367],
];

function initializeMaps() {
  var myLatLng = {
    lat: -25.363,
    lng: 131.044
  };

  var map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 4,
    center: myLatLng
  });

  var bounds = new google.maps.LatLngBounds();

  markers.forEach(function(point) {
      var pos = new google.maps.LatLng(point[1], point[2]);

      new google.maps.Marker({
        position: pos,
        map: map,
        icon: getMarkerIcon(point[0]),         
      });

      bounds.extend(pos);
  });

  map.fitBounds(bounds);
}

initializeMaps();
#map_canvas {
  width: 100%;
  height: 300px;
}
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>        
  </head>

  <body>
    <div id="map_canvas"></div>
  </body>
  
  <script src="script.js"></script>

</html>

Google지도의 인라인 SVG에 대한 추가 정보 : https://robert.katzki.de/posts/inline-svg-as-google-maps-marker







google-maps-api-3