Ответ 1
Вы можете сделать это, наложив изображение тепловой карты на карту. Там очень хороший пример с открытым исходным кодом в https://github.com/jeffkaufman/apartment_prices
Я делаю плакат с Google API v3. Я приведу пример. Давайте рассмотрим величины землетрясений. Я назначаю веса каждой точке, чтобы указать их величину. Однако Google учитывает плотность точек при уменьшении масштаба. Чем больше очков в месте, тем более красным оно становится. Например, если два earthqueaks произошли в милях друг от друга, один с магнитудой 3, а другие с магнитудой 8, первый один должен быть зеленым/синим цветом, а второй один будет красным. Но как только вы уменьшаете масштаб, и две точки становятся ближе к карте, карты google учитывают количество точек вместо весов, и в результате они выглядят считанными. Я хочу, чтобы он был средним, т.е. (3 + 8)/2=5.5... любым цветом, который представляет. Это возможно?
Вы можете сделать это, наложив изображение тепловой карты на карту. Там очень хороший пример с открытым исходным кодом в https://github.com/jeffkaufman/apartment_prices
Если вы похожи на меня и у вас нет времени на обработку или мощности для создания оверлея, существует несколько достойное решение, и вы не можете изменять существующие библиотеки по своему вкусу.
Я использовал библиотеку Heatmap карт google и установил maxIntensity и рассеивался на false. Установка maxIntensity на выбранное вами значение решит проблему того, что ваши точки нагрева будут окрашены по отношению друг к другу, а не к 0 или заданному значению. При настройке параметра disipating to false вы можете отключить параметры автоматического радиуса, которые происходят при изменении уровней масштабирования.
Далее я сделал событие для каждого изменения уровня масштабирования, и в этом случае я установил радиус в значение, которое, казалось, представляло мои данные самым точным способом для этого уровня масштабирования.
Теперь, чтобы избавиться от проблемы, когда точки данных на карте смешиваются и объединяются в большой красный блок, я решил сделать отдельную сетку на моей карте для каждого уровня масштабирования, который я хочу использовать. Я усредняю все значения, которые помещаются внутри одной и той же точки сетки, и убедитесь, что сетка достаточно велика, чтобы точки точек нагрева не перекрывались, но достаточно мала, чтобы не выглядеть как куча кругов. (Я обнаружил, что сетка должна быть примерно в 0,4 раза больше радиуса теплоты на карте для гладкого внешнего вида).
Радиус точки Heatmap задается Google в пикселях. Я не знал, как преобразовать пиксели в Lat/Long, поэтому я просто измерил его, вычерчивая линии за круг с определенным радиусом и измеряя расстояние между этими линиями. Этот метод конвертации будет работать очень хорошо, если вы не планируете отображать гораздо больше, чем небольшая страна.
Производительность - это не так плохо, как я думал. Я загружаю около 2300 точек, а карта загружается так же быстро, как и до того, как я сделал сетку для каждого уровня масштабирования, и вы фактически не видите, что обновленные точки данных обновляются при изменении уровней масштабирования.
Вот некоторые фрагменты кода для всего вышеперечисленного:
Настройки карты:
map.heatmap.set('maxIntensity', 12000);
map.heatmap.set('dissipating', false);
Измените сетку и радиус для каждого уровня масштабирования:
map._on({
obj: map.gMap,
event: "zoom_changed",
callback: function(){
var zoomLevel = map.zoom();
switch(zoomLevel){
case 7:
map.heatmap.setData(gridData[zoomLevel]);
map.heatmap.set('radius', 0.04);
break;
case 8:
map.heatmap.setData(gridData[zoomLevel]);
map.heatmap.set('radius', 0.03);
break;
case 9:
map.heatmap.setData(gridData[zoomLevel]);
map.heatmap.set('radius', 0.02);
break;
case 10:
map.heatmap.setData(gridData[zoomLevel]);
map.heatmap.set('radius', 0.01);
break;
case 11:
map.heatmap.setData(gridData[zoomLevel]);
map.heatmap.set('radius', 0.005);
break;
case 12:
map.heatmap.setData(gridData[zoomLevel]);
map.heatmap.set('radius', 0.0025);
break;
case 13:
map.heatmap.setData(gridData[zoomLevel]);
map.heatmap.set('radius', 0.00225);
break;
default:
map.heatmap.setData(gridData[zoomLevel]);
map.heatmap.set('radius', 0.000625);
}
}
});
Мои сетки генерируются в PHP, которые, вероятно, будут выглядеть разными для всех, но, как пример, здесь используется функция:
function getHeatGrid($gridSize){
$mapGrid = false;
$mapData = false;
$radius = $gridSize * 2.8 * 0.3; //grid size is multiplied by 2.8 to convert from the heat map radius to lat/long values(works for my lat/long, maybe not yours). * 0.3 is arbitrary to avoid seeing the grid on the map.
$string = file_get_contents("mapData.json");
$json_a = json_decode($string, true);
forEach($json_a as $key => $value){
$row = intval(round(($value['center_longitude'] / $radius)));
$column = intval(round(($value['center_latitude'] / $radius)/68*111)); //around 52.0;5.0 latitude needs to be scaled to make a square grid with the used longitude grid size
if(isset($mapGrid[$row][$column])){
$mapGrid[$row][$column] = round(($value['solarValue'] + $mapGrid[$row][$column]) / 2);
} else {
$mapGrid[$row][$column] = $value['solarValue'];
}
}
forEach($mapGrid as $long => $array){
forEach($array as $lat => $weight){
$mapData[] = array(
"center_longitude" => $long * $radius,
"center_latitude" => ($lat * $radius)/111*68,
"solarValue" => $weight
);
}
}
return $mapData;
}
К сожалению, я не могу отобразить карту прямо сейчас, поскольку она в настоящее время остается конфиденциальной для клиентов компании, в которой я работаю, но если она станет доступна публично, я добавлю ссылку, чтобы вы могли видеть, насколько хорошо этот метод работает.
Надеюсь, это поможет кому-то.
Лукаса
Тепловая карта по определению рассматривает плотность точек, а также вес, присвоенный каждой точке. Насколько я знаю из-за работы с ними, по крайней мере, Google Heat Map работает так. Так что вам действительно нужна не карта тепла, а карта точек, в которой они будут окрашены в зависимости от значения.
Мне также нужно было изменить плотность/вес отношения, которые учитывают диаграммы Google, чтобы окрасить карту, но я не нашел никакого способа. В настоящее время основным фактором тепловой карты является плотность, а изменение веса мало влияет на цвет.
Как частичное решение, я изменил heatmap.js из следующего проекта: https://github.com/pa7/heatmap.js
Чтобы получить среднее значение в одной длинной/лат-точке, я изменил функцию _organiseData для хранения PointCount и PointSum для каждой позиции x, y; и с этими значениями я получаю среднее значение в точке с:
store [x] [y] = storePointSum [x] [y]/storePointCount [x] [y];
Я все еще работаю над тем, как модифицировать "blend", когда несколько x, y coords стека при различных разрешениях карты... Если я выясню это, я опубликую его.
веселит
~ Аарон
Этот пример использует тепловые карты как слой над картой, надеюсь, что это поможет: http://maps.forum.nu/v3/gm_customTiles.html