Создание картосхемы
- Эдуард Столяр
Платформа поддерживает создание интерактивных картосхем. Вы можете задать параметры карты в формате GeoJSON, и затем создать пользовательский виджет (карту) с использованием полученного кода.
Для создания картосхемы необходимо выполнить следующие шаги:
На вкладке Виджет нажмите кнопку с тремя точками и щелкните Создать виджет для создания пользовательского виджета:
В открывшемся окне введите название виджета (например, “Карта”).
В поле JavaScript вставьте код карты в формате GeoJSON (например, из нашего примера ниже) с требуемыми настройками параметров. В нашем примере представлен код карты Москвы. Код снабжен комментариями, облегчающими понимание настроек:
console.log(w);
//Данная карта выводит слой GeoJSON с привязаными к нему данными.
//В коде можно также отформатировать всплывающую подсказку или подсказку в правом верхнем углу (см. комментарии).
//Изменить стиль подсказки в правом верхнем углу можно в начале кода в styleText.
w.props = {
defaultLatLan: [55.7533, 37.622], //Значение широты и долготы по умолчанию.
defaultZoom: 10, //Значение зума по умолчанию.
maxZoom: 14, //Максимальный зум
minZoom: 9, //Минимальный зум
nameOfProperty: 'district_nm', //Имя свойства карты, по которому будут привязываться данные и которое будет показываться в подсказках.
jsonURL: 'https://lms.matyx.ru/uploads/dict.d_division_district.json', //Путь доя geojson файла.
tilesURL: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', //Путь до скаченных файлов (т.е. скаченная карта). Если параметр не указан, карта работает онлайн.
colorAxis: ['#FFEDA0', '#800026'], //Цвета, в которые будут раскрашены полигоны. Слева минимальное значение, справа максимальное.
axisSteps: 30, //Количество шагов, которое будет использовано для цветовой оси.
stepLegendWidth: '10px', //Ширина шага на легенде. Если шагов много, логично сделать ширину шага уже, т.к. легенда может быть очень широкой.
};
//Подключение стилей и библиотеки Leaflet
const head = document.querySelector('head');
const leafletCSS = ` <link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css"
integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
crossorigin=""/>`;
head.insertAdjacentHTML('beforeend', leafletCSS);
const leafletJS = document.createElement('script');
leafletJS.async = false;
leafletJS.src = 'https://unpkg.com/leaflet@1.8.0/dist/leaflet.js';
head.append(leafletJS);
const choroplet = document.createElement('script');
choroplet.async = false;
choroplet.src = 'https://cdn.jsdelivr.net/gh/cyxapbyad/visiology@main/choropleth.js';
head.append(choroplet);
//Стили для подсказки и легенды
const styleText = `
.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;
}
.info h4 {
margin: 0 0 5px;
color: #777;
}
.legend {
color: #555;
padding: 6px 8px;
font: 12px Arial, Helvetica, sans-serif;
font-weight: bold;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}
.legend ul {
list-style-type: none;
padding: 0;
margin: 0;
clear: both;
}
.legend li {
display: inline-block;
width: ${w.props.stepLegendWidth};
height: 22px;
}
.legend .min {
float: left;
padding-bottom: 5px;
}
.legend .max {
float: right;
}`;
const style = document.createElement('style');
style.insertAdjacentHTML('afterbegin', styleText);
head.append(style);
//Если бибилотека Leaflet полностью загружена, работаем с картой.
leafletJS.onload = async () => {
// Проверяем, пустой ли контейнер с картой, чтобы не было ошибки. Если не пустой - очищаем.
var container = L.DomUtil.get(w.general.renderTo);
if (container !== null) {
container._leaflet_id = null;
}
//Объявляем карту, начальные координаты и масштаб по умолчанию.
var map = L.map(w.general.renderTo, { attributionControl: false }).setView(
w.props.defaultLatLan,
w.props.defaultZoom
);
//Основной слой карты
var tiles = L.tileLayer(w.props.tilesURL ? w.props.tilesURL : 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: w.props.maxZoom,
minZoom: w.props.minZoom,
//attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
//Загружаем GeoJSON с районами Москвы. В данном примере в этом блоке карта фильтруется, остаются только нужные полигоны.
const districtJson = w.props.jsonURL;
let district = await $.getJSON(districtJson, function (geojson) {
return geojson;
});
//district.features = district.features.filter(item => item.properties.name === "СК-ТТК" || item.properties.name === "ТТК-МКАД" || item.properties.name === "Внутри СК" || item.properties.name === "За МКАД")
console.log(district);
//Подготавливаем данные. Добавляем показатели из базы.
w.data.primaryData.items.forEach((item, itemInd) => {
district.features.forEach((dist, distInd) => {
if (item.keys[0].replace('район', '').trim() === dist.properties[w.props.nameOfProperty]) {
dist.properties.value = item.values[0];
dist.properties.value2 = item.values[1];
}
});
});
//Добавляем слой GeoJSON с помощью плагина Koroplet, который раскрасит полигоны по заданным параметрам.
let choroplethLayer = L.choropleth(district, {
valueProperty: 'value', // указывает какое свойство из фич использовать для разукрашивания секторов
scale: w.props.colorAxis, // chroma.js scale - включите столько, сколько захотите.
steps: w.props.axisSteps, // количество шагов для цветовой шкалы.
mode: 'q', // q - для квантиля, e - для эквидистанты, k - для k-средних.
style: {
color: '#fff', // цвет границы.
weight: 2,
fillOpacity: 0.5,
dashArray: '3',
},
// onEachFeature: function(feature, layer) {
// layer.bindPopup(feature.properties.value)
// }
}).addTo(map);
//Добавляем события over и out для мыши (подсветка полигона, подсказка).
let geojson;
function highlightFeature(e) {
var layer = e.target;
//console.log(layer)
layer.bindTooltip(`<b>${layer.feature.properties[w.props.nameOfProperty]}</b></br>
Мощность: ${layer.feature.properties.value} кВт
`); //Форматирование подсказки
this.openTooltip();
layer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7,
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
info.update(layer.feature.properties);
}
function resetHighlight(e) {
geojson.resetStyle(e.target);
//this.closePopup();
info.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature,
});
}
geojson = L.geoJson(district, {
style: {
color: '#fff', // Цвет границы.
weight: 2,
fillOpacity: 0,
dashArray: '',
},
onEachFeature: onEachFeature,
}).addTo(map);
var info = L.control();
// Подсказка в правом верхнем углу.
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info'); // создайте div с классом "info"
this.update();
return this._div;
};
// Метод, который мы будем использовать для обновления элемента управления на основе переданных свойств объекта.
// Здесь можно отформатировать текст подсказки.
info.update = function (props) {
this._div.innerHTML =
'<h4>Вся информация</h4>' +
(props
? `<b>${props[w.props.nameOfProperty]}</b><br />
Мощность: ${props.value ? props.value : '0'} кВт</br>
Средняя стоимость кВт\ч: ${props.value2 ? props.value2.toFixed(2) : '0'} руб
`
: 'Наведите на район');
};
info.addTo(map);
// Добавьте легенду (не забудьте добавить CSS из index.html)
var legend = L.control({ position: 'bottomright' });
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend');
var limits = choroplethLayer.options.limits;
var colors = choroplethLayer.options.colors;
var labels = [];
// Добавьте максимальные и минимальные значения
div.innerHTML =
'<div class="labels"><div class="min">' +
limits[0] +
'</div> \
<div class="max">' +
limits[limits.length - 1] +
'</div></div>';
limits.forEach(function (limit, index) {
labels.push('<li style="background-color: ' + colors[index] + '"></li>');
});
div.innerHTML += '<ul>' + labels.join('') + '</ul>';
return div;
};
legend.addTo(map);
};
Добавьте необходимые поля виджета в правой части окна и нажмите Готово:
Созданный виджет появится среди прочих пользовательских виджетов:
Теперь для создания картосхемы щелкните по иконке виджета и перетащите требуемые столбцы с данными из загруженной таблицы – карта отобразится в окне виджета. В нашем примере при наведении курсора мыши на какой-либо район Москвы изменяется цвет просматриваемой области, а также отображается окно с дополнительной информацией:
Смотрите также