In am using Leafletjs in Angular2, http.get to invoke JSON from a URL, but I can't define style for the features that are added to the map because of predefining the geoJSON layer:
// Add an empty layer to the map
var geoJsonLayer1 = L.geoJSON().addTo(myMap);
// Retrieve the geojson file
http.get(myJsonURL)
.map((response: Response) => {
geoJsonLayer1.addData(response.json());
}).subscribe();
The geoJSON layer doesn't have any style and it looks as below:
The reason that I am predefining the layer is, I am lazy-loading the JSON file. In the regular way, we can define the style as below:
L.geoJSON(myLines, {
style: myStyle
}).addTo(map);
Now my question is, how to define the style for a predefined layer?
Just predefine the layer without data…
var geoJsonLayer1 = L.geoJSON(null, {
style: myStyle
}).addTo(map);
// Later on…
geoJsonLayer1.addData(response.json());
BTW your screenshot looks to show markers (for "Point" type features) with missing icon image. In that case, instead of style option for vector shapes (like polygons, line strings, etc.), you should use the pointToLayer option.
Related
I'm working on a timelapsed filled map using Leaflet as a baselayer and a d3 topojson file so I can color in some countries. I used http://bost.ocks.org/mike/leaflet/ to get started, and everything was going great until I tried to shade in the Russian Federation. Its landmass spans non-contiguous tiles, and when I try to add a fill style to my #RUS path, it behaves anomalously. Example is here: http://dataviz.du.edu/projects/scratch/study_abroad.html
Example will take 1.5 s to render completely, it shades 3 countries, with the Russian Federation shading last.
This example uses a topojson file that I have used in other, pure d3 projects and have filled #RUS in those contexts without this issue.
Can anyone help? Thanks in advance.
This example uses a topojson file that I have used in other, pure d3 projects and have filled #RUS in those contexts without this issue.
You must be mistaken because your TopoJSON file is actually corrupt. See here an example with that file straight from your server: http://plnkr.co/edit/QOTwV3?p=preview Mind that i'm using plain TopoJSON and Leaflet's GeoJSON layer but it's yielding the exact same results.
PS. Is there any reason as to why you're using D3 for this? Asking because what i see you doing can be done just using Leaflet and TopoJSON, without D3. Here's a simple example:
function delay(features) {
var geojsonLayer = new L.GeoJSON(null, {
style: getStyle,
}).addTo(map);
var delay = 100;
features.forEach(function(feature) {
delay = delay + 100;
setTimeout(function() {
geojsonLayer.addData(feature);
}, delay);
});
}
var url = 'http://crossorigin.me/http://dataviz.du.edu/projects/scratch/worldnew.json';
$.getJSON(url, function(data) {
var geojsonData = topojson.feature(data, data.objects.test);
delay(geojsonData.features);
});
I want to interact with a leaflet powered map's GeoJson overlay (polygons) from outside of L.'s realm, but I don't seem to be able to access objects created by L..
Interaction would include:
getBounds(myFeature)
fitBounds(myFeature)
setStyle
etc
I can see Leaflet exposing L.GeoJSON.getFeature(), but I don't seem to be able to squeeze anything out of it. No documentation, and the inspector seems to suggest it does not take arguments... :\
Is this just there for future development?
You may use getLayer to get the feature by its id.
http://leafletjs.com/reference.html#layergroup-getlayer
var geojsonLayer = L.geoJson(data,{
onEachFeature: function(feature, layer) {
layer._leaflet_id = feature.id;
}});
geojsonLayer.addTo(map);
feature = geojsonLayer.getLayer(12345); //your feature id here
alert(feature.feature.id);
I'd like to list all of the elements from a Mapbox gridLayer that are visible to a user in the viewport.
There is an excellent example on the Mapbox site called 'Listing markers in view'. It shows all the markers on the featureLayer that are in the view of the browser.
I'd like to create something similar, but using using a gridLayer instead. (the gridLayer was created in TileMill)
Here is an example fiddle of the data with a version of non-working 'in-bounds' code:
http://jsfiddle.net/bfab/uSLVw/1/
For reference, the gridLayer has a variable in it (passed from TileMill in the UTFGrid) called '{{{Magnitude}}}' I'd like to list each of the instances of earthquakes that appear to the user, and add it to a list on the bottom left of the example. The function I'm trying to use is gridLayer.getData(latlng,callback).
Here is the snippet of code that is not working:
map.on('move', function() {
// Construct an empty list to fill with gridLayer elements.
var inBounds = [],
// Get the map bounds - the top-left and bottom-right locations.
bounds = map.getBounds();
// For each part of the grid, consider whether
// it is currently visible by comparing with the current map bounds.
// This is what fails....
myGridLayer.getData(bounds,function(earthquake){
inBounds.push(earthquake.Magnitude);
});
// Display a list of markers.
document.getElementById('coordinates').innerHTML = inBounds.join('\n');
});
Apologies if I am making a simple error...
Actually you can't (not easily at least)
1/ You misunderstand the getData function on the gridlayer
first parm is not a boundary but a location latlng
when you use this in a callback (onclick for example) you will get data only if you click on one of your circles, if not you get undefined). The data is not a list of markers but the information of your earthquake (e.g. {DateTime: "2014-04-26T16:59:15.710+00:00", Magnitude: 3.9})
myGridLayer.getData(event.latlng, function(data) {
console.log(data);
// if clicked on a marker: data is defined
// e.g. Object {DateTime: "2014-04-26T16:59:15.710+00:00", Magnitude: 3.9}
});
http://jsfiddle.net/FranceImage/uSLVw/11/
2/ It is not easy to think in terms of markers when using gridlayer as the markers are already part of the image when you load tiles:
http://a.tiles.mapbox.com/v3/bfab.i4nm0adm/3/0/2.png
The interaction is described in some javascript loaded at the same time
http://a.tiles.mapbox.com/v3/bfab.i4nm0adm/3/0/2.grid.json
I just started playing with MapBox and am running into a confusing issue. I'm creating a map with a geoJSON layer using this code:
var map = L.mapbox.map('map', '<MapBoxID>');
var zipLayer = L.mapbox.featureLayer('data/blah.json');
zipLayer.addTo(map);
zipLayer.setStyle({color: 'red'});
The map appears and shows the geoJSON, but it ignores the styling. When I copy that last line into the JS console in my browser, it works fine, though.
What am I missing here? Also, I've tried at least a dozen different ways of including the style in the options directly in the featureLayer() call, but nothing has worked. How do I specify the style when creating the feature layer?
I'm guessing a bit here, since I don't know the Mapbox JS very well, but it sounds a lot like an async error. Strangely, I don't see anything in the Mapbox or Leaflet APIs about a callback for this function. But, you can pass straight GeoJSON to featureLayer(), so I'd suggest using jQuery (or your XHR library of choice) to grab the data:
var map = L.mapbox.map('map', '<MapBoxID>');
var zipLayer;
$.getJSON('data/blah.json', function(data) {
zipLayer = L.mapbox.featureLayer(data);
zipLayer.addTo(map);
zipLayer.setStyle({color: 'red'});
});
Hopefully that'll do the trick.
I would go the route of using the built-in featureLayer function, then listening for it to be ready. This should help get you pointed in the right direction:
var featureLayer = L.mapbox.featureLayer()
.loadURL('/example-single.geojson')
.on('ready', function(layer) {
this.eachLayer(function(marker) {
// See the following for styling hints:
// https://help.github.com/articles/mapping-geojson-files-on-github#styling-features
marker.setIcon(L.mapbox.marker.icon({
'marker-color': '#CC0000'
}));
});
})
.addTo(map);
Have you tried adding the zipLayer after setting the style?
I want to draw many geo points with Leaflet. Therefore I want to use HTML5 canvas to improve the performance.
My datasoure is geoJSON. As I saw in the documention of Leaflet, it is not possible to draw the geo positions as canvas yet.
var anotherGeojsonLayer = new L.GeoJSON(coorsField, {
pointToLayer: function (latlng){
return new L.Marker(latlng, {
icon: new BaseballIcon()
});
}
});
I think I should hook up here:
pointToLayer: function (latlng) { }
Does somebody know how to draw my latlng objects as canvas?
I'm Leaflet author. You can do this by using L.CircleMarker instead of regular Marker, and also using an experimental L_PREFER_CANVAS switch to render vectors as Canvas (instead of SVG), like this: https://github.com/CloudMade/Leaflet/blob/master/debug/vector/vector-canvas.html
Expanding on the original answer in case anyone needs this for Leaflet 1.0. You should still use L.circleMarker() (Leaflet circleMarker documentation) instead of L.marker(), but the way to use the canvas has changed.
In Leaflet 1.0, the experimental L_PREFER_CANVAS switch has been upgraded to an official map option preferCanvas (Leaflet preferCanvas documentation).
var map = L.map('mapid', {
preferCanvas: true
});
Alternatively, you can explicitly set the canvas renderer; I think this does the same thing as the preferCavas option. Here's the Leaflet documentation for canvas.
var map = L.map('mapid', {
renderer: L.canvas()
});
Either of these options (preferCanvas: true or renderer: L.canvas()) with L.circleMarker() was significantly faster than a regular layer using L.marker().