Pluggable formats for geometries
See original GitHub issueThe past few days I’ve had a few looks at the APIs of other libraries (mapbox-gl, openlayers), looking at all that separation between model (geometries) and views (styling/symbolizers), and I’ve been thinking…
The current situation
Leaflet uses LatLng
for everything. And then we have fights about LngLat
vs LatLng
, it doesn’t make sense for L.CRS.Simple
, and other woes.
The good part, the really really good part that makes Leaflet easy, is that we cast stuff to instances of LatLng
s:
L.marker([63,10]);
L.marker({lat: 63, lng: 10});
L.marker(L.latLng([63,10]);
What I would like
I would like the magical casting of stuff into LatLng
s to be pluggable, so we could do wild things like:
// GeoJSON geometry (not feature)
L.marker({ type: 'Point', coordinates: [10, 63] });
// WKT
L.marker("POINT (63 10)");
And this applies to things that expect an array of LatLng
s:
L.polyLine({ type: 'LineString', coordinates: [[10, 63], [11, 64]] });
How to get there
By replacing LatLng
with some weird mixture of mapbox’s LngLatLike
and openlayer’s ol.geom.Point
.
Let’s call this hypothetical thing L.GeomPoint
. In the same vein, L.GeomLine
and L.GeomPolygon
(or L.GeomArea
), and maybe L.GeomCollection
.
Now, L.GeomPoint
can have a static class method to attach/detach formats, e.g.:
L.GeomPoint.addFormat({
name: 'wkt',
toGeom: function(wkt) {
var match = wkt.match(/^POINT\s\((\d+\s\d+)\)/);
if (!match) { return undefined; } // If the input doesn't match this format
return [match[1], match[2]]; // return [x, y];
},
toWKT: function() {
return "POINT (" + this.x + ' ' + this.y + ')';
}
});
L.GeomPoint.removeFormat('wkt') // Or maybe pass the whole format definition and not have a string
Then the GeomPoint
constructor just loops through the toGeom
methods of the formats until it gets something which is not undefined
.
We kinda are doing this already in the L.latLng
factory. There might be some performance hit, but once the instance is made, it shouldn’t be too big.
Then, keep L.LatLng
around (compatible with L.GeomPoint
) for long enough until we nuke it in Leaflet 2 or whatever. Or make it an alias or something.
@mourner @patrickarlt @olanod @tmcw @perliedman @yohanboniface @hyperknot: does this make any sense?
Issue Analytics
- State:
- Created 7 years ago
- Comments:6 (6 by maintainers)
Top GitHub Comments
I think this will likely make things more complicated with more ambiguity while not fully solving the original issue.
What we might want to explore instead is having GeoJSON as a first-class citizen that’s used internally for all geometries without wrapper classes, and getting rid of geography-aware methods like
getSouthWest
andgetNorthEast
in favor of less ambiguousmin
andmax
.Initially I got really excited by this idea (seeing as Esri Leaflet) ships its own conversion tools and this seems like it fits right in but I agree with @mourner and @tmcw that this feels really overly complicated, especially when things like Terraformer and Leaflet Omnivore exist.
Making GeoJSON more of a first class citizen in Leaflet like @tmcw suggested does seem like a really good idea. I like the idea of being able to do
L.marker({ type: 'Point', coordinates: [10, 63] });
feels really natural but I’m not sure Leaflet needs a fully pluggable geometry engine.It seems like the original intent of this issue was to fix things for
L.CRS.Simple
which @mourner suggested could simply be solved by adding{x: 10, y: 20}
as a new format which seems like a nice simple solution to the problem.