2016-06-17 16 views
2

So wenden Sie Hex auf die ganze Welt an. Ich fand this Beispiel im Internet, konnte es aber nicht für die ganze Welt anwenden var bbox = [-180, -90, 180, 90];, aber es funktioniert nicht wie erwartet.So wenden Sie Hex auf die ganze Welt an

///////////////////////////////////////////////////////////////////////////////////////////// 
 
//setting up the map// 
 
///////////////////////////////////////////////////////////////////////////////////////////// 
 

 
// set center coordinates 
 
var centerlat = 40.758896; 
 
var centerlon = -73.985130; 
 

 
// set default zoom level 
 
var zoomLevel = 11; 
 

 
// initialize map 
 
var map = L.map('map').setView([centerlat, centerlon], zoomLevel); 
 

 
// set source for map tiles 
 
ATTR = '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' + 
 
    '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a> | ' + 
 
    '&copy; <a href="http://cartodb.com/attributions">CartoDB</a>'; 
 

 
CDB_URL = 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png'; 
 

 
// add tiles to map 
 
L.tileLayer(CDB_URL, { 
 
    attribution: ATTR 
 
}).addTo(map); 
 

 
///////////////////////////////////////////////////////////////////////////////////////////// 
 
//generating the GeoJSON objects// 
 
///////////////////////////////////////////////////////////////////////////////////////////// 
 

 
//create some GeoJSON points to be sampled (function below) 
 
var dotcount = 200000; 
 
var dots = make_dots(dotcount); 
 

 
//parameters for hex grid 
 
var bbox = [-74.035492, 40.706523, -73.908463, 40.825095]; 
 
var cellWidth = 0.3; 
 
var units = 'miles'; 
 

 
//create hex grid and count points within each cell 
 
var hexgrid = turf.hexGrid(bbox, cellWidth, units); 
 
var hexcounts = turf.count(hexgrid, dots, 'pt_count'); 
 
L.geoJson(hexcounts, { 
 
    onEachFeature: onEachHex 
 
}).addTo(map); 
 

 
function getRandomCoordinates(radius, uniform) { 
 
    // Generate two random numbers 
 
    var a = Math.random(), 
 
    b = Math.random(); 
 

 
    // Flip for more uniformity. 
 
    if (uniform) { 
 
    if (b < a) { 
 
     var c = b; 
 
     b = a; 
 
     a = c; 
 
    } 
 
    } 
 

 
    // It's all triangles. 
 
    return [ 
 
    b * radius * Math.cos(2 * Math.PI * a/b), 
 
    b * radius * Math.sin(2 * Math.PI * a/b) 
 
    ]; 
 
} 
 

 
function getRandomLocation(latitude, longitude, radiusInMeters) { 
 
    var randomCoordinates = getRandomCoordinates(radiusInMeters, true); 
 

 
    // Earths radius in meters via WGS 84 model. 
 
    var earth = 6378137; 
 

 
    // Offsets in meters. 
 
    var northOffset = randomCoordinates[0], 
 
    eastOffset = randomCoordinates[1]; 
 

 
    // Offset coordinates in radians. 
 
    var offsetLatitude = northOffset/earth, 
 
    offsetLongitude = eastOffset/(earth * Math.cos(Math.PI * (latitude/180))); 
 

 
    // Offset position in decimal degrees. 
 
    return { 
 
    latitude: latitude + (offsetLatitude * (180/Math.PI)), 
 
    longitude: longitude + (offsetLongitude * (180/Math.PI)) 
 
    } 
 
} 
 

 
/*function make_dots() { 
 
    var dots = { 
 
    type: "FeatureCollection", 
 
    features: [] 
 
    }; 
 

 
    for (var i = 0; i < dotcount; ++i) { 
 
    var loc = getRandomLocation(40.767915, -73.972321, 1000); 
 

 
    var t = L.marker([loc.latitude, loc.longitude]); 
 

 
    dots.features.push(t.toGeoJSON()); 
 
    } 
 

 
    return dots; 
 
} 
 
*/ 
 

 
///////////////////////////////////////////////////////////////////////////////////////////// 
 
//legend// 
 
///////////////////////////////////////////////////////////////////////////////////////////// 
 

 
//create legend 
 
var hexlegend = L.control({ 
 
    position: 'topright' 
 
}); 
 
//generate legend contents 
 
hexlegend.onAdd = function(map) { 
 
    //set up legend grades and labels 
 
    var div = L.DomUtil.create('div', 'info legend'), 
 
    grades = [1, 2, 5, 10, 20, 50, 100], 
 
    labels = ['<strong>Point Count</strong>'], 
 
    from, to; 
 

 
    //iterate through grades and create a color field and label for each 
 
    for (var i = 0; i < grades.length; i++) { 
 
    from = grades[i]; 
 
    to = grades[i + 1]; 
 
    labels.push(
 
     '<i style="background:' + getColor(from + 0.5) + '"></i> ' + from + (to ? '&ndash;' + to : '+')); 
 
    } 
 
    div.innerHTML = labels.join('<br>'); 
 
    return div; 
 
}; 
 
