Using WFS with layers with leaflet 1.0 generates an error - javascript

I'm having a problem using Leaflet 1.2.0 with WFS and control Layers, WFS works fine, however when I use it with control.layers (see code bellow) it does not work and it returns an error:
Uncaught TypeError: Can not read property 'minZoom' of undefined
If using with version 0.6 works but I can not use it because of its limitations. Can someone please help me?
The code is here in git:
https://github.com/eltonsantos/leaflet-tests/blob/master/teste14/index.html
and here in jsfiddle:
https://jsfiddle.net/eltin182/amg80r7j/3/

You are building a plain JS object:
var stComerciaisLayer = {
service: 'WFS',
// etc.
};
…and try to feed it into the Leaflet Layers Control:
var objCamadas = {
"Setores Comerciais": stComerciaisLayer
}
L.control.layers(baseLayers, objCamadas).addTo(map);
…whereas the Layers Control is supposed to handle Leaflet layers, not plain JS objects.
There should be some Leaflet plugins to handle WFS, have a look on the plugins page.

Related

How to remove a feature in openlayers with multiple possible sources

I have a map with multiple layers, all connected to different vector sources.
When a user selects a feature I want him to be able to delete the feature. However, I can't seem to find a way to locate the source layer the feature is from.
If I try to just remove the feature from all layers I get an error:
Vector.js:946 Uncaught TypeError: Cannot read property 'forEach' of undefined
at Vector.removeFeatureInternal (Vector.js:946)
Is there a good way of doing finding the source layer or removing features without specifying from where?
At the moment I'm catching the exceptions, but this turns unwieldy with a lot of layers and sources.
For each source, you could try to get the selected Feature. If the response is not null, the feature exists on that source.
Something along this way inside your select:
const featureId = selectedFeature.getId()
map.getLayers().getArray().forEach(layer => {
const source = layer.getSource();
if (source instanceof VectorLayer) {
const featureExists = source.getFeatureById(featureId);
if (featureExists) {
source.removeFeature(selectedFeature);
return;
}
}
})

Get KML style in OpenLayers 5

I have some code in an application that access the style of a selected feature in a KML layer. It was working in OpenLayers 3.1. I have now upgraded to 5.3.0 and it stopped working. See the relevant lines below:
var featStyle = feature.getStyleFunction().call(feature, map.getView().getResolution());
var strokeWidth = featStyle[0].getStroke().getWidth();
var strokeColor = featStyle[0].getStroke().getColor();
var fillColor = featStyle[0].getFill().getColor();
var fillOpacity = (Math.round(fillColor[3] * 100));
The line:
var featStyle = feature.getStyleFunction().call(feature, map.getView().getResolution());
Produces an error visible in the developer console:
TypeError: o.getGeometry is not a function[Learn More] KML.js:943
a KML.js:943
myFunctionName file.php:5371
onclick file.php:1
I can't find anything in the documentation or examples that shows how to properly access the KML style data for a given feature (not an entire layer/source). Is there a new way to do this or did I miss something?
Could it have to do with this?: https://github.com/IGNF/geoportal-sdk/issues/2 Plugged into Google translate it seems to say something about no longer storing style properties inside each feature but it does not seem to say where they are stored...
The KML is valid and displays on the map properly. I just can't seem to find a way to access the style data anymore.
In OpenLayers 3 and 4 a feature style function takes only a resolution argument but internally uses this so the function or call must be bound to the feature:
feature.getStyleFunction().bind(feature)(map.getView().getResolution());
or
feature.getStyleFunction().call(feature, map.getView().getResolution());
In OpenLayers 5 feature style function are similar to layer style functions and require the feature to be passed as an argument:
feature.getStyleFunction()(feature, map.getView().getResolution());

d3 + leaflet path fill issue

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);
});

Accessing Leaflet.js GeoJson features from outside

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);

Styling a geoJSON Feature Layer in MapBox

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?

Categories

Resources