I'm trying to create a map of bicycle routes which will get color from properties from geojson file. It is based on Interactive Choropleth Map. The problem I have at the moment is highlighting. This part of the code checks in geojson properties the colour of route:
function getColor(d) {
return d == 'red' ? 'red' :
d == 'blue' ? 'blue' :
d == 'green' ? 'green' :
d == 'black' ? 'black' :
d == 'yellow' ? 'yellow' :
'orange';
}
function style(feature) {
return {
weight: 2,
opacity: 1,
color: getColor(feature.properties.colour),
dashArray: '3',
fillOpacity: 0.7,
};
}
It works ok but when I try to use the same function "get color" on highlighting :
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
color: getColor(feature.properties.colour),
dashArray: '',
fillOpacity: 0.7
});
It doesn't highlight in the colors from properties of geojson. It's probably some small problem but I'm still learning and I don't understand it. Could someone explain it and point a solution, please? Thanks very much!
Here's a working example (not full working of course as I'm still learning):
http://members.upcpoczta.pl/w.racek/mapa.html
Thanks!
In your highlightFeature method, you have the setStyle method where you're referencing feature which doesn't exist. The feature is defined in e.target.feature. So this would work:
function highlightFeature(e) {
e.target.setStyle({
weight: 5,
color: getColor(e.target.feature.properties.colour),
dashArray: '',
fillOpacity: 0.7
});
}
But since you're not changing the color (and the opacity) you might as well leave those out entirely, which also solves the problem :)
Related
I'm trying to style a map layer for a leafletJS map and have the following code but it doesn't seem to colour at all:
var vectorTileOptions = {
rendererFactory: L.canvas.tile,
vectorTileLayerStyles: {
weight: 2,
color: 'yellow',
},
};
var mapLayer = L.vectorGrid.protobuf("/tiles/admin_countries/{z}/{x}/{y}", vectorTileOptions)
It's just comes renders the standard blue, i'm not sure what i'm doing wrong, any suggestions would be great.
This would do it:
.setStyle({fillColor: '#dd0000', color: '#dd0000', weight: 1, opacity: 0.8, fillOpacity: 0.8});
actually, no I think you need to just adjust what you have there:
vectorTileLayerStyles: {
weight: 2,
fillColor: '#9bc2c4'
},
there is a lot about it here: https://leaflet.github.io/Leaflet.VectorGrid/vectorgrid-api-docs.html#styling-vectorgrids
The answer can be found here, by having a click log e.layer to console you can get the property which is used as the key for the vectorTileOptions and then style as appropriate.
After a week of tests, and researches I've decided to "give up" and ask you guys for some help.
What I'm trying to accomplish is fairly easy.
Take the world map and split it in 4 quadrants (done)
Take each quadrant, and using turf calculate how many squares of N units are contained.
Everything works fine with the 2 first quadrants: A (red), B (green)
In fact, if I then try to fill the first two quadrants with squares using turf the result is correct:
The problem is that when trying to replicate the same logic on the squares below, turf returns 0 squares...
The code used to create the 4 quadrants with Leaflet is the following:
const quadrantA = L.rectangle(L.latLngBounds(L.latLng(90, -180), L.latLng(0, 0)), { weight: 1, fillColor: 'red', color: 'red' });
const quadrantB = L.rectangle(L.latLngBounds(L.latLng(90, 0), L.latLng(0, +180)), { weight: 1, fillColor: 'green', color: 'green' });
const quadrantC = L.rectangle(L.latLngBounds(L.latLng(0, -180), L.latLng(-90, 0)), { weight: 1, fillColor: 'blue', color: 'blue' });
const quadrantD = L.rectangle(L.latLngBounds(L.latLng(0, 0), L.latLng(-90, 180)), { weight: 1, fillColor: 'yellow', color: 'yellow' });
quadrantA.addTo(this.map);
quadrantB.addTo(this.map);
quadrantC.addTo(this.map);
quadrantD.addTo(this.map);
Meanwhile the code used to calculate the squares in each quadrant with turf is the following:
const QGrid_A = turf.squareGrid(turf.bbox(quadrantA.toGeoJSON()), 500, { units: 'kilometers' });
const QGrid_B = turf.squareGrid(turf.bbox(quadrantB.toGeoJSON()), 500, { units: 'kilometers' });
const QGrid_C = turf.squareGrid(turf.bbox(quadrantC.toGeoJSON()), 500, { units: 'kilometers' });
const QGrid_D = turf.squareGrid(turf.bbox(quadrantD.toGeoJSON()), 500, { units: 'kilometers' });
Problem is, that the "second round" of calculations returns always 0 features for the quadrants C and D.
QGrid_A features: 800
QGrid_B features: 800
QGrid_C features: 0
QGrid_D features: 0
I've also read about that Leaflet reverses the standard GeoJSON coordinates positions, by using [LAT,LON] instead of [LON,LAT], so I've also tried to reverse the result of the Leaflet generated GeoJSONs by doing a reverse on the coordinates array, but still nothing.
I wonder where am I wrong here? Is it a problem of "looped" coordinates? Is it a problem due to a falsy conversion between Leaflet and Turf? Is it me dumb? Please help me guys.
My solution
At the end of the day, I've adopted another strategy. Pretty simple tbh.
I've created a polygon which is the "area to map". This polygon then is split in several sub-squares polygons. Each square then can be used as an individual "tile".
Using #turf/square-grid and #turf/bbox was to achieve this was pretty easy,
the code for this is all incapsulated in 2 functions:
export interface ISplitAreaInSubareasConf {
squareCellSide?: number;
units?: `meters` | `kilometers`;
}
private splitAreaToMapInSubAreas(areaToMap: Polygon, opts?: ISplitAreaInSubareasConf): BBox[] {
const units = opts && opts.units ? opts.units : this.SQUARE_UNIT;
const side = opts && opts.squareCellSide ? opts.squareCellSide : this.SQUARE_CELL_SIDE_IN_KM;
const grid = turfSquareGrid.default(this.getAreaToMapBBox(areaToMap), side, {units, mask: areaToMap});
return grid.features.map(feat => this.getAreaToMapBBox(feat.geometry));
}
private getAreaToMapBBox(areaToMap: Polygon) {
return bbox.default(areaToMap);
}
I have a leaflet map with an overlay made from a geojson file that contains polygons, lines and points. I'd like to be able to use custom markers (let's say the image marker is CustomMarker.png). So far, I have the following code that works perfectly well, the only thing is that it displays standard marker icons :
$.getJSON(url, function(geojson) {
overlay = L.geoJson(geojson, {
style: function(feature) {
return {
fillColor: 'red',
weight: 1,
opacity: 0.5,
color: 'red',
dashArray: 3,
fillOpacity: 0.5,
}
},
onEachFeature: function(feature, layer) {
layer.bindPopup("<strong>" + layer.feature.properties.Titre + "</strong><br/>" + " : nom de la région")
}
}).addTo(map);
I know the solution is at my grasp and that something should be put just above "onEachFeature" but can't figure it out so far.
I am creating a document from a leaflet map. The legend from the map features will not be part of the map but a separate area on the document. I am trying to get the Layer information such as color and dasharray(solid, dashed....) information from each layer.
I have used feature.option.style, but I get function style(feature) {return....}. I want to get the actual values.
var lyrs = map._layers;
for (var f in map._layers) {
var feature = map._layers[f];
alert(feature.options.style);
return false;
}
I get this:
function style(feature) {
return {
weight: 1,
opacity: 1,
color: 'black',
dashArray: '3',
fillOpacity: 0.7,
fillColor: getColor(feature.properties.Rights, "geojson", "parcel")
};
}
I want to be able to get:
fillColor:black;
dashArray: '3'
Instead of using the style call the code should read as follows
var lyrs = map._layers;
for (var f in lyrs) {
var feature = map._layers[f];
var properties = feature.options.dashArray;
alert(properties);
return false;
}
This returns the value of 3. Exactly what was desired. The same call could be used to find the weight, opacity, color, fillOpacity or fillColor
I am working with this example of US map http://leafletjs.com/examples/choropleth.html.
I am Highlighting the map of a state using a color. But the problem is there are some markers that were clickable before the addition of this highlighting color now becomes non clickable. How can I make the markers clickable even after keeping the map highlighted? Any solution? By the way I am using the following code to highlight the map:
function getColor(d) {
if(d === "Iowa")
return '#800026';
else
return '#ffffff';
}
function style(feature) {
return {
//fillColor: getColor(feature.properties.name),
weight: 4,
opacity: .1,
color: getColor(feature.properties.name),
dashArray: '3',
fillOpacity: 0.3
};
}
L.geoJson(statesData, {style: style}).addTo(map);
It seems you have the fillColor option commented out. If you remove the // before fillColor it should work.