New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow overriding of GeoJSON output #6681
Conversation
This request intends to facilitate overwriting of An other approach to my main problem of accuracy may be that |
var marker = new L.Marker([-1.4837191022531273, 43.49222084042808]), | ||
layerGroup = new L.LayerGroup([marker]); | ||
|
||
expect(layerGroup.toGeoJSON()).to.eql({ | ||
type: 'FeatureCollection', | ||
features: [{ | ||
type: 'Feature', | ||
properties: {}, | ||
geometry: { | ||
type: 'Point', | ||
coordinates: [43.492221, -1.483719] | ||
} | ||
}] | ||
}); | ||
|
||
L.GeoJSON.latLngToCoords = function (latlng, precision) { | ||
if (typeof precision === 'number') { | ||
return latlng.alt !== undefined ? | ||
[L.Util.formatNum(latlng.lng, precision), L.Util.formatNum(latlng.lat, precision), L.Util.formatNum(latlng.alt, precision)] : | ||
[L.Util.formatNum(latlng.lng, precision), L.Util.formatNum(latlng.lat, precision)]; | ||
} else { | ||
return latlng.alt !== undefined ? [latlng.lng, latlng.lat, latlng.alt] : [latlng.lng, latlng.lat]; | ||
} | ||
}; | ||
|
||
expect(layerGroup.toGeoJSON()).to.eql({ | ||
type: 'FeatureCollection', | ||
features: [{ | ||
type: 'Feature', | ||
properties: {}, | ||
geometry: { | ||
type: 'Point', | ||
coordinates: [43.49222084042808, -1.4837191022531273] | ||
} | ||
}] | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var marker = new L.Marker([-1.4837191022531273, 43.49222084042808]), | |
layerGroup = new L.LayerGroup([marker]); | |
expect(layerGroup.toGeoJSON()).to.eql({ | |
type: 'FeatureCollection', | |
features: [{ | |
type: 'Feature', | |
properties: {}, | |
geometry: { | |
type: 'Point', | |
coordinates: [43.492221, -1.483719] | |
} | |
}] | |
}); | |
L.GeoJSON.latLngToCoords = function (latlng, precision) { | |
if (typeof precision === 'number') { | |
return latlng.alt !== undefined ? | |
[L.Util.formatNum(latlng.lng, precision), L.Util.formatNum(latlng.lat, precision), L.Util.formatNum(latlng.alt, precision)] : | |
[L.Util.formatNum(latlng.lng, precision), L.Util.formatNum(latlng.lat, precision)]; | |
} else { | |
return latlng.alt !== undefined ? [latlng.lng, latlng.lat, latlng.alt] : [latlng.lng, latlng.lat]; | |
} | |
}; | |
expect(layerGroup.toGeoJSON()).to.eql({ | |
type: 'FeatureCollection', | |
features: [{ | |
type: 'Feature', | |
properties: {}, | |
geometry: { | |
type: 'Point', | |
coordinates: [43.49222084042808, -1.4837191022531273] | |
} | |
}] | |
}); | |
var arrLatLng = [-1.4837191022531273, 43.49222084042808]; | |
var arrLngLat = [arrLatLng[1], arrLatLng[0]]; | |
var latLng = L.latLng(arrLatLng); | |
var latLngToCoords = L.GeoJSON.latLngToCoords; // keep ref to original func | |
// override with custom function, to prevent latlngs formatting when precision is not specified | |
// (to avoid round-off errors) | |
L.GeoJSON.latLngToCoords = function (latlng, precision) { | |
if (typeof precision === 'number') { | |
return latLngToCoords.apply(this, arguments); | |
} | |
return latlng.alt !== undefined ? [latlng.lng, latlng.lat, latlng.alt] : [latlng.lng, latlng.lat]; | |
}; | |
expect(L.GeoJSON.latLngToCoords(latLng, 6)).to.eql([43.492221, -1.483719]); | |
expect(L.GeoJSON.latLngToCoords(latLng)).to.eql(arrLngLat); | |
var marker = new L.Marker(latLng); | |
expect(marker.toGeoJSON()).to.eql({ | |
type: 'Feature', | |
properties: {}, | |
geometry: { | |
type: 'Point', | |
coordinates: arrLngLat | |
} | |
}); | |
L.GeoJSON.latLngToCoords = latLngToCoords; |
I understand the issue, but I do not like proposed solution, as it is too specific. Currently most of internals routines are not overridable. Even those that look like overridable. E.g., the most straight-forward way to solve your issue could be overriding just single function: Lines 258 to 261 in 1ae785b
Unfortunately, if you look into built function latLngToCoords(latlng, precision) {
precision = typeof precision === 'number' ? precision : 6;
return latlng.alt !== undefined ?
[formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision)] : Thus allowing overriding of some arbitrary function looks like inconsistent decision. |
I would better think about alternative approaches:
// @function latLngToCoords(latlng: LatLng, precision?: Number or Function): Array
// precision:
// - if given value is `number` than apply `L.Util.formatNum` function to latlng values
// - if it is `function` than apply it to to format latlng values
function latLngToCoords(latlng, precision) {
What do think? |
I have an idea: enhance if (digits === false) { return num; } // no formatting |
Hi @johnd0e, thank you for looking into this old problem. I like your idea, and the possibility to skip precision with |
Closed in favor of #7100 |
Background:
I reported in #6586 a problem about accuracy in
L.Util.formatNum
rounding method.Following my pull request, a performance issue has been reported in #6668, and my changes have been reverted.
Problem:
I agree with the arguments advanced in this last thread.
In the end, I especially have a problem with the inaccuracy of the
toGeoJson
function.The solution for me was to overwrite the
GeoJSON.latLngToCoords
but it's not so easy because Leaflet uses internal API.If I overwrite this function, it won't be used by
GeoJSON.latLngsToCoords
.If I also overwrite this function, it won't be used by every
toGeoJSON
declared for each feature.Et cetera. At the end, I have to copy so many functions.
Solution:
I just replaced
latLngToCoords
withGeoJSON.latLngToCoords
EDIT : the first PR text was submitted by error.