Wrapping lines/polygons across the antimeridian in Leaflet.js
Oh, you're hitting antimeridian artifacts. You're not the first one, and will not be the last one.
In Leaflet, there are basically two approaches for this problem:
1a: Cut the polygon beforehand
If you know your GIS tools, preprocess your polygon, so you end up with two (or possibly more) polygons. See «How can I make a polyline wrap around the world?».
Once you have a file with several polygons which don't cross the antimeridian, they should render fine. You will hit artifacts (namely, a vertical polygon border at the antimeridian, spanning the inside ofthe polygon) if you apply a border to the polygons, so you might want to cut a polygon and a polyline with the polygon's edge if you want to render both nicely.
1b: Cut the polygon on the browser
If you don't want to cut the polygon beforehand, you can let the web browser do it on the fly.
There are some utilities that can help here, but I'm going to point to Leaflet.VectorGrid in particular. By leveraging geojson-vt, it can cut polygons and their edges into tile-sized polygons and polygon edges. It can handle geometries crossing the antimeridian quite well.
You might want to look into geojson-vt directly, or maybe turf.js to do some on-the-fly geoprocessing.
2: Think outside the [-180..180]
range
Leaflet can handle longitudes outside the [-180..180]
range. In Leaflet, longitudes wrap only the TileLayer
's tiles and not markers or polylines.
In other words: a marker at [0, -179]
is shown at a different place than [0, 181]
. See this answer for an example.
In other words: a line from [0, 179]
to [0, -179]
is 358 degrees long, but a line from [0, 179]
to [0, 181]
is two degrees long.
In other words: you can have linestrings or polygons with coordinates with longitudes outside the [-180..180]
range, and that's fine for Leaflet. It's not fine for a lot of GIS software (in fact, I think that the new GeoJSON spec prohibits it). But it will make Leaflet happy.
How to display Leaflet markers near the 180° meridian?
Just make sure that the longitudes of your markers are in the range 0..360
instead of in the range -180..180
. See a working example.
i.e. instead of
L.marker([0,170]).addTo(map);
L.marker([0,-180]).addTo(map);
L.marker([0,-170]).addTo(map);
Do something like
L.marker([0,170]).addTo(map);
L.marker([0,180]).addTo(map);
L.marker([0,190]).addTo(map);
In other words, if a longitude is smaller than zero, add 360 to it. You might want to use L.Util.wrapNum(lng, [0,360], true)
instead, if you plan to filter all your longitudes at once.
Related Topics
JavaScript Pass Object as Reference
How to Scroll the Window Using Jquery $.Scrollto() Function
Getting a List of Associative Array Keys
Can a Website Know If I am Running a Userscript
Export Table from Database to CSV File
How to Handle Circular Dependencies with Requirejs/Amd
Differences Between Contenttype and Datatype in Jquery Ajax Function
How to Get the Containing Form of an Input
JavaScript Equivalent of Jquery's Extend Method
Convert a Directory Structure in the Filesystem to JSON with Node.Js
How to Set the Id Attribute of a HTML Element Dynamically with Angularjs (1.X)
Using Await Outside of an Async Function
No Ways to Have Class-Based Objects in JavaScript
Get the Visible Height of a Div with Jquery
How to Use Preload.Js Properly in Electron
Code with Classlist Does Not Work in Ie
How to Reverse an Array in JavaScript Without Using Libraries