hexlegend.addTo(map); 
 

 
///////////////////////////////////////////////////////////////////////////////////////////// 
 
//styling functions// 
 
///////////////////////////////////////////////////////////////////////////////////////////// 
 

 
//highlight style 
 
var hexStyleHighlight = { 
 
    color: "#336", 
 
    weight: 2, 
 
    opacity: 1, 
 
}; 
 

 
//create color ramp 
 
function getColor(y) { 
 
    return y == undefined ? '#888' : 
 
    y < 1 ? '#ffffe9' : 
 
    y < 2 ? '#edf8b1' : 
 
    y < 5 ? '#c7e9b4' : 
 
    y < 10 ? '#7fcdbb' : 
 
    y < 20 ? '#41b6c4' : 
 
    y < 50 ? '#1d91c0' : 
 
    y < 100 ? '#225ea8' : 
 
    '#0c2c84'; 
 
} 
 

 
//create style, with fillColor picked from color ramp 
 
function style(feature) { 
 
    return { 
 
    fillColor: getColor(feature.properties.pt_count), 
 
    color: "#888", 
 
    weight: 0.5, 
 
    opacity: 1, 
 
    fillOpacity: 0.4//0.8 
 
    }; 
 
} 
 

 
//attach styles and popups to the hex layer 
 
function highlightHex(e) { 
 
    var layer = e.target; 
 
    layer.setStyle(hexStyleHighlight); 
 
    if (!L.Browser.ie && !L.Browser.opera) { 
 
    layer.bringToFront(); 
 
    } 
 
} 
 

 
function resetHexHighlight(e) { 
 
    var layer = e.target; 
 
    var hexStyleDefault = style(layer.feature); 
 
    layer.setStyle(hexStyleDefault); 
 
} 
 

 
function onEachHex(feature, layer) { 
 
    layer.on({ 
 
    mouseover: highlightHex, 
 
    mouseout: resetHexHighlight 
 
    }); 
 
    var hexStyleDefault = style(layer.feature); 
 
    layer.setStyle(hexStyleDefault); 
 
    //for the sake of grammar 
 
    if (feature.properties.pt_count == 1) { 
 
    var be_verb = "There is"; 
 
    var point_s = "point"; 
 
    } else { 
 
    var be_verb = "There are"; 
 
    var point_s = "points"; 
 
    } 
 
    layer.bindPopup(be_verb + ' <b>' + feature.properties.pt_count + '</b> ' + point_s + ' in this cell.'); 
 

 
} 
 

 
///////////////////////////////////////////////////////////////////////////////////////////// 
 
//synthetic GeoJSON functions// 
 
///////////////////////////////////////////////////////////////////////////////////////////// 
 

 
//cheapo normrand function 
 
function normish(mean, range) { 
 
    var num_out = ((Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random() - 4)/4) * range + mean; 
 
    return num_out; 
 
} 
 

 
//create geojson data with random ~normal distribution 
 
function make_dots(dotcount) { 
 

 
    var dots = { 
 
    type: "FeatureCollection", 
 
    features: [] 
 
    }; 
 

 
    for (var i = 0; i < dotcount; ++i) { 
 

 
    //set up random variables 
 
    /*x = normish(0, 4); 
 
    y = normish(0, 4); 
 

 
    //create points randomly distributed about center coordinates 
 
    var g = { 
 
     "type": "Point", 
 
      "coordinates": [((x * 0.11) + centerlon), ((y * 0.1) + centerlat)] 
 
    }; 
 

 
    //create feature properties, roughly proportional to distance from center coordinates 
 
    var p = { 
 
     "id": i, 
 
      "popup": "Dot_" + i, 
 
      "year": parseInt(Math.sqrt(x * x + y * y) * 60 * (1 - Math.random()/1.5) + 1900), 
 
      "size": Math.round((parseFloat(Math.abs((normish(y*y, 2) + normish(x*x, 2)) * 50) + 10)) * 100)/100 
 
    };*/ 
 

 
    var loc = getRandomLocation(40.769996, -73.973007, 5000); 
 

 
    var t = L.marker([loc.latitude, loc.longitude]); 
 

 
    dots.features.push(t.toGeoJSON()); 
 

 
    //create features with proper geojson structure   
 
    //dots.features.push({ 
 
    // "geometry" : g, 
 
    // "type": "Feature", 
 
    // "properties": p 
 
    //}); 
 
    } 
 
    return dots; 
 
}
html, 
 
body, 
 
#map { 
 
    height: 100%; 
 
    width: 100%; 
 
    padding: 0px; 
 
    margin: 0px; 
 
} 
 

 
.info { 
 
    padding: 6px 8px; 
 
    font: 14px/16px Arial, Helvetica, sans-serif; 
 
    background: white; 
 
    background: rgba(255, 255, 255, 0.8); 
 
    box-shadow: 0 0 15px rgba(0, 0, 0, 0.2); 
 
    border-radius: 5px; 
 
} 
 

 
.legend { 
 
    text-align: left; 
 
    line-height: 18px; 
 
    color: #555; 
 
} 
 

 
.legend i { 
 
    width: 18px; 
 
    height: 18px; 
 
    float: left; 
 
    margin-right: 8px; 
 
    opacity: 0.7; 
 
} 
 

 
.legend .colorcircle { 
 
    border-radius: 50%; 
 
    width: 15px; 
 
    height: 15px; 
 
    margin-top: 0px; 
 
}
<script src="https://api.mapbox.com/mapbox.js/plugins/turf/v2.0.2/turf.min.js"></script> 
 
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script> 
 
