我使用 JavaScript API V3 创建了一个 Google 地图。我正在绘制一些邮政编码多边形。根据某些条件,多边形具有不同的颜色。现在我想根据某些标准在某些多边形内绘制直线/散列标记。我们怎样才能做到呢。下面是我编写的用于绘制多边形的代码。
var path = [
{% for polycoord in zip.zip_info.zip_polygon %}
new google.maps.LatLng({{polycoord.1}}, {{polycoord.0}}),
{% endfor %}
];
var polygon_{{ forloop.counter }} = new google.maps.Polygon(
{
path:path,
clickable:true,
strokeColor: '#000000',
strokeOpacity: 0.15,
strokeWeight: 2,
fillColor: fillColor,
fillOpacity: 1,
zipcode: '{{zip.zip_info.zipcode}}'
});
polygon_{{ forloop.counter }}.setMap(map);
这是显示我的要求的图片:
您可以在图像中看到一些多边形用直线着色,一些多边形仅用颜色着色。
我一直在研究同样的问题。这是我到目前为止所拥有的:示例的jsFiddle
BW.PolyLineFill
函数创建一个自定义叠加。它需要 4 个参数,最后两个是可选的。
1. path: an array of Google LatLng objects
2. map: the map to attach theoverlay to
3. fillColor: (optional) the color of the fill, default is red.
4. strokeColor: (optional) the stroke color, default is black
我还没有测试性能,它可能仍需要更多调整,但它应该可以帮助您入门。
相关代码:
PolyLineFill.prototype = new google.maps.OverlayView();
function PolyLineFill(poly, map, fill, stroke) {
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < poly.length; i++) {
bounds.extend(poly[i]);
}
//initialize all properties.
this.bounds_ = bounds;
this.map_ = map;
this.div_ = null;
this.poly_ = poly;
this.polysvg_ = null;
this.fill_ = fill;
this.stroke_ = stroke;
// Explicitly call setMap on this overlay
this.setMap(map);
}
PolyLineFill.prototype.onAdd = function () {
// Create the DIV and set some basic attributes.
var div = document.createElement('div');
div.style.borderStyle = 'none';
div.style.borderWidth = '0px';
div.style.position = 'absolute';
//createthe svg element
var svgns = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(svgns, "svg");
svg.setAttributeNS(null, "preserveAspectRatio", "xMidYMid meet");
var def = document.createElementNS(svgns, "defs");
//create the pattern fill
var pattern = document.createElementNS(svgns, "pattern");
pattern.setAttributeNS(null, "id", "lineFill");
pattern.setAttributeNS(null, "patternUnits", "userSpaceOnUse");
pattern.setAttributeNS(null, "patternTransform", "rotate(-45)");
pattern.setAttributeNS(null, "height", "7");
pattern.setAttributeNS(null, "width", "7");
def.appendChild(pattern);
var rect = document.createElementNS(svgns, "rect");
rect.setAttributeNS(null, "id", "rectFill");
rect.setAttributeNS(null, "fill", this.fill_ || "red");
rect.setAttributeNS(null, "fill-opacity", "0.3");
rect.setAttributeNS(null, "stroke", this.stroke_ || "#000");
rect.setAttributeNS(null, "stroke-dasharray", "7,7");
rect.setAttributeNS(null, "height", "7");
rect.setAttributeNS(null, "width", "7");
pattern.appendChild(rect);
svg.appendChild(def);
//add polygon to the div
var p = document.createElementNS(svgns, "polygon");
p.setAttributeNS(null, "fill", "url(#lineFill)");
p.setAttributeNS(null, "stroke", "#000");
p.setAttributeNS(null, "stroke-width", "1");
//set a reference to this element;
this.polysvg_ = p;
svg.appendChild(p);
div.appendChild(svg);
// Set the overlay's div_ property to this DIV
this.div_ = div;
// We add an overlay to a map via one of the map's panes.
// We'll add this overlay to the overlayLayer pane.
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
}
PolyLineFill.prototype.AdjustPoints = function () {
//adjust the polygon points based on the projection.
var proj = this.getProjection();
var sw = proj.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = proj.fromLatLngToDivPixel(this.bounds_.getNorthEast());
var points = "";
for (var i = 0; i < this.poly_.length; i++) {
var point = proj.fromLatLngToDivPixel(this.poly_[i]);
if (i == 0) {
points += (point.x - sw.x) + ", " + (point.y - ne.y);
} else {
points += " " + (point.x - sw.x) + ", " + (point.y - ne.y);
}
}
return points;
}
PolyLineFill.prototype.draw = function () {
// Size and position the overlay. We use a southwest and northeast
// position of the overlay to peg it to the correct position and size.
// We need to retrieve the projection from this overlay to do this.
var overlayProjection = this.getProjection();
// Retrieve the southwest and northeast coordinates of this overlay
// in latlngs and convert them to pixels 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';
this.polysvg_.setAttributeNS(null, "points", this.AdjustPoints());
}
PolyLineFill.prototype.onRemove = function () {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
}
window.BW = {};
window.BW.PolyLineFill = PolyLineFill;
我研究了 Bryan Weaver 的解决方案,使其适用于使用绘图管理器的可编辑多边形。这是我的 jsfiddle 示例
function initialize() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 5,
center: {
lat: 24.886,
lng: -70.268
},
mapTypeId: 'terrain'
});
var drawingManager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [google.maps.drawing.OverlayType.POLYGON]
},
polygonOptions: {
fillOpacity: 0,
strokeWeight: 1,
strokeColor: '#ff0000',
clickable: true,
editable: true,
draggable: true,
}
});
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
var poly = event.overlay;
poly.bk = new BW.PolyLineFill(poly.getPath(), this.map, "red", "#000");
google.maps.event.addListener(poly, 'dragstart', function(event) {
if (poly.bk != null) {
poly.bk.setMap(null);
poly.bk = null
}
poly.isBeingDragged = true;
});
google.maps.event.addListener(poly, 'dragend', function(event) {
if (poly.bk != null) {
poly.bk.setMap(null);
poly.bk = null
}
poly.bk = new BW.PolyLineFill(poly.getPath(), poly.map, "red", "#000");
poly.isBeingDragged = false;
});
google.maps.event.addListener(poly.getPath(), 'set_at', function(event) {
if (poly.isBeingDragged) return;
console.log('set_at');
if (poly.bk != null) {
poly.bk.setMap(null);
poly.bk = null
}
poly.bk = new BW.PolyLineFill(poly.getPath(), poly.map, "red", "#000");
});
google.maps.event.addListener(poly.getPath(), 'insert_at', function(event) {
if (poly.bk != null) {
poly.bk.setMap(null);
poly.bk = null
}
poly.bk = new BW.PolyLineFill(poly.getPath().b, poly.map, "red", "#000");
});
drawingManager.setDrawingMode(null);
});
}
///Start custom poly fill code
PolyLineFill.prototype = new google.maps.OverlayView();
function PolyLineFill(poly, map, fill, stroke) {
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < poly.length; i++) {
bounds.extend(poly.getAt(i));
}
//initialize all properties.
this.bounds_ = bounds;
this.map_ = map;
this.div_ = null;
this.poly_ = poly;
this.polysvg_ = null;
this.fill_ = fill;
this.stroke_ = stroke;
// Explicitly call setMap on this overlay
this.setMap(map);
}
PolyLineFill.prototype.onAdd = function() {
// Create the DIV and set some basic attributes.
var div = document.createElement('div');
div.style.borderStyle = 'none';
div.style.borderWidth = '0px';
div.style.position = 'absolute';
//https://www.w3schools.com/graphics/svg_reference.asp
//createthe svg element
var svgns = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(svgns, "svg");
svg.setAttributeNS(null, "height", "100%");
svg.setAttributeNS(null, "width", "100%");
svg.setAttributeNS(null, "preserveAspectRatio", "xMidYMid meet");
//A container for referenced elements
var def = document.createElementNS(svgns, "defs");
//create the pattern fill
var pattern = document.createElementNS(svgns, "pattern");
//***************************CHANGE PATTERN HERE**********************************
pattern.setAttributeNS(null, "id", "lineFill");
pattern.setAttributeNS(null, "patternUnits", "userSpaceOnUse");
//pattern.setAttributeNS(null, "patternTransform", "rotate(-33)");
pattern.setAttributeNS(null, "height", "60");
pattern.setAttributeNS(null, "width", "60");
def.appendChild(pattern);
var rect = document.createElementNS(svgns, "rect");
rect.setAttributeNS(null, "id", "rectFill");
rect.setAttributeNS(null, "fill", "green");
rect.setAttributeNS(null, "fill-opacity", "0.25");
rect.setAttributeNS(null, "stroke", "#0000FF");
rect.setAttributeNS(null, "stroke-width", "8");
rect.setAttributeNS(null, "stroke-opacity", "0.25");
rect.setAttributeNS(null, "stroke-dasharray", "10 10");
rect.setAttributeNS(null, "x", "5");
rect.setAttributeNS(null, "y", "5");
rect.setAttributeNS(null, "height", "50");
rect.setAttributeNS(null, "width", "50");
rect.setAttributeNS(null, "rx", "25");
rect.setAttributeNS(null, "ry", "25");
pattern.appendChild(rect);
svg.appendChild(def);
//add polygon to the div
var p = document.createElementNS(svgns, "polygon");
p.setAttributeNS(null, "fill", "url(#lineFill)");
//set a reference to this element;
this.polysvg_ = p;
svg.appendChild(p);
div.appendChild(svg);
// Set the overlay's div_ property to this DIV
this.div_ = div;
// We add an overlay to a map via one of the map's panes.
// We'll add this overlay to the overlayLayer pane.
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
}
PolyLineFill.prototype.AdjustPoints = function() {
//adjust the polygon points based on the projection.
var proj = this.getProjection();
var sw = proj.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = proj.fromLatLngToDivPixel(this.bounds_.getNorthEast());
var points = "";
for (var i = 0; i < this.poly_.length; i++) {
var point = proj.fromLatLngToDivPixel(this.poly_.getAt(i));
if (i == 0) {
points += (point.x - sw.x) + ", " + (point.y - ne.y);
} else {
points += " " + (point.x - sw.x) + ", " + (point.y - ne.y);
}
}
return points;
}
PolyLineFill.prototype.draw = function() {
// Size and position the overlay. We use a southwest and northeast
// position of the overlay to peg it to the correct position and size.
// We need to retrieve the projection from this overlay to do this.
var overlayProjection = this.getProjection();
// Retrieve the southwest and northeast coordinates of this overlay
// in latlngs and convert them to pixels 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';
this.polysvg_.setAttributeNS(null, "points", this.AdjustPoints());
}
PolyLineFill.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
}
window.BW = {};
window.BW.PolyLineFill = PolyLineFill;
///end poly fill code
google.maps.event.addDomListener(window, 'load', initialize);
//**************************velho
function showArrays(event) {
if (this.overlay)
this.overlay.setMap(null)
this.overlay = new BW.PolyLineFill(this.getPath().b, this.map, "red", "#000");
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas,
#map_canvas {
height: 100%;
}
@media print {
html,
body {
height: auto;
}
#map_canvas {
height: 650px;
}
}
<script src="https://maps.google.com/maps/api/js?sensor=false&libraries=drawing&.js"></script>
<div id="map-canvas"></div>
可以在CANVAS中完成:
http://home.provide.net/~bratliff/hawaii/
单击“样式”单选选项可查看其他可选图案。