I am looking function which enable me to loss of parts of Layer when zooming the map.
map.on('zoomend', onZoomend)
function onZoomend(feature){
if(map.getZoom()<11)
{map.addLayer("road_2"==feature.properties.density)};
if(map.getZoom()>11)
{map.removeLayer("road_2"==feature.properties.density)};
}
My GeoJson file is in panel layers:
var overLayers = [
{
group: "Layer",
collapsed: true,
layers: [
{
name: "Road",
icon: iconByName('fuel_road'),
layer: L.geoJson(road,{style: style_road})
},
File GeoJson bulid that:
var road = {
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "density" : "road_1"....
{ "type": "Feature", "properties": { "density" : "road_2"....
{ "type": "Feature", "properties": ....
Update:
Is this way have a future? What must it be improved?
function style_road(feature) {
if ("road_1" == feature.properties.density) {
return {
weight: 3,
opacity:function()
{if (zoom > 13) {opacity:0},
else (zoom < 13) {opacity:1},
},
color: 'red',
};
}
else if ("road_2" == feature.properties.density){
return {
weight: 1.5,
opacity: 1,
color: 'red',
};
}
else {
return {
weight: 0.5,
opacity: 1,
color: 'red',
};
}
}
I am not sure if I understand you right, but you want to remove a layer when zooming in and adding it when zooming out?
You just can use:
if(map.getZoom()<11){
mylayer.removeFrom(map);
}else{
mylayer.addTo(map);
}
Did I understand you right?
UPDATE:
You can iterate through the GeoJson Layer and set the fillOpacity to 0 for hiding some geoms:
var geoJsonLayer = L.geoJson(myGeoJson).addTo(map);
if(map.getZoom()<11){
geoJsonLayer.eachLayer(function(layer) {
if(layer.feature.properties.density == "road_"){
layer.setStyle({fillOpacity:0});
}
});
}
Related
I am trying to display multiple circles on a mapbox-gl map. The color of the circles depends on the value of the aqi property. I have set interpolation of the color depending on that value. The problem is I am always getting black circles.
The circle color property:
'circle-color': [
'interpolate',
['linear'],
['get', 'aqi'],
0,
'#eee695',
50,
'#a5fc03',
100,
'#dbfc03',
200,
'#fc1c03'
],
The full function:
map.on('load', () => {
Axios.get('https://api.waqi.info/map/bounds/?latlng=41.03143,20.52421,42.20194,22.89056&token='+AQI_KEY).then(res=>{
const data = [];
res.data.data.map(station=>{
if(station.aqi!=='-'){
data.push(JSON.stringify({ "type": "Feature", "properties": {"aqi": station.aqi},
"geometry":
{
"type": "Point", "coordinates": [ station.lon, station.lat ]
}
}))
}
})
map.addSource('AQI', {
'type': 'geojson',
'data':
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "aqi": "aqi" } },
"features": data.map(JSON.parse)
}
});
map.addLayer(
{
'id': 'AQI-heat',
'type': 'circle',
'source': 'AQI',
'paint': {
'circle-radius': {
'type': 'exponential',
'stops': [[0, 70], [500, 70]]
},
'circle-opacity': {
'type': 'exponential',
'stops': [[-99, 0.0], [-50, 1.0]]
},
'circle-color': [
'interpolate',
['linear'],
['get', 'aqi'],
0,
'#eee695',
50,
'#a5fc03',
100,
'#dbfc03',
200,
'#fc1c03'
],
'circle-blur': 1
}
}
);
})
})
}
Even tho I have set different colors for different values, I always just get black circles.
I'm using MapBox GL JS v1.4.1
Based on the example here: https://docs.mapbox.com/mapbox-gl-js/example/cluster/
I cannot get my cluster count to display.
I have tried replicating the MapBox example directly and also using my own data but whatever I try results in the count not displaying.
This is what I have:
<div id="map"></div>
mapboxgl.accessToken = 'ACCESS_TOKEN';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v10',
zoom: 1
});
My geoJson data:
var geoData = {
"type": 'FeatureCollection',
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [151.12100, -33.78420]
},
"properties": {
"title" : "title",
"description": "description"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [151.12100, -33.78420]
},
"properties": {
"title" : "title",
"description": "description"
}
}
]
};
Loading the map, adding geoJSON, clusters etc:
map.on('load', function() {
map.addSource("testMapData", {
type: "geojson",
data: geoData,
cluster: true,
clusterMaxZoom: 14,
clusterRadius: 50
});
map.addLayer({
id: "cluster-count",
type: "symbol",
source: "testMapData",
filter: ["has", "point_count"],
layout: {
"text-field": "{point_count_abbreviated}",
"text-font": ["Arial Unicode MS Bold"],
"text-size": 12,
"text-allow-overlap" : true
}
});
map.addLayer({
id: "clusters",
type: "circle",
source: "testMapData",
filter: ["has", "point_count"],
paint: {
"circle-color": "#f1f075",
"circle-radius": 40
}
});
map.addLayer({
id: "unclustered-point",
type: "circle",
source: "testMapData",
filter: ["!", ["has", "point_count"]],
paint: {
"circle-color": "#51bbd6",
"circle-radius": 8,
"circle-stroke-width": 1,
"circle-stroke-color": "#fff"
}
});
});
Based on the above I should get the cluster count on each of my clusters, but I only see the cluster with no count.
The console also shows no errors.
I can't determine if there's an issue with my geoJSON (it validates via the linter here: http://geojsonlint.com/)... or if the issue lies in how I have added the cluster-count layer... or somewhere else entirely.
Currently you are adding the cluster-count layer before the clusters layer so the latter is covering up the former. If you switch the order you will see both: https:///codepen.io/pj_leonard/pen/bGGgYwv?editors=1000
Update your code to the following:
map.on('load', function() {
map.addSource("testMapData", {
type: "geojson",
data: geoData,
cluster: true,
clusterMaxZoom: 14,
clusterRadius: 50
});
map.addLayer({
id: "clusters",
type: "circle",
source: "testMapData",
filter: ["has", "point_count"],
paint: {
"circle-color": "#f1f075",
"circle-radius": 40
}
});
map.addLayer({
id: "cluster-count",
type: "symbol",
source: "testMapData",
filter: ["has", "point_count"],
layout: {
"text-field": "{point_count_abbreviated}",
"text-font": ["Arial Unicode MS Bold"],
"text-size": 12,
"text-allow-overlap" : true
}
});
map.addLayer({
id: "unclustered-point",
type: "circle",
source: "testMapData",
filter: ["!", ["has", "point_count"]],
paint: {
"circle-color": "#51bbd6",
"circle-radius": 8,
"circle-stroke-width": 1,
"circle-stroke-color": "#fff"
}
});
});
Disclaimer: I work at Mapbox
If the order of the layers is correct, pay attention to text font, eg: "text-font": ["MicrosoftYaHeiRegular"]
I'm trying to link two sets of geojson data.
The two data sets are integrated in different "div" and therefore different maps. As can be seen on running the code below, the dynamic highlight works on both maps on hover the IDS.
However, what I want is to highlight the geojson object on the first map when hovering the corresponding geojson object from the second one. (Objects are linked by a same ID attibut).
var dat1 =({
"type" : "FeatureCollection",
"name" : "NewFeatureType",
"features" : [
{
"type" : "Feature",
"geometry" : {
"type" : "Polygon",
"coordinates" : [
[
[ 7.2518485112, 47.1390738345 ],
[ 7.2540323762, 47.1390773819 ],
[ 7.2540289251, 47.1400723508 ],
[ 7.2518450195, 47.1400688032 ],
[ 7.2518485112, 47.1390738345 ]
]
]
},
"properties" : {
"start_fid" : "504748"
}
},
{
"type" : "Feature",
"geometry" : {
"type" : "Polygon",
"coordinates" : [
[
[ 7.2565390484, 47.130837227 ],
[ 7.2633719322, 47.1308479108 ],
[ 7.2633626773, 47.1336579369 ],
[ 7.2565294346, 47.1336472526 ],
[ 7.2565390484, 47.130837227 ]
]
]
},
"properties" : {
"start_fid" : "862126"
}
}
]
});
var dat2 =({
"type" : "FeatureCollection",
"name" : "NewFeatureType",
"features" : [
{
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [ -19.9169596449, 32.1396903724 ]
},
"properties" : {
"start_fid" : "504748"
}
},
{
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [ -19.924214327, 32.1530002773 ]
},
"properties" : {
"start_fid" : "862126"
}
}
]
});
var mymap = L.map('mapid').setView([47.132,7.260], 15);
L.tileLayer('https://api.mapbox.com/styles/v1/mtheisen/citei76iz005f2jpac8g7ilcl/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoibXRoZWlzZW4iLCJhIjoiY2l0ZWk0NTBoMDVmMDJ0bXlyNmxzZ3RnMyJ9.fErHtcHVcTsHCLMPN1ZcQg', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mtheisen',
accessToken: 'pk.eyJ1IjoibXRoZWlzZW4iLCJhIjoiY2l0ZWk0NTBoMDVmMDJ0bXlyNmxzZ3RnMyJ9.fErHtcHVcTsHCLMPN1ZcQg'
}).addTo(mymap);
geojson1=L.geoJson(dat1, {style: style,
onEachFeature: onEachFeature
}).addTo(mymap);
var mymapid2 = L.map('mapid2',{ zoomControl:false }).setView([32.1378527851,-19.9229088608], 14);
geojson2=L.geoJson(dat2, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng)
},
style: style,
onEachFeature: onEachFeature
}).addTo(mymapid2);
function style(feature) {
return {
fillColor: "red",
weight: 1,
opacity: 1,
color: 'red',
dashArray: '3',
fillOpacity: 0.7
};
}
var highlightStyle = {
fillColor: "yellow",
weight: 2,
opacity: 1,
color: 'yellow',
dashArray: '3',
fillOpacity: 0.7
};
function highlightFeature(e) {
var layer = e.target;
layer.setStyle(highlightStyle);
}
function resetHighlight(e) {
geojson1.resetStyle(e.target);
}
function zoomTo(e) {
var layer = e.target;
mymap.fitBounds(layer.getBounds());
}
function onEachFeature(feature, layer) {
name = feature.properties.start_fid;
$('#mapid2').append('<li data-value="' + name + '">'+name+'</li>');
layer._leaflet_id = name;
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomTo
});
}
var hovered_id, layer;
$('#mapid2 li').on('mouseenter', function(e){
hovered_id = $(e.target).data('value');
//console.log(hovered_id);
layer = geojson1.getLayer(hovered_id);
layer2 = geojson2.getLayer(hovered_id);
layer.setStyle(highlightStyle);
layer2.setStyle(highlightStyle);
}).on('mouseout', function(e){
geojson1.resetStyle(layer);
geojson2.resetStyle(layer2);
});
#mapid {
height: 100%;
width: 50%;
left: 0;
position: fixed;
z-index: 0;
/*top: 0;*/
}
#mapid2 {
height: 100%;
width: 50%;
right: 0;
position: fixed;
z-index: 0;
/*top: 0;*/
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.css" rel="stylesheet"/>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div id="mapid"></div>
<div id="mapid2"></div>
<script src="script.js"></script>
</body>
Thanks to my brother for the solution!
var dat1 =({
"type" : "FeatureCollection",
"name" : "NewFeatureType",
"features" : [
{
"type" : "Feature",
"geometry" : {
"type" : "Polygon",
"coordinates" : [
[
[ 7.2518485112, 47.1390738345 ],
[ 7.2540323762, 47.1390773819 ],
[ 7.2540289251, 47.1400723508 ],
[ 7.2518450195, 47.1400688032 ],
[ 7.2518485112, 47.1390738345 ]
]
]
},
"properties" : {
"start_fid" : "504748",
"group_fid" : "1"
}
},
{
"type" : "Feature",
"geometry" : {
"type" : "Polygon",
"coordinates" : [
[
[ 7.2565390484, 47.130837227 ],
[ 7.2633719322, 47.1308479108 ],
[ 7.2633626773, 47.1336579369 ],
[ 7.2565294346, 47.1336472526 ],
[ 7.2565390484, 47.130837227 ]
]
]
},
"properties" : {
"start_fid" : "862126",
"group_fid" : "2"
}
},
{
"type" : "Feature",
"geometry" : {
"type" : "Polygon",
"coordinates" : [
[
[ 7.2585, 47.1345 ],
[ 7.2633, 47.1345 ],
[ 7.2633, 47.1366 ],
[ 7.2585, 47.1366 ],
[ 7.2585, 47.1345 ]
]
]
},
"properties" : {
"start_fid" : "99999",
"group_fid" : "2"
}
}
]
});
var dat2 =({
"type" : "FeatureCollection",
"name" : "NewFeatureType",
"features" : [
{
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [ -19.9169596449, 32.1396903724 ]
},
"properties" : {
"start_fid" : "504748",
"group_fid" : "1"
}
},
{
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [ -19.924214327, 32.1530002773 ]
},
"properties" : {
"start_fid" : "862126",
"group_fid" : "2"
}
}
]
});
var defaultStyle = {
fillColor: "red",
weight: 1,
opacity: 1,
color: 'red',
dashArray: '3',
fillOpacity: 0.7
};
var highlightStyle = {
fillColor: "yellow",
weight: 2,
opacity: 1,
color: 'yellow',
dashArray: '3',
fillOpacity: 0.7
};
var mymap = L.map('mapid').setView([47.132,7.260], 15);
L.tileLayer('https://api.mapbox.com/styles/v1/mtheisen/citei76iz005f2jpac8g7ilcl/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoibXRoZWlzZW4iLCJhIjoiY2l0ZWk0NTBoMDVmMDJ0bXlyNmxzZ3RnMyJ9.fErHtcHVcTsHCLMPN1ZcQg', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mtheisen',
accessToken: 'pk.eyJ1IjoibXRoZWlzZW4iLCJhIjoiY2l0ZWk0NTBoMDVmMDJ0bXlyNmxzZ3RnMyJ9.fErHtcHVcTsHCLMPN1ZcQg'
}).addTo(mymap);
geojson1=L.geoJson(dat1, {style: defaultStyle,
onEachFeature: onEachFeature
}).addTo(mymap);
var mymap2 = L.map('mapid2').setView([32.1378527851,-19.9229088608], 14);
geojson2=L.geoJson(dat2, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng)
},
style: defaultStyle,
onEachFeature: onEachFeature
}).addTo(mymap2);
function highlightFeature(e) {
manageHighlight(e, dat1, geojson1, highlightStyle);
manageHighlight(e, dat2, geojson2, highlightStyle);
}
function resetHighlight(e) {
manageHighlight(e, dat1, geojson1, defaultStyle);
manageHighlight(e, dat2, geojson2, defaultStyle);
}
function manageHighlight(e, dataBloc, geojson, style){
for (var i = 0; i < dataBloc.features.length; i++) {
if(dataBloc.features[i].properties.group_fid == e.target.feature.properties.group_fid){
var layer = geojson.getLayer(dataBloc.features[i].properties.start_fid);
layer.setStyle(style);
}
}
}
function onEachFeature(feature, layer) {
name = feature.properties.start_fid;
layer._leaflet_id = name;
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
});
}
#mapid {
height: 100%;
width: 50%;
left: 0;
position: fixed;
z-index: 0;
/*top: 0;*/
}
#mapid2 {
height: 100%;
width: 50%;
right: 0;
position: fixed;
z-index: 0;
/*top: 0;*/
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.css" rel="stylesheet"/>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div id="mapid"></div>
<div id="mapid2"></div>
<script src="script.js"></script>
</body>
I’m wondering if there is a way to distinguish the data point being inside or outside of a bar.
Basically, with the chart below
I want the text 9178 to be in a colour I generate (because it’s inside a bar)
I want the rest of the numbers to be black (because they are outside of bars)
I’m wondering if the API provides something that I can use programmatically to decide what colour to use.
e.g. If a data point has a method isOverflow() that I can call, then I can set the colour to black if it returns true.
created on jsfiddle: https://jsfiddle.net/Mingzilla/pjqhqn4u/6
var generateColor = function(item) {
var lightColor = "#DADADA";
var color = new Highcharts.Color(item.point.color).rgba;
var isLightBg = color[0] + color[1] + color[2] > 384;
return isLightBg ? '#000000' : lightColor;
};
$(function() {
$('#container').highcharts({
title: {
text: 'I want data point inside a bar to be my colour, and outside to be black'
},
chart: {
type: 'column'
},
xAxis: {
categories: ['Car Insurance',
'Life Insurance',
'Pet Insurance'
]
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
overflow: 'justify',
style: {
fontWeight: 'normal',
textShadow: 'none'
},
formatter: function() {
var item = this;
return '<span style="fill:' +
generateColor(item) + '">' +
(item.point.formattedValue || item.point.y) +
'</span>';
}
}
}
},
series: [{
"color": "#666699",
"name": "North",
"data": [{
"color": "#666699",
"name": "Car Insurance",
"y": 9178
}, {
"color": "#666699",
"name": "Life Insurance",
"y": 4518
}, {
"color": "#666699",
"name": "Pet Insurance",
"y": 1450
}]
}, {
"color": "#663366",
"name": "South",
"data": [{
"color": "#663366",
"name": "Car Insurance",
"y": 2129
}, {
"color": "#663366",
"name": "Life Insurance",
"y": 1066
}, {
"color": "#663366",
"name": "Pet Insurance",
"y": 374
}]
}]
});
});
Defaulty the color is based on contrast or declared single color. But you can return a color (i.e black) for all datalabels. Then catch load / redraw events in the chart object to interate on all dataLabels. Inside each of them, there is information about position and verticalAlign, which can be used to check where label is. If this is top, apply your lightColor by css() method.
var lightColor = "#DADADA";
function datalabelColor() {
var chart = this,
series = chart.series,
each = Highcharts.each,
dL;
each(series, function(serie, i) {
each(serie.data, function(p, j) {
dL = p.dataLabel;
if(dL.alignOptions.verticalAlign === 'top') {
dL.css({
color: lightColor
});
}
});
});
}
Example:
- https://jsfiddle.net/mys5k9ty/
Let me know if you have any further questions.
var non_tfl_lines_JubileetoIlford = L.geoJson(non_tfl_lines_JubileetoIlford, {
pointToLayer: function(feature, latlng) {
switch (feature.geometry.type) {
case 'LineString': return new L.polyline(latlng, {
color: feature.properties.color
});
case 'Point': return new L.Circle(latlng, 400, {
color: getColor(feature.properties.relief_JtI)});
}
onEachFeature: popup
}
}).addTo(map);
For some reason the colour of the polyline is the default colour and not the one specified. In same time it gives me the correct colours of the circles. Any idea what could be wrong?
As you see in the documentation, pointToLayer callback is for GeoJSON points; this is why your code works for points.
If you want to set the color with information from your geojson structure, the best is to have a color property ...
{
"type": "Feature",
"properties": {
"color": "#ff7800"
},
"geometry": {
"type": "LineString",
"coordinates": [
And use it in the style callback
L.geoJson(non_tfl_lines_JubileetoIlford, {
style: function(feature) {
if(feature.geometry.type == "LineString") {
return {
"color": feature.properties.color,
"weight": 5,
"opacity": 0.65
};
}
}
Here is an example http://jsfiddle.net/FranceImage/myxd1ooy/