How can I make a Google Maps API v3 hexagon tiled map, preferably coordinate-based?
Asked Answered
A

2

6

http://econym.org.uk/gmap/example_eshapes.htm has a Google Maps API v2 example of how to tile hexagons, although the implementation scales painfully: it has a center hexagon, then six hexagons adjacent to it in the appropriate directions, then (in quasi-recursion) three hexagons adjacent to one of the hexagons adjacent to the original hexagon. And it has a nice border with transparent fill.

How can I create a similar effect, but preferably with tiling so that I specify (without mounds of recursion) that I want a tile six hexagons to the east of the origin and four hexagons 60° north of east from the tile six hexagons to the east?

I'm looking for something coordinate-based and preferably simple. I've looked at the source for http://www.rootmetrics.com/check-coverage/ and it works, but the code is coupled to their specific page, markup, etc., so imitating their code would take a bit of untangling.

Aperient answered 1/8, 2012 at 14:44 Comment(0)
S
3

The following example demonstrates how to render horizontal hexagons grid:

function initialize() {
    var mapOptions = {
        zoom: 7,
        mapTypeId: google.maps.MapTypeId.TERRAIN
    };

    var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
    var startPosition = new google.maps.LatLng(33.748589, -84.390392);  //Atlanta, GA, USA 
    var radius = 40 * 1000; //radius in meters
    drawHorizontalHexagonGrid(map,startPosition,radius,6);
    map.setCenter(startPosition);
}

function drawHorizontalHexagonGrid(map,startPosition,radius,count){
    var curPos = startPosition;
    var width = radius * 2 * Math.sqrt(3)/2 ; 
    for(var i = 0;i < count; i++){
        drawHorizontalHexagon(map,curPos,radius);
        curPos = google.maps.geometry.spherical.computeOffset(curPos, width,90);   
    }
}

function drawHorizontalHexagon(map,position,radius){
    var coordinates = [];
    for(var angle= 0;angle < 360; angle+=60) {
       coordinates.push(google.maps.geometry.spherical.computeOffset(position, radius, angle));    
    }
  
    // Construct the polygon.
    var polygon = new google.maps.Polygon({
        paths: coordinates,
        strokeColor: '#FF0000',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#FF0000',
        fillOpacity: 0.35
    });
    polygon.setMap(map);
    map.setCenter(position);
}

google.maps.event.addDomListener(window, 'load', initialize);
html, body, #map-canvas {
    height: 100%;
    margin: 0px;
    padding: 0px;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&libraries=geometry"></script>
<div id="map-canvas"></div>
Soundboard answered 3/7, 2015 at 19:34 Comment(0)
B
2

I ported eshapes (and http://econym.org.uk/gmap/example_eshapes.htm) to the Google Maps API v3

http://www.geocodezip.com/v3_MW_example_eshapes.html

Not clear if that is what you are looking for, but it seems to be from the title of your question.

proof of concept fiddle

code snippet:

var map = null;

function initMap() {
  var myOptions = {
    zoom: 8,
    center: new google.maps.LatLng(43, -79.5),
    mapTypeControl: true,
    mapTypeControlOptions: {
      style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
    },
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  map = new google.maps.Map(document.getElementById("map"),
    myOptions);

  // === Hexagonal grid ===
  var point = new google.maps.LatLng(42, -78.8);
  map.setCenter(point);
  var hex1 = google.maps.Polygon.RegularPoly(point, 25000, 6, 90, "#000000", 1, 1, "#00ff00", 0.5);
  hex1.setMap(map);
  var d = 2 * 25000 * Math.cos(Math.PI / 6);
  var hex30 = google.maps.Polygon.RegularPoly(EOffsetBearing(point, d, 30), 25000, 6, 90, "#000000", 1, 1, "#00ffff", 0.5);
  hex30.setMap(map);
  var hex90 = google.maps.Polygon.RegularPoly(EOffsetBearing(point, d, 90), 25000, 6, 90, "#000000", 1, 1, "#ffff00", 0.5);
  hex90.setMap(map);
  var hex150 = google.maps.Polygon.RegularPoly(EOffsetBearing(point, d, 150), 25000, 6, 90, "#000000", 1, 1, "#00ffff", 0.5);
  hex150.setMap(map);
  var hex210 = google.maps.Polygon.RegularPoly(EOffsetBearing(point, d, 210), 25000, 6, 90, "#000000", 1, 1, "#ffff00", 0.5);
  hex210.setMap(map);
  hex270 = google.maps.Polygon.RegularPoly(EOffsetBearing(point, d, 270), 25000, 6, 90, "#000000", 1, 1, "#ffff00", 0.5);
  hex270.setMap(map);
  var hex330 = google.maps.Polygon.RegularPoly(EOffsetBearing(point, d, 330), 25000, 6, 90, "#000000", 1, 1, "#ffff00", 0.5);
  hex330.setMap(map);
  var hex30_2 = google.maps.Polygon.RegularPoly(EOffsetBearing(EOffsetBearing(point, d, 30), d, 90), 25000, 6, 90, "#000000", 1, 1, "#ff0000", 0.5);
  hex30_2.setMap(map);
  var hex150_2 = google.maps.Polygon.RegularPoly(EOffsetBearing(EOffsetBearing(point, d, 150), d, 90), 25000, 6, 90, "#000000", 1, 1, "#0000ff", 0.5);
  hex150_2.setMap(map);
  var hex90_2 = google.maps.Polygon.RegularPoly(EOffsetBearing(EOffsetBearing(point, d, 90), d, 90), 25000, 6, 90, "#000000", 1, 1, "#00ff00", 0.5);
  hex90_2.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initMap);

// EShapes.js
//
// Based on an idea, and some lines of code, by "thetoy" 
//
//   This Javascript is provided by Mike Williams
//   Community Church Javascript Team
//   http://www.bisphamchurch.org.uk/   
//   http://econym.org.uk/gmap/
//
//   This work is licenced under a Creative Commons Licence
//   http://creativecommons.org/licenses/by/2.0/uk/
//
// Version 0.0 04/Apr/2008 Not quite finished yet
// Version 1.0 10/Apr/2008 Initial release
// Version 3.0 12/Oct/2011 Ported to v3 by Lawrence Ross
// subset of EShapes.js

google.maps.Polygon.Shape = function(point, r1, r2, r3, r4, rotation, vertexCount, strokeColour, strokeWeight, Strokepacity, fillColour, fillOpacity, opts, tilt) {
  var rot = -rotation * Math.PI / 180;
  var points = [];
  var latConv = google.maps.geometry.spherical.computeDistanceBetween(point, new google.maps.LatLng(point.lat() + 0.1, point.lng())) * 10;
  var lngConv = google.maps.geometry.spherical.computeDistanceBetween(point, new google.maps.LatLng(point.lat(), point.lng() + 0.1)) * 10;
  var step = (360 / vertexCount) || 10;

  var flop = -1;
  if (tilt) {
    var I1 = 180 / vertexCount;
  } else {
    var I1 = 0;
  }
  for (var i = I1; i <= 360.001 + I1; i += step) {
    var r1a = flop ? r1 : r3;
    var r2a = flop ? r2 : r4;
    flop = -1 - flop;
    var y = r1a * Math.cos(i * Math.PI / 180);
    var x = r2a * Math.sin(i * Math.PI / 180);
    var lng = (x * Math.cos(rot) - y * Math.sin(rot)) / lngConv;
    var lat = (y * Math.cos(rot) + x * Math.sin(rot)) / latConv;

    points.push(new google.maps.LatLng(point.lat() + lat, point.lng() + lng));
  }
  return (new google.maps.Polygon({
    paths: points,
    strokeColor: strokeColour,
    strokeWeight: strokeWeight,
    strokeOpacity: Strokepacity,
    fillColor: fillColour,
    fillOpacity: fillOpacity
  }))
}

google.maps.Polygon.RegularPoly = function(point, radius, vertexCount, rotation, strokeColour, strokeWeight, Strokepacity, fillColour, fillOpacity, opts) {
  rotation = rotation || 0;
  var tilt = !(vertexCount & 1);
  return google.maps.Polygon.Shape(point, radius, radius, radius, radius, rotation, vertexCount, strokeColour, strokeWeight, Strokepacity, fillColour, fillOpacity, opts, tilt)
}

function EOffsetBearing(point, dist, bearing) {
  var latConv = google.maps.geometry.spherical.computeDistanceBetween(point, new google.maps.LatLng(point.lat() + 0.1, point.lng())) * 10;
  var lngConv = google.maps.geometry.spherical.computeDistanceBetween(point, new google.maps.LatLng(point.lat(), point.lng() + 0.1)) * 10;
  var lat = dist * Math.cos(bearing * Math.PI / 180) / latConv;
  var lng = dist * Math.sin(bearing * Math.PI / 180) / lngConv;
  return new google.maps.LatLng(point.lat() + lat, point.lng() + lng)
}
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map"></div>
Berry answered 1/8, 2012 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.