将自定义背景图片添加到Google地图中的可拖动多边形? [英] Add custom background image to draggable polygons in google map?

查看:80
本文介绍了将自定义背景图片添加到Google地图中的可拖动多边形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想向Google Map中的可拖动多边形添加自定义背景图像.我已经使用Polygon类制作了可以旋转的可拖动多边形.我想向其中添加背景图片.我读过其他文章,他们提到自定义叠加层",但这是地图上的固定图像,不支持拖动/旋转.我应该怎么做呢?

I want to add custom background image to my draggable polygons in google Map. I've already used the Polygon class to make a draggable polygon that can also rotate. I want to add background image to it. I've read other posts and they mentioned "custom overlay" but that is a fixed image on the map which doesn't support dragging/rotation. How should I go about doing this?

更新: 我使用图像创建了一个自定义图层,并将其添加到地图中,该坐标与多边形相同.每当多边形的边界发生变化时,我还将更新自定义图层,使它们始终重叠.但是,如gif所示, https://imgur.com/3oaktIY ,多边形和图像都是不同步,会有延迟.

Update: I created a custom layer with my image and added it to the map with the same coordinates as the polygon. Whenever the bounds of my polygon change, I will also update my custom layer so they always overlap. However, as shown in the gif, https://imgur.com/3oaktIY, the polygon and the image are not in sync and there's a delay.

还有其他方法可以做到吗?

Is there any other way to do it?

推荐答案

没有在线找到解决方案,所以我通过以下演示示例自己弄清楚了:

Did not find solutions online so I figured it out myself with this working demo: draggable polygon with image. I made it with a combination of custom overlay and normal polygon library. You can click on the polygon to rotate and drag it around.

plz see jsfiddle

代码段:

// This example adds hide() and show() methods to a custom overlay's prototype.
// These methods toggle the visibility of the container <div>.
// Additionally, we add a toggleDOM() method, which attaches or detaches the
// overlay to or from the map.

var overlay;

USGSOverlay.prototype = new google.maps.OverlayView();



function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 20,
    center: {
      lat: 33.678,
      lng: -116.243
    },
    mapTypeId: google.maps.MapTypeId.TERRAIN
  });

  var rectangle = new google.maps.Rectangle({
    strokeColor: 'red',
    strokeOpacity: 0,
    strokeWeight: 2,
    fillColor: '#FF0000',
    fillOpacity: 0,
    map: map,
    bounds: calcBounds(map.getCenter(), new google.maps.Size(2.7, 20))
  });

  var rectPoly = createPolygonFromRectangle(rectangle); //create a polygom from a rectangle



  rectPoly.addListener('click', function(e) {
    rotatePolygon(rectPoly, 10);
    rectPoly.rotation += 10;
    console.log(rectPoly.rotation)
    overlay.div_.style.transform = 'rotate(' + rectPoly.rotation + 'deg)';
  });

  rectPoly.addListener('drag', function() {
    console.log('Drag end!');

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

    // The Bermuda Triangle
    let polygonCoords = rectPoly.getPath().getArray();

    for (i = 0; i < polygonCoords.length; i++) {
      bounds.extend(polygonCoords[i]);
    }

    // The Center of the Bermuda Triangle - (25.3939245, -72.473816)
    center = bounds.getCenter();

    overlay.bounds_ = calcBounds(center, new google.maps.Size(2.7, 20))
    overlay.draw();

  });

  function calcBounds(center, size) {
    var n = google.maps.geometry.spherical.computeOffset(center, size.height / 2, 0).lat(),
      s = google.maps.geometry.spherical.computeOffset(center, size.height / 2, 180).lat(),
      e = google.maps.geometry.spherical.computeOffset(center, size.width / 2, 90).lng(),
      w = google.maps.geometry.spherical.computeOffset(center, size.width / 2, 270).lng();
    return new google.maps.LatLngBounds(new google.maps.LatLng(s, w),
      new google.maps.LatLng(n, e))
  }


  var srcImage = 'https://developers.google.com/maps/documentation/' +
    'javascript/examples/full/images/talkeetna.png';



  overlay = new USGSOverlay(rectangle.bounds, srcImage, map, rectPoly);


  // The custom USGSOverlay object contains the USGS image,
  // the bounds of the image, and a reference to the map.
}

/** @constructor */
function USGSOverlay(bounds, image, map, rectPoly) {

  // Now initialize all properties.
  this.bounds_ = bounds;
  this.image_ = image;
  this.map_ = map;
  this.rectPoly_ = rectPoly

  // Define a property to hold the image's div. We'll
  // actually create this div upon receipt of the onAdd()
  // method so we'll leave it null for now.
  this.div_ = null;

  // Explicitly call setMap on this overlay
  this.setMap(map);
}

/**
 * onAdd is called when the map's panes are ready and the overlay has been
 * added to the map.
 */
USGSOverlay.prototype.onAdd = function() {

  var div = document.createElement('div');
  div.style.border = 'none';
  div.style.borderWidth = '0px';
  div.style.position = 'absolute';
  rectPoly = this.rectPoly_;

  // Create the img element and attach it to the div.
  var img = document.createElement('img');
  img.src = this.image_;
  img.style.width = '100%';
  img.style.height = '100%';
  div.appendChild(img);

  this.div_ = div;

  // Add the element to the "overlayImage" pane.
  var panes = this.getPanes();
  panes.overlayImage.appendChild(this.div_);
};

USGSOverlay.prototype.draw = function() {

  // We use the south-west and north-east
  // coordinates of the overlay to peg it to the correct position and size.
  // To do this, we need to retrieve the projection from the overlay.
  var overlayProjection = this.getProjection();

  // Retrieve the south-west and north-east coordinates of this overlay
  // in LatLngs and convert them to pixel coordinates.
  // We'll use these coordinates to resize the div.
  var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
  var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());

  // Resize the image's div to fit the indicated dimensions.
  var div = this.div_;
  div.style.left = sw.x + 'px';
  div.style.top = ne.y + 'px';
  div.style.width = (ne.x - sw.x) + 'px';
  div.style.height = (sw.y - ne.y) + 'px';
};

USGSOverlay.prototype.onRemove = function() {
  this.div_.parentNode.removeChild(this.div_);
};

// Set the visibility to 'hidden' or 'visible'.


function createPolygonFromRectangle(rectangle) {
  var map = rectangle.getMap();

  var coords = [{
      lat: rectangle.getBounds().getNorthEast().lat(),
      lng: rectangle.getBounds().getNorthEast().lng()
    },
    {
      lat: rectangle.getBounds().getNorthEast().lat(),
      lng: rectangle.getBounds().getSouthWest().lng()
    },
    {
      lat: rectangle.getBounds().getSouthWest().lat(),
      lng: rectangle.getBounds().getSouthWest().lng()
    },
    {
      lat: rectangle.getBounds().getSouthWest().lat(),
      lng: rectangle.getBounds().getNorthEast().lng()
    }
  ];

  // Construct the polygon.
  var rectPoly = new google.maps.Polygon({
    path: coords,
    draggable: true,
    rotation: 0

  });
  var properties = ["strokeColor", "strokeOpacity", "strokeWeight", "fillOpacity", "fillColor"];
  //inherit rectangle properties 
  var options = {};
  properties.forEach(function(property) {
    if (rectangle.hasOwnProperty(property)) {
      options[property] = rectangle[property];
    }
  });
  rectPoly.setOptions(options);

  rectangle.setMap(null);
  rectPoly.setMap(map);
  return rectPoly;
}


function rotatePolygon(polygon, angle) {
  var map = polygon.getMap();
  var prj = map.getProjection();

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

  // The Bermuda Triangle
  var polygonCoords = polygon.getPath().getArray();

  for (i = 0; i < polygonCoords.length; i++) {
    bounds.extend(polygonCoords[i]);
  }

  // The Center of the Bermuda Triangle - (25.3939245, -72.473816)
  console.log(bounds.getCenter());
  var origin = prj.fromLatLngToPoint(bounds.getCenter()); //rotate around first point

  //var origin2 = prj.fromLatLngToPoint(polygon.getPath().getAt(1)); //rotate around first point


  var coords = polygon.getPath().getArray().map(function(latLng) {
    var point = prj.fromLatLngToPoint(latLng);
    var rotatedLatLng = prj.fromPointToLatLng(rotatePoint(point, origin, angle));
    return {
      lat: rotatedLatLng.lat(),
      lng: rotatedLatLng.lng()
    };
  });
  polygon.setPath(coords);
}

function rotatePoint(point, origin, angle) {
  var angleRad = angle * Math.PI / 180.0;
  return {
    x: Math.cos(angleRad) * (point.x - origin.x) - Math.sin(angleRad) * (point.y - origin.y) + origin.x,
    y: Math.sin(angleRad) * (point.x - origin.x) + Math.cos(angleRad) * (point.y - origin.y) + origin.y
  };
}

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

/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */

#map {
  height: 100%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: 'Roboto', 'sans-serif';
  line-height: 30px;
  padding-left: 10px;
}

<!-- Add an input button to initiate the toggle method on the overlay. -->

<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=geometry"></script>

这篇关于将自定义背景图片添加到Google地图中的可拖动多边形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