Put a GeoJSON on a Leaflet map: Invalid GeoJSON object. throw new Error('Invalid GeoJSON object.');
Solution 1
The problem was about I tried to use a string as a JSON object.
The solutions is to use jQuery.parseJSON function to convert my string with my JSON code (addressPCN1) to a Javascript JSON object.
Here you are code that works ...
<!DOCTYPE html>
<html>
<head>
<title>Prova caricamento WMS Indirizzi del PCN</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css"/>
</head>
<body>
<div id="map" style="width: 600px; height: 400px"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet-src.js"></script>
<script>
var browser = navigator.userAgent.toLowerCase();
var isIE = (browser.indexOf("msie")>-1 || browser.indexOf("trident")>-1);
if (isIE && window.XDomainRequest) {
if (window.XDomainRequest) {
var query = 'service_url';
var xdr = new XDomainRequest();
if (xdr) {
xdr.onload = function () {
addressPCN(xdr.responseText);
}
xdr.onerror = function () {
alert("KO");
}
xdr.open('GET', query);
xdr.send();
}
}
}
else {
var query = 'service_url';
$.ajax({
type: "GET",
url: query,
dataType: "text",
crossDomain: true,
success: function (data) {
//alert("OK");
//alert(data);
addressPCN(data);
alert($this.find('ms\\:nome, nome').text() + ' - ' + $this.find('ms\\:civico, civico').text());
},
error: function (response, textStatus, errorThrown) {
alert("KO");
alert(errorThrown);
}
});
}
var map = L.map('map').setView([42, 12], 5);
L.tileLayer('https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: 'examples.map-20v6611k'
}).addTo(map);
function addressPCN (addressList) {
var addressPCN = '{"type": "FeatureCollection","features":[';
$xmlData = $.parseXML(addressList);
$features = $('gml\\:featureMember, featureMember', $xmlData);
$features.each(function () {
var $this = $(this);
//alert($this.find('ms\\:nome, nome').text() + ' - ' + $this.find('ms\\:civico, civico').text());
addressPCN = addressPCN + '{"type": "Feature", "properties": { "popupContent": "' + $this.find('ms\\:nome, nome').text() + ' ' + $this.find('ms\\:civico, civico').text() + '", ' + '"show_on_map": true }, "geometry": { "type": "Point", "coordinates": [' + $this.find('gml\\:Point, Point').find('gml\\:coordinates, coordinates').text() + ']}},'
});
var addressPCN = addressPCN + ']}';
alert(addressPCN);
var addressPCN1 = addressPCN.replace(',]}',']}');
alert(addressPCN1);
var addressPCN2 = jQuery.parseJSON(addressPCN1);
alert(addressPCN2);
function onEachFeature(feature, layer) {
if (feature.properties && feature.properties.popupContent) {
layer.bindPopup(feature.properties.popupContent);
}
}
L.geoJson(addressPCN2, {
onEachFeature: onEachFeature
}).addTo(map);
}
</script>
</body>
</html>
Solution 2
First, make sure the Geo JSON data is valid data with http://geojsonlint.com/ or any other service. Fix the errors if there are any.
And then parse your data which is in the text format with JSON.parse()
:
L.geoJSON(JSON.parse(data)).addTo(this.map);
Cesare
Updated on July 30, 2022Comments
-
Cesare over 1 year
I've some trouble with a Leaflet code that build a GeoJSON and put it on the map.
The GeoJSON is builded from an XML response of a service.
The error is
Invalid GeoJSON object. throw new Error('Invalid GeoJSON object.');
My code is ...
<html> <head> <title>Prova caricamento WMS Indirizzi del PCN</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css"/> </head> <body> <div id="map" style="width: 600px; height: 400px"></div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet-src.js"></script> <script> var browser = navigator.userAgent.toLowerCase(); var isIE = (browser.indexOf("msie")>-1 || browser.indexOf("trident")>-1); if (isIE && window.XDomainRequest) { if (window.XDomainRequest) { var query = 'http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/wfs/Numeri_Civici_2012.map&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=IN.NUMERICIVICI.2012&SRSNAME=EPSG:4326&bbox=7.719,44.849,7.72,44.85&outputFormat=GML2'; var xdr = new XDomainRequest(); if (xdr) { xdr.onload = function () { addressPCN(data); } xdr.onerror = function () { alert("KO"); } xdr.open('GET', query); xdr.send(); } } } else { var query = 'http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/wfs/Numeri_Civici_2012.map&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=IN.NUMERICIVICI.2012&SRSNAME=EPSG:4326&bbox=7.719,44.849,7.72,44.85&outputFormat=GML2'; $.ajax({ type: "GET", url: query, dataType: "text", crossDomain: true, success: function (data) { addressPCN(data); }, error: function (response, textStatus, errorThrown) { alert("KO"); alert(errorThrown); } }); } var map = L.map('map').setView([42, 12], 5); L.tileLayer('https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png', { maxZoom: 18, attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' + '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' + 'Imagery © <a href="http://mapbox.com">Mapbox</a>', id: 'examples.map-20v6611k' }).addTo(map); function addressPCN (addressList) { //alert("In function addressList"); //alert(addressList); var addressPCN = '{"type": "FeatureCollection","features":['; $xmlData = $.parseXML(addressList); $features = $('gml\\:featureMember, featureMember', $xmlData); //alert($features.length); $features.each(function () { var $this = $(this); //alert($this.find('ms\\:nome, nome').text() + ' - ' + $this.find('ms\\:civico, civico').text()); addressPCN = addressPCN + '{"type": "Feature", "properties": { "popupContent": "' + $this.find('ms\\:nome, nome').text() + ' ' + $this.find('ms\\:civico, civico').text() + '", ' + '"show_on_map": true }, "geometry": { "type": "Point", "coordinates": [' + $this.find('gml\\:Point, Point').find('gml\\:coordinates, coordinates').text() + ']}},' }); var addressPCN = addressPCN + ']}'; alert(addressPCN); function onEachFeature(feature, layer) { if (feature.properties && feature.properties.popupContent) { layer.bindPopup(feature.properties.popupContent); } } //var addressPCN = {"type": "FeatureCollection","features":[{"type": "Feature", "properties": { "popupContent": "Via Pegolo 9", "show_on_map": true }, "geometry": { "type": "Point", "coordinates": [7.719490,44.849197]}},{"type": "Feature", "properties": { "popupContent": "Via Pegolo 8", "show_on_map": true }, "geometry": { "type": "Point", "coordinates": [7.719490,44.849197]}},]}; L.geoJson(addressPCN, { onEachFeature: onEachFeature }).addTo(map); } </script>
You can copy/paste it and shoud work on your desktop/laptop.
Note that if you uncomment the row ....
//var addressPCN = {"type": "FeatureCollection","features":[{"type": "Feature", "properties": { "popupContent": "Via Pegolo 9", "show_on_map": true }, "geometry": { "type": "Point", "coordinates": [7.719490,44.849197]}},{"type": "Feature", "properties": { "popupContent": "Via Pegolo 8", "show_on_map": true }, "geometry": { "type": "Point", "coordinates": [7.719490,44.849197]}},]};
.... you've the GeoJSON I'm building (you can match it with the alert message ....).
In this case all it's working right.
NOTE: you've to use Firefox or Chrome at the momenti, my code still doesn't work foi IE.
Any suggestion is appreciated!!
Thank you in advance!!
Cesare