<link href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" rel="stylesheet"/> 
 

 
<div id="map"></div>

EDIT: Statt turf.js zu verwenden, die 3rd-Party-Bibliothek, die ich versuchte, meine eigene Hexagone erstellen L.multiPolygon mit allem funktioniert gut, aber es funktioniert nur für kleinen Teil der Karte, wenn Ich füge mehr Sechsecke hinzu, wenn der Browser abstürzt. Ich wollte also vermeiden, alle Hexfelder gleichzeitig zu laden, aber nur die, die auf dem Bildschirm zu sehen sind. Ich fand eine Methode L.PolyUtil.clipPolygon aber ich nicht sicher, wie es, hier ist die jsfiddle

///////////////////////////////////////////////////////////////////////////////////////////// 
 
//setting up the map// 
 
///////////////////////////////////////////////////////////////////////////////////////////// 
 
// set center coordinates 
 
var lat = 35.15; 
 
var lng = 33.35; 
 
var R = 500; 
 

 
// set default zoom level 
 
var zoomLevel = 13; 
 

 
// initialize map 
 
var map = L.map('map').setView([lat, lng], zoomLevel); 
 

 
// set source for map tiles 
 
ATTR = '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' + 
 
    '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a> | ' + 
 
    '&copy; <a href="http://cartodb.com/attributions">CartoDB</a>'; 
 

 
CDB_URL = 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png'; 
 

 
// add tiles to map 
 
L.tileLayer(CDB_URL, { 
 
    attribution: ATTR, 
 
    noWrap: true 
 
}).addTo(map); 
 

 
var b = new L.Circle([lat, lng], R).getBounds(); 
 
var r = (b._northEast.lat - b._southWest.lat)/2; 
 
var h = (b._northEast.lng - b._southWest.lng)/2; 
 
var d = Math.sqrt(3 * h * h/4); 
 

 
var grid_x = 100; 
 
var grid_y = 100; 
 

 
var la = lat; 
 
var lo = lng; 
 
var multiPolygonLatLongs = []; 
 
for (var i = 0; i < grid_x; i++) { 
 
    for (var j = 0; j < grid_y; j++) { 
 
     multiPolygonLatLongs.push([ 
 
      [la + r, lo], 
 
      [la + r/2, lo + d], 
 
      [la - r/2, lo + d], 
 
      [la - r, lo], 
 
      [la - r/2, lo - d], 
 
      [la + r/2, lo - d] 
 
     ]); 
 
     lo += d * 2; 
 
    } 
 
    lo = i % 2 == 0 ? lng + d : lng; 
 
    la += r * 1.5; 
 
} 
 

 
var p1 = map.getPixelOrigin(); 
 
var bounds = map.getPixelBounds(); 
 

 
var clipped = L.PolyUtil.clipPolygon(multiPolygonLatLongs, bounds); 
 

 
L.multiPolygon(clipped, { 
 
    weight: 1, 
 
    opacity: 0.2, 
 
    fill: false 
 
}).addTo(map);
html, body, #map { 
 
     height: 100%; 
 
     width:100%; 
 
     padding:0px; 
 
     margin:0px; 
 
    }
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script> 
 
<link href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" rel="stylesheet"/> 
 

 
<div id="map"></div>

Antwort

2

Sie konnte es in CartoDB mit einer Abfrage wie diese funktioniert:

SELECT 
    CDB_HexagonGrid(
    ST_Transform(
     ST_SetSRID( 
     ST_MakeEnvelope(
      -179.99, 
      -89.99, 
      179.99, 
      89.99), 
     4326), 
     3857), 
    150000) 
    AS the_geom_webmercator 

Führen Sie es im Editor aus und klicken Sie auf 'Datensatz von Abfrage erstellen'

Danach könnten Sie die Schicht als eine verwenden ny andere Schicht in CartoDB. Überprüfen Sie this example, um zu sehen, wie es mit cartodb.createLayer() mit benutzerdefinierter Interaktivität geladen wird.

Auch, wenn Sie die Daten in GeoJSON Format herunterladen wollen, anstatt im Merkblatt verwendet werden, könnten Sie so etwas wie verwenden:

var sql=new cartodb.SQL({user:'USERNAME', format:'geojson'}); 
    sql.execute("SELECT * FROM table_name").done(function(geojson){ 
    data=geojson; 
    }); 

Danach werden Sie das Hex-Raster als geoJSON layer im Merkblatt verwenden könnten .

+0

Ich möchte Kontrolle über mein Hex haben, möchte ich wissen, wenn es geklickt wird – Almis

+0

könnten Sie bitte jfiddle machen? – Almis