question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Pluggable formats for geometries

See original GitHub issue

The 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 LatLngs:

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 LatLngs 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 LatLngs:

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:open
  • Created 7 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
mournercommented, Oct 3, 2016

I think this will likely make things more complicated with more ambiguity while not fully solving the original issue.

// proposed format
L.polyLine({ type: 'LineString', coordinates: [...] });
L.marker("POINT (63 10)");

// what you can do now
L.GeoJSON.geometryToLayer({ type: 'LineString', coordinates: [...] });
pluginThatConvertsWKTtoLayer("POINT (63 10)");

// what if you do this? confusing
L.marker("POLYGON (...)");
L.polygon("MULTIPOINT (...)");

// what if a value could equally be a valid input for multiple formats?
L.GeomPoint.addFormat(...) // for [x, y]
L.marker([50, 30]); // WTF, is this LatLng or x, y or what?

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 and getNorthEast in favor of less ambiguous min and max.

0reactions
patrickarltcommented, Oct 23, 2016

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Geometry objects—Common Data Types | ArcGIS Developers
This topic defines the JSON formats of the geometry and spatial reference objects as returned by ArcGIS REST API. ArcGIS REST API supports...
Read more >
extensions for Pluggable types and JSON, GEOMETRY - Jira
Connectors team is asking for a new way to distinguish real data types on the client side: BOOLEAN vs TINYINT; JSON vs LONGEXT;...
Read more >
Geolatte-geom - GitHub
Codecs for translating from/to native database formats for Postgis, Mysql, Oracle, and Microsoft SQL Server. Pluggable, extendable Geometry operations ...
Read more >
About Pluggable Storage Architecture - VMware Docs
Pluggable Storage Architecture (PSA) is an open and modular framework that coordinates various software modules responsible for multipathing ...
Read more >
Geospatial starts with Geometry | The Eclipse Foundation
These are supplemented with indexes, edge graphs, a pluggable precision model, ... for standard spatial text (WKT), binary (WKB), GeoJSON and GML formats....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found