2013-04-04 140 views
4

我使用google map javascript API V3创建了谷歌地图。我正在绘制多个邮政编码多边形。多边形根据某些条件具有不同的颜色。现在我想根据某些标准在某些多边形内绘制直线/散列标记。我们该怎么做。下面是我写的绘制多边形的代码。如何在谷歌地图多边形内绘制直线

{% if zip.zip_info.zip_polygon %} 
    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); 

{% endif %} 

我也给我的需求的图像链接。

enter image description here

你可以像一些多边形的阴影与直线中所看到的,有些是只用颜色阴影。

+0

听起来好像要填充 “纹理”,类似这样的[增强请求(https://code.google.com/p/gmaps-api-issues/issues/detail?id = 598) – geocodezip 2013-04-04 20:10:26

+0

是的,想要添加一个纹理,其他字我们可以说我想在多边形内画线。我们能做到吗? – sandeep 2013-04-05 03:41:36

+0

目前您无法使用API​​来完成此操作。您可以为该增强请求投票(或为您的目的找到另一个更好的,或创建一个新的)。你或许可以用多段线做一些事情,但它可能会影响性能。 – geocodezip 2013-04-05 04:44:44

回答

6

我一直在研究同样的问题。这是我到目前为止:jsFiddle of Example

BW.PolyLineFill函数创建一个Custom Overlay。它需要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; 
+0

这方面的进一步进展如何?看起来像是有效的,但只要你放大缩小的东西看起来不正确。 – BigDubb 2014-09-02 15:55:33

+0

@BigDubb你能更具体什么不工作?上面的小提琴示例中的叠加示例没有与Google地图上定义的边界完全对齐,因为我很快获取了一些用于该示例的地理数据。用于收集数据的地图与Google的预测之间的地图投影可能略有不同。更准确的数据会有更好的结果,或者至少与Google选择的预测数据一致。我相信Google使用墨卡托投影,所以如果您使用其他类型,则在转换为屏幕坐标时会发生轻微偏移。 – 2014-09-05 14:55:56

+0

我在Chrome中解决了这个问题。放大犹他州,一旦我超过了一个特定的缩放级别,它会停止正确的多边形。它的一部分不渲染,如果放大足够,它就会一起消失。 – BigDubb 2014-09-18 18:01:56

-1

它可以在帆布做:

http://home.provide.net/~bratliff/hawaii/ 

单击 “样式” 单选选择,看看其他可选模式。

+0

是的,我看到了链接中的例子,它正在工作。但我们可以使用谷歌地图V3 API js来做到这一点。 – sandeep 2013-04-08 05:39:45

+0

这只适用于静态图片,可能为什么他们使用谷歌静态地图。 – Dennis 2014-02-20 19:08:45

1

我已经在Bryan Weaver的解决方案中使用绘图管理器使它可用于可编辑多边形。这里是我的jsfiddle example

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().b, 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().b, 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().b, 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[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_[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>

相关问题