В процессе аппетиты как обычно выросли, и захотелось на карту добавить средства измерения расстояний и площадей.
Разобрались, что для расчетов нужен turf.min.js, а для менюшки и отрисовки mapbox-gl-draw.js.
Менюшку с кнопками добавили, как считать тоже более-менее понятно из примера. А как это вместе соединить, чтобы при выборе линейки и рисовке линии в контейнере на карте отображалась её длина?
Аналогично нужно для полигонов и их площадей.
Исходник страницы на данный момент, ссылка на неё же
Код: Выделить всё
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<style>
.distance-container {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
}
.distance-container > * {
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
font-size: 11px;
line-height: 18px;
display: block;
margin: 0;
padding: 5px 10px;
border-radius: 3px;
}
</style>
<style>
#menu {
background: #fff;
position: absolute;
z-index: 1;
top: 10px;
right: 10px;
border-radius: 3px;
width: 120px;
border: 1px solid rgba(0,0,0,0.4);
font-family: 'Open Sans', sans-serif;
}
#menu a {
font-size: 13px;
color: #404040;
display: block;
margin: 0;
padding: 0;
padding: 10px;
text-decoration: none;
border-bottom: 1px solid rgba(0,0,0,0.25);
text-align: center;
}
#menu a:last-child {
border: none;
}
#menu a:hover {
background-color: #f8f8f8;
color: #404040;
}
#menu a.active {
background-color: #3887be;
color: #ffffff;
}
#menu a.active:hover {
background: #3074a4;
}
</style>
<nav id="menu"></nav>
<div id="map"></div>
<div id='distance' class='distance-container'></div>
<script src='https://api.tiles.mapbox.com/mapbox.js/plugins/turf/v3.0.11/turf.min.js'></script>
<script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.0.0/mapbox-gl-draw.js'></script>
<link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.0.0/mapbox-gl-draw.css' type='text/css'/>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoibWV6aGR1cmVjaGllIiwiYSI6ImNqNTg1Y2F1YzB3dnEzMG9jcG9tcmhxdXoifQ.TucxuoURziJkOdBVfnrC0A';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mezhdurechie/cj59enqdt56o92so1hp3sh03o',
zoom: 14,
center: [38.008, 57.09],
maxZoom: 19
});
var draw = new MapboxDraw({
displayControlsDefault: false,
controls: {
line_string: true,
polygon: true,
trash: true
}
});
map.on('load', function () {
map.addSource('elevations', {
type: 'raster',
url: 'mapbox://mezhdurechie.4alj1vc7'
});
map.addLayer({
'id': 'Модель высот',
'type': 'raster',
'source': 'elevations',
'layout': {
'visibility': 'none'
},
});
map.addSource('road', {
type: 'vector',
url: 'mapbox://mezhdurechie.crsa2fjj'
});
map.addLayer({
'id': 'Дороги',
'type': 'line',
'source': 'road',
'source-layer': 'roads_all-du3t1x',
'layout': {
'visibility': 'none'
},
'paint': {
'line-color': '#000000',
'line-width': 2
}
});
map.addSource('parcels', {
type: 'vector',
url: 'mapbox://mezhdurechie.do9pu85q'
});
map.addLayer({
'id': 'Участки',
'type': 'line',
'source': 'parcels',
'source-layer': 'parcels-8my99a',
'layout': {
'visibility': 'none'
},
'paint': {
'line-color': 'hsl(0, 100%, 50%)',
'line-width': 2,
'line-opacity':0.6
}
});
map.addLayer({
'id': 'Подписи участков',
'type': 'symbol',
'source': 'parcels',
'source-layer': 'parcels-8my99a',
'layout': {
'visibility': 'none',
"icon-allow-overlap": true,
"text-field": "{КНоме}",
"text-font": ["Open Sans Bold", "Arial Unicode MS Bold"],
"text-size": 10,
"text-offset": [0, 0.5]
},
'paint': {
"text-color": "hsl(0, 100%, 50%)",
"text-halo-color": "#fff",
"text-halo-width": 1
}
});
map.addSource('el_nodes', {
type: 'vector',
url: 'mapbox://mezhdurechie.6s1w5dt2'
});
map.addLayer({
'id': 'Отметки высот',
'type': 'symbol',
'source': 'el_nodes',
'source-layer': 'poi_nodes-7wlbey',
'layout': {
'visibility': 'none',
"icon-allow-overlap": true,
"text-field": "{elevation}",
"text-font": ["Open Sans Bold", "Arial Unicode MS Bold"],
"text-size": 10,
"text-offset": [0, 0.5]
},
'paint': {
"text-color": "hsl(0, 0%, 0%)",
"text-halo-color": "#fff",
"text-halo-width": 1
}
});
});
var toggleableLayerIds = ['Участки', 'Подписи участков', 'Дороги', 'Модель высот', 'Отметки высот'];
for (var i = 0; i < toggleableLayerIds.length; i++) {
var id = toggleableLayerIds[i];
var link = document.createElement('a');
link.href = '#';
link.className = 'hover';
link.textContent = id;
link.onclick = function (e) {
var clickedLayer = this.textContent;
e.preventDefault();
e.stopPropagation();
var visibility = map.getLayoutProperty(clickedLayer, 'visibility');
if (visibility === 'visible') {
map.setLayoutProperty(clickedLayer, 'visibility', 'none');
this.className = '';
} else {
this.className = 'active';
map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
}
};
var layers = document.getElementById('menu');
layers.appendChild(link);
}
var draw = new MapboxDraw({
displayControlsDefault: false,
controls: {
line_string: true,
polygon: true,
trash: true
}
});
map.addControl(draw, ['top-left']);
</script>
</body>
</html>
Видел годные примеры на Leaflet, даже пытался вставить, но не взлетело.
Этим кодом добавил на карту кнопку, которая не активна, не нажимается.
Код: Выделить всё
var measureControl = new L.Control.Measure({
primaryLengthUnit: 'meters',
secondaryLengthUnit: 'kilometers',
primaryAreaUnit: 'sqmeters',
secondaryAreaUnit: 'hectares'
});
window.onload = map.addControl(measureControl, ['top-left']);
Видимо Mapbox GL не очень дружит с leaflet.
Путаное немного техзадание получилось, просто мозг кипит от кучи новых знаний .
Вижу результат как кусок кода в странице или подключаемый скрипт, который добавит вычисление на лету длины для рисуемых интерактивно полилиний и площади соответственно для полигонов.
Стоимость попробуйте назвать сами, я не знаю сколько это вообще может стоить. Товарищ, которому это всё нужно, готов на разумную оплату